Canvas & SVG & DOM
Canvas and SVG are both powerful 2D plotting tools. In addition, CSS and DOM can also be used to draw certain characters, and these techniques can also be used in animation to achieve animation effects. Here we will briefly compare these technologies.
• Canvas: canvas draws a picture in the form of pixels without the concept of shape and vector. So there is no object to accept the event. It just draws the pixel. This is both a disadvantage and an advantage.
• SVG: SVG draws shapes based on vectors. Each shape can accept events. The biggest advantage of a vector chart is that scaling is not distorted. This is something canvas cannot do.
• CSS: CSS adds styles to DOM objects. Because there is no DOM object in the canvas, CSS cannot be used for images in the canvas. CSS can only act on the canvas itself, such as the background color and border.
• DOM Animation: DOM defines all objects on the screen. DOM animation, whether implemented using CSS or Javascript, can be smoother than canvas. However, this is related to browser implementation.
As we can see from the above, there are many restrictions on canvas, so why should we use cavas?
First, canvas is a more underlying technology. You can easily control the Painting Process and the memory usage is also relatively low, but the cost is to write more code. The advantage of SVG is that it can be drawn using existing shapes. CSS or DOM animation has the advantage of a wide range of animation areas.
Secondly, if you want to use 3D transform for graphs, graphs, dynamic charts, and video games, canvas is a good choice.
In addition, canvas provides direct API support for 2D plotting, But 3D APIs are provided by WebGL. WebGL is a more underlying technology that is difficult to use, but also more powerful.
Event
The event is the basis. Here is a brief introduction to the canvas event. Canvas does not define any new events. You can still listen to any mouse events as before. As mentioned above, canvas is a series of pixels that do not respond to any events, so the browser does not know what is inside canvas.
If you want internal graphics to accept events, it is almost impossible for canvas. Fortunately, you can still know that the given point is not in the current path. The example is as follows:
C. beginPath ();
C. arc (
100,100, 40, // 40 pix radius circle at 100,100
0, Math. PI * 2, // 0 to 360 degrees for a full circle
);
C. closePath ();
Var a = c. isPointInPath (80, 0); // returns true
Var B = c. isPointInPath (200,100); // returns false
To check whether a vertex is in a graphic (Rule-based image, such as a self-drawn button), we usually compare the coordinates of the vertex with the coordinates of each vertex of the graph.
Basic Animation
The basic idea of animation is to use scripts to manipulate canvas objects, so it is quite easy to implement interactive animations. However, canvas is not designed specifically for animation (unlike Flash), so operations may be limited.
The biggest limitation is that once an image is drawn, it will always be like that. If you need to move it, we have to re-paint everything. Re-painting is quite time-consuming, and the performance depends on the speed of the computer.
Basic animation steps:
1. To draw a frame, perform the following steps:
(1) Clear the canvas
Unless the content to be drawn is fully filled with a canvas (for example, a background image), you need to clear all the items. The simplest way is to use the clearRect method.
(2) Save the canvas status
If you want to change the settings that will change the canvas state (style, deformation, and so on) and the canvas state is original when every frame is drawn, you need to save it first.
(3) drawing animated images (animated shapes)
This step is to re-paint the animation frame. The general steps are to generate a new image, update the existing image location, clear the image that has been moved outside the canvas, and finally draw a new scene.
(4) restore the canvas status
If you have saved the canvas status, you can restore it and redraw the next frame.
2. Calculate the graph transformation according to certain settings, and redraw new frames. The process of drawing each frame is the same.
There are usually two ways to set the repainting frequency:
(1) timed re-painting
The first method is to use the setInterval and setTimeout methods to control the re-painting at the specified time point.
SetInterval (animateShape, 500 );
SetTimeout (animateShape, 500 );
The setTimeout and setInterval syntaxes are the same. They all have two parameters: one is the code string to be executed, and the other is the interval in milliseconds. after that period, the code will be executed.
However, there are differences between the two functions. After the setInterval code is executed, it automatically repeats the code after the fixed interval, setTimeout only executes the code once.
If you do not need any interactive operations, it is best to use the setInterval method to perform regular re-painting.
(2) redraw a specific event
Second, we can use user input for control. If you want to make a game, you can control the animation effect by monitoring events triggered during user interaction (such as various keyboard and mouse events of the document.
The following example uses the first method to simulate a simple snow scenario. The loop method defines the operations required for each frame:
<Html>
<Body>
<Canvas width = "800" height = "600" id = "canvas"> </canvas>
<Script>
Var canvas = document. getElementById ('canvas ');
Var participant = [];
Var tick = 0;
Function loop (){
CreateParticles ();
UpdateParticles ();
Killparticle ();
Drawparticipant ();
}
Function createParticles (){
// Check on every 10th tick check
If (tick % 10 = 0 ){
If (participant. length <100 ){
Participant. push ({
X: Math. random () * canvas. width,
Y: 0,
Speed: 2 + Math. random () * 3, // between 2 and 5
Radius: 5 + Math. random () * 5, // between 5 and 10
Color: "white ",
});
}
}
}
Function updateParticles (){
For (var I in participant ){
Var part = participant [I];
Part. y + = part. speed;
}
}
Function killparticipant (){
For (var I in participant ){
Var part = participant [I];
If (part. y> canvas. height ){
Part. y = 0;
}
}
}
Function drawparticipant (){
Var c = canvas. getContext ('2d ');
C. fillStyle = "black ";
C. fillRect (0, 0, canvas. width, canvas. height );
For (var I in participant ){
Var part = participant [I];
C. beginPath ();
C. arc (part. x, part. y, part. radius, 0, Math. PI * 2 );
C. closePath ();
C. fillStyle = part. color;
C. fill ();
}
}
SetInterval (loop, 30 );
</Script>
</Body>
</Html>
Genie Animation
Genie animation is also a common animation technique.
A genie is a small image. You can quickly draw it to the screen. Generally, a genie is a part of a big image, which also becomes a Sprite clip. This clip may include all actions of an genie or all the roles in a game. By drawing different genie in Different frames, an animation is an animated genie. This is also a typical book-turning animation. When you were a child, you must have painted many of these types of animations.
Why use genie?
It has the following advantages:
1. The genie is a small image, so the rendering speed is very fast. In particular, it is relative to a complicated vector.
2. It is easier to use the genie when you repeat an object multiple times. For example, a bullet in an Air Combat Game can be loaded once when the screen is full, and the bullet genie can be constantly drawn.
3. The genie can be quickly and conveniently downloaded. As long as you download an image, all the genie will be downloaded. This is more convenient than downloading many small images, and the memory usage is relatively small.
4. Low coupling, easy to upgrade genie. Because your code only knows how to play the Genie without worrying about the content of the genie. In this way, it is very convenient to change the genie image later. You just need to modify the image.
The process of rendering the genie is very simple. As mentioned above, the Sprite is a small image. You can use the image rendering API: context. drawImage.
Optimization
As we can see from the above, canvas animation will be re-painted in every frame, which is very time-consuming. To improve animation efficiency, we need to optimize the rendering process. The general principle here is "Less painting ".
• Do not draw invisible objects.
• Use genie instead of a large number of images. For some objects that won't change, use photoshop to draw them in advance. Images are usually drawn faster than complex vectors, especially when you need to repeat them.
• Use cache. You can create an invisible canvas as a cache during running. When the program is idle, You can first draw a graph to this cache. When you need to use it, copy it directly. This is similar to the direct use of images.
• Use Image stretching to implement some special effects. Most canvas implementations optimize the image stretching and cutting code, so sometimes it is faster to use images to achieve some results.
• Only redraw the part to be repainted.
• Reduce the number of frames. Generally, the higher the number of frames, the smoother the animation, but it does not work if it exceeds 60 FPS, because the refreshing rate of most displays is 60. Therefore, selecting an appropriate number of frames can be optimized to achieve smooth performance.
If you do not draw less, haha. If the background is unchanged, you can put it in the Browser and set the canvas background to transparent. If there is a large scope of animation, use CSS to implement it, because CSS is implemented through C code and the efficiency is higher than that of JS.
• Point-to-point rendering. If you can, make sure that the grid coordinate system is consistent with the pixel coordinate system. In this case, Some browsers have a high rendering efficiency.
Canvas is basically like this, Over.
From the autumn army