Honeycomb animation effects implemented with css3 and canvas

Source: Internet
Author: User

Honeycomb animation effects implemented with css3 and canvas

Recently, I have studied css3 and js animations. They are mainly used to enhance the fun of pages. We have intentionally or unintentionally added a lot of animations. Of course, most of them are css3 animations, gpu acceleration reduces performance requirements on mobile terminals.

Today, we mainly talk about cellular effects. For specific effects, you can run the source code. Here, we will not place gif images.

The principle of css3 is very simple, that is, by changing the background-size, because the background in css3 can set the repeat attribute to tile the background image in the x and y directions. First, Set background-size: 10%, 10% (this value can be freely defined, but you don't mind setting too large, otherwise the effect is not obvious), and finally change backg-size: 100%, 100%; this will fill the background image with the whole screen. Oh, don't forget to set the background-position: 50% 50%; otherwise, you will feel strange, background-position is set to tile the background image at the center point. By default, the background position is tiled in the upper left corner. Then, you can call the animation by setting the animation to achieve this effect.

.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%;}}

Css3 is used to implement the honeycomb animation effect. It is simple in principle and has perfect results. However, the only difference is that some mobile phones may be incompatible. In addition, by modifying the background-size in animation, this behavior is rare. Although it will not cause browser rearrangement, it will also cause partial repainting of the browser.

As for how to use canvas to implement it, this is purely boring. We do not recommend that you use this method. Here we use canvas to draw it. It is totally boring, however, if you are interested in canvas animation, you can pay attention to the canvas implementation solution below. The principle of canvas painting is very simple. The percentage of width and height is input to calculate the number of rectangles to be drawn and the coordinates of the center of each rectangle. I encapsulated this code into a module. You can look at it step by step. First, define an object honey.

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. wi Dth = 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 ['height'] | 1; this. img = options. img;/* if (! Options. img) {console. log ('image address not passed in ');}*/};
Some attributes of this object are defined below. The canvas image is drawn from the upper left corner by default. Therefore, we need to write a method to draw from the center point. We can add it 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);// }},


This method is simple, but it is a simple offset of half of the width and height, and then calls the default draw function of canvas.

The following method is to obtain the center point of the rectangle to be drawn. first look at the Code:

// Obtain the center point position of all small images. 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 the number of rectangles to be drawn in the horizontal and vertical directions is represented by the center point of the canvas 50, 50, numW, and numH respectively. Math should be used here. ceil rounded up to ensure that the entire canvas can be fully filled, and then x = 50 + width * I; indicates that the width value is subtracted from the x direction, it is equal to the number of x values on the left of the center. Similarly, in the y direction, the function returns an array containing all coordinate points. Next we will use this array and the above method to draw all the images 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'); t His. 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 ['dh Eight '] | 1; this. img = options. img;/* if (! Options. img) {console. log ('image address not passed in ');} */}; Honey. prototype = {// draw with the center point 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); //}, // obtain the center point position of all small images displayed getPoints: function (widt H, 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 ('image address not passed in '); 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; // prevents excessively large image scaling and automatically sets the stop flag if (width> = 100) {width = 100 ;} if (height> = 100) {height = 100;} if (width> = 100 & height> = 100) {self. stopped = true;} // draw 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 loop calling, instead of common setTimeout. For the specific reason, Google. Painting with canvas is performance-consuming and does not mind. However, when writing a canvas animation, you can consider adding such an animation effect.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.