Home >Web Front-end >HTML Tutorial >Honeycomb animation effect realized with css3 and canvas_html/css_WEB-ITnose
I have recently studied css3 animation and js animation at work. In order to enhance the fun of the page, everyone has added a lot of animation effects intentionally or unintentionally. Of course, most of them are css3 animation effects. You can GPU acceleration, which will reduce the performance requirements of mobile terminals.
Today we are mainly talking about the honeycomb effect. You can run the source code later for the specific effect. I won’t include the gif here.
The principle of css3 is very simple, that is, by changing the background-size, because the repeat attribute can be set in the background of css3, the background image can be tiled in the x, y direction. First set background-size: 10%, 10% (this value can be freely defined, but you don’t mind setting it too large, otherwise the effect will not be obvious), and finally change backg-size: 100%, 100%; this will make the background The picture fills the entire screen. Oh, by the way, don’t forget to set background-position: 50% 50%; otherwise you will feel weird. Setting background-position is to tile the background picture at the center point, and the system default It will be tiled in the upper left corner. Then you can achieve this effect by setting the animation animation to call the animation
<pre name="code" class="html">.honey { position: absolute; top: 0; left: 0; height: 100%; width: 100%; background: url(2.jpg) repeat; background-size: 30% 30%; background-position: center center; -webkit-animation: honeycomb 3s 1 linear; } @-webkit-keyframes honeycomb { 0% { background-size: 10% 10%; } 100% { background-size: 100% 100%; } }
As for using canvas to achieve this, this is purely boring. I don’t recommend you to use this method. Using canvas to draw here is completely boring for me, but if you are interested in canvas If you are interested in animation, you can pay attention to the canvas implementation plan below. The principle of canvas drawing is very simple. By passing in the percentage of width and height, you can calculate how many rectangles need to be drawn in total, as well as the center point coordinates of each rectangle. I have encapsulated this code into a module. You can read it step by step. First, define an object honey object
var Honey = function (options) { for (var i in options) { if (options.hasOwnProperty(i)) { this[i] = options[i]; } } this.canvas = this.canvasId || document.getElementById(this.canvasId) || document.getElementById('#canvas'); this.ctx = this.canvas.getContext('2d'); this.canvasWidth = document.body.getBoundingClientRect().width; this.canvasHeight = document.body.getBoundingClientRect().height; this.canvas.width = this.canvasWidth; this.canvas.height = this.canvasHeight; this.stopped = true; this.width = options['width'] || 10; this.height = options['height'] || 10; this.dwidth = options['dwidth'] || 1; this.dheight = options['dheight'] || 1; this.img = options.img; /*if (!options.img) { console.log('没有传入图片地址'); }*/ };Next, let’s define some attributes in this object. The canvas drawing image starts from the upper left corner by default, so we need to write a method to draw from the center point, which can be added to the attribute through prototype
drawImage : function (x, y, w, h) { var width = w * this.canvasWidth / 100, height = h * this.canvasHeight / 100; var top = y - height / 2, left = x - width / 2; var self = this; // var img = self.img; // img.onload = function () { self.ctx.drawImage(self.img, left, top, width, height); // } },
The next method is To get the center point position of the rectangle you need to draw, first look at the code:
// 获取所有显示小图片的中心点位置 getPoints : function (width, height) { // var width = parseInt(w), height = parseInt(h); var numW = Math.ceil(100 / width), numH = Math.ceil(100 / height); var result = []; for (var i = -Math.ceil(numW * 0.5); i <= Math.ceil(numW * 0.5); i++) { var x = 50 + width * i; for (var j = -Math.ceil(numH * 0.5); j <= Math.ceil(numH * 0.5); j++) { var y = 50 + height * j; result.push({x: x * this.canvasWidth / 100, y: y * this.canvasHeight / 100}); } } return result; },In fact, it turns out that starting from the center point 50, 50 of the canvas, numW and numH represent the horizontal and vertical directions respectively. The number of rectangles that need to be drawn in the direction. Here you should pay attention to using Math.ceil to round up to ensure that the entire canvas can be filled. Then x = 50 width * i; it means subtracting the value of width in the x direction, which is equal to The x value to the left of the center point, and the same is true in the y direction. Finally, the function returns an array containing all coordinate points. The next step is to use this array and the drawing method provided above to draw all the pictures one by one.
The complete module source code is as follows:
define(function (require, exports, module) { var RAF = window.requestAnimationFrame || window.webkietRequestAnimationFrame || function (callback) { setTimeout(callback, 1000/ 60); }; var Honey = function (options) { for (var i in options) { if (options.hasOwnProperty(i)) { this[i] = options[i]; } } this.canvas = this.canvasId || document.getElementById(this.canvasId) || document.getElementById('#canvas'); this.ctx = this.canvas.getContext('2d'); this.canvasWidth = document.body.getBoundingClientRect().width; this.canvasHeight = document.body.getBoundingClientRect().height; this.canvas.width = this.canvasWidth; this.canvas.height = this.canvasHeight; this.stopped = true; this.width = options['width'] || 10; this.height = options['height'] || 10; this.dwidth = options['dwidth'] || 1; this.dheight = options['dheight'] || 1; this.img = options.img; /*if (!options.img) { console.log('没有传入图片地址'); }*/ }; Honey.prototype = { // 以中心点来画图 drawImage : function (x, y, w, h) { var width = w * this.canvasWidth / 100, height = h * this.canvasHeight / 100; var top = y - height / 2, left = x - width / 2; var self = this; // var img = self.img; // img.onload = function () { self.ctx.drawImage(self.img, left, top, width, height); // } }, // 获取所有显示小图片的中心点位置 getPoints : function (width, height) { // var width = parseInt(w), height = parseInt(h); var numW = Math.ceil(100 / width), numH = Math.ceil(100 / height); var result = []; for (var i = -Math.ceil(numW * 0.5); i <= Math.ceil(numW * 0.5); i++) { var x = 50 + width * i; for (var j = -Math.ceil(numH * 0.5); j <= Math.ceil(numH * 0.5); j++) { var y = 50 + height * j; result.push({x: x * this.canvasWidth / 100, y: y * this.canvasHeight / 100}); } } return result; }, init : function () { var width = this.width, height = this.height, dwidth = this.dwidth, dheight = this.dheight, loaded = false;; var self = this; var img = this.img; if (!img) { console.log('没有传入图片地址'); return; } if (typeof img == 'string') { var image = new Image(); image.src = img; img = image; this.img = img; } tick(); function tick () { if (!self.stopped) { width += dwidth; height += dheight; // 防止图片过大缩放,自动设置停止标志位 if (width >= 100) { width = 100; } if (height >= 100) { height = 100; } if (width >= 100 && height >= 100) { self.stopped = true; } // 画图 self.animate(width, height); RAF(function () { tick(); }) } } }, animate : function (w, h) { var self = this; var points = self.getPoints(w, h); // console.log(points.length, w, h); self.clear(); for (var i = 0, len = points.length; i < len; i++) { var point = points[i]; // console.log(point.x, point.y , w * this.canvasWidth / 100, h * this.canvasHeight / 100); self.drawImage(point.x, point.y, w, h); } }, clear : function () { this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight); } }; return Honey;})Here, requestAnimatioFrame is used for cyclic calls instead of the common setTimeout. The specific reason is probably Google. Using canvas to draw will consume more performance. I don’t mind if you use it, but if you are writing canvas animation, you can consider adding such an animation effect.