Building a canvas animation framework (I) -- Extraction of common classes

Source: Internet
Author: User
Tags image flip

I have been doing canvas animation recently and found that canvas animation is not impossible. Compared with flash, it is too low-level. If there is a powerful editor or a powerful framework, it can exert more power.

Therefore, I decided to write a simple animation frame to facilitate the construction of some animation effects.

I will introduce the implementation of this small animation frame in several chapters:

1. Extraction of common classes: animation objects and Frame Objects

2. The combination of spirit and meat: An easy-to-disassemble Motion Equation

3. Implementation of the progress bar: canvas image pre-loading

4. demo test: Use a demo test framework

In this section, we will first talk about the extraction of general classes.

In fact, in the previous article, I have used this idea for reference from flash:An animated object (similar to a component in flash) and a frame object (similar to a frame in flash). Animation is implemented by constantly drawing Every animation object on the current frame. With these two objects and some motion methods, we can build a motion picture.

First, let's take a look at the animation object Aniele:

/** Aniele animation object * ancestor of all animation objects */var Aniele = function () {this. img = new Image (); // defines the animation object location this. loca = {x: 300, y: 300} // defines the animation object size (which can be scaled) this. dw; this. dh; // The speed attribute of the animation object this. speed = {x: 0, y: 0} // sets the object transparency this. alpha = 1; // set image flip, 1 is not flip,-1 is flip this. scale = {x: 1, y: 1} // set the animation object motion library this. motionFncs = [];} Aniele. prototype = {// Add the motion method addMotionFnc: function (name, fnc) {this. motionFncs [name] = fnc;}, // Delete the motion method deleMot IonFnc: function (name) {this. motionFncs [name] = null ;}, // traverse all the motion methods in the motion method library countMotionFncs: function () {for (var I = 0; I <this. motionFncs. length; I ++) {if (this. motionFncs [I] = null) continue; this. motionFncs [I]. call (this) ;}}, // you can draw your own method, including the function: horizontal flip draw: function (canvas, ctx) {// store the canvas status ctx. save (); // Changes the transparency of ctx. globalAlpha = this. alpha; // implements horizontal and vertical flip, and defines the two location parameters dx and dy var dx = this of drawImage. loca. x; var dy = This. loca. y; if (this. scale. x! = 1 | this. scale. y! = 1) {if (this. scale. x <0) {console. log (this. img. width) dx = canvas. width-this.loca.x-this.img.width; ctx. translate (canvas. width, 1); ctx. scale (this. scale. x, 1);} if (this. scale. y <0) {dy = canvas. height-this.loca.y-this.img.height; ctx. translate (1, canvas. height); ctx. scale (1, this. scale. y) ;}} if (this. dw = null) this. dw = this. img. width; if (this. dh = null) this. dh = this. img. height; // draw the ctx object. drawImage (this. img, dx, dy, this. dw, this. dh); // restore the canvas status ctx. restore ();}}

Main attributes of an animation object:

This. img = new Image (); we introduce an Image attached to an animation object.

This. loca. x, and so on; image size and position transparency, so that it can be called during plotting.

This. motionFncs = []; this is more important. We defineExercise LibraryAnd place the motion rules of the animation object in the motion detection library for unified management (each animation object has its own motion detection library)

Main Methods of animation objects:

AddMotionFnc: adds a motion method to the animation object's motion detection library.

DeleMotionFnc: deletes a motion method from the animation object's motion detection library.

CountMotionFncs: traverses all motion methods in the motion cube for an animation object.

Draw: draw the animation object on the canvas. Here we will upload the canvas as a parameter to this method to facilitate drawing.

In the draw method, I encapsulate some simple operations on the image. These operations are often used in animation:Transparent,ZoomAndFlip.

With this, we get a component in flash. We can modify its attributes to change it at will.

What about frame objects?

Frame Objects shoulder the rendering task and manage all animation objects:

/** Render rendering object * manage all animation objects and rendering * parameters: canvas object, canvas context */var Render = function (canvas, ctx) {// introduce canvas this. canvas = canvas; this. ctx = ctx; // create a buffer canvas this. backBuffer = document. createElement ('canvas '); this. backBuffer. width = this. canvas. width; this. backBuffer. height = this. canvas. height; this. backBufferctx = this. backBuffer. getContext ('2d '); // All animation objects this. aniEles = [];} Render. prototype = {// initialize the canvas int: function () {clearInterval (this. sint); this. ctx. clearRect (0, 0, this. canvas. width, this. canvas. height); this. backBufferctx. clearRect (0, 0, this. backBuffer. width, this. backBuffer. height) ;}, // set to start rendering begin: function () {this. lastFrame = (new Date ()). getTime (); this. sint = setInterval (function (progra) {return function () {progra. render () ;}}) (this), SECOND) ;}, // main Rendering Method render: function () {// clear historical frames on the canvas and cache canvas this. ctx. clearRect (0, 0, this. canvas. width, this. canvas. height); this. backBufferctx. clearRect (0, 0, this. backBuffer. width, this. backBuffer. height); // Save the current real-time output frame rate this. ftp this. nowFrame = (new Date ()). getTime (); this. ftp = 1000/(this. nowFrame-this.lastFrame); this. lastFrame = this. nowFrame; // call the motion method of each animation object for (var I = 0; I <this. aniEles. length; I ++) {if (this. aniEles [I] = null) continue; this. aniEles [I]. countMotionFncs (); // draws the object to the background buffer canvas. this. aniEles [I]. draw (this. backBuffer, this. backBufferctx);} // draws the background object to the foreground. this. ctx. drawImage (this. backBuffer,) ;}, // Add the animation object addAniEle: function (name, aniEle) {this. aniEles [name] = aniEle;}, // Delete the animation object deleAniEle: function (name) {this. aniEles [name] = null ;}}

The main attributes of the frame object:

This. aniEles = []; is used to store arrays of all animation instances on the current canvas.

I should know when I use canvas to load images. Due to the asynchronous loading of images, the images will flash during the animation process. To avoid this problem, I usedDouble Buffering.

First, create a canvas in the background:

This. backBuffer = document. createElement ('canvas ');

This. backBuffer. width = this. canvas. width;

This. backBuffer. height = this. canvas. height;

This. backBufferctx = this. backBuffer. getContext ('2d ');

All the drawing commands are executed on the background canvas, and the background canvas is finally painted:

This. ctx. drawImage (this. backBuffer, 0, 0 );

This method is called dual-buffer technology.

The main methods of frame attributes are as follows:

Int: used to initialize the canvas.

Begin: Method for starting animation Rendering

Render: Primary Rendering Method

AddAniEle: add an animation object to the current frame

DeleAniEle: deletes an animation for the current frame.

The process of using the frame object is: first add an animation object to the current frame, and then let the current frame start rendering.

 

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.