In the introduction to canvas, the knowledge you didn't notice

Compared with reading various articles, I prefer the logic in mathematics; compared with learning various frameworks that are changing with each passing day, I prefer the solid foundation brought by people; I prefer animations, and the graphics are intuitively represented on the page.

Maybe you are just like me, because of your curiosity about H5 and your love for graphics, you have learned canvas, but you are not proficient, but simply entered a door. Maybe you stumbled on the threshold of entry, and your classmates don’t cry. , stand up and continue licking. I wrote down the accumulation of my entry two days, some thresholds, tripped hundreds of times, and some should also work for you. The ctx below refers to the 2d graphical instance created by canvas, the code:

var canvas = document.querySelector('#test');  //test是Html中一个canvas元素的ID,其宽为600,高为400;
var ctx = canvas.getContext('2d');

say something important

The 2d context (canvas) coordinates start at the upper left corner of the <canvas> element, its vertex is the origin of the coordinates, the positive x-axis points to the right of the screen, and the positive direction of the y-axis points to the bottom of the screen. Therefore, the larger the x value, the more right, and the larger the y value, the lower. This is very different from our traditional coordinate axis, which may be seen in the following picture. The reverse of the Y-axis may be easy to understand, but it is worth remembering that the positive 0 degree clockwise is at the position of the coordinate axis. It is very important to be familiar with this common sense when using arc.

four basic methods

Stroke: stroke and strokeStyle

ctx.strokeStyle = 'red';
 ctx.arc(200,200,50,0,PI*2,false);
 ctx.stroke();

The lineTo, moveTo methods are very basic. Here, let’s talk about the arc(x,y,r,startAngle,endAngle,direction) method of drawing a circle. This method accepts 6 parameters, the first five are required, which are the position of the center of the circle ( x coordinate, y coordinate), then the radius r of the circle, and then the starting position angle and the ending position angle, these two are very important, combined with the previous picture, we can see that the first code drawn by the above code A point is (0,50), and the end position is also (0,50). The latter direction is an optional parameter. The default value is false, which means clockwise drawing. When true, it is counterclockwise drawing.

Special Note:

  • The Red Book says that drawing a path should start with the beginPath() method, but practice has proved that this is not necessary. You only need to end the drawing of this path in the stroke method, but adding it is not a bad thing, so it is still add it;
  • Only call the lineTo(0,50) method once, you will not see a straight line drawn, because (0,0) is not the default starting point, unless you first set a starting point with the moveTo() method, this simple truth Call two points to determine a straight line;
  • closePath() is not a method used in contrast to beginPath, its role is to draw a closed path, as shown in the following figure. It can be seen that we only called the lineTo method twice, but in the end, in addition to three lines, the last line is the effect of closePath. But it should be noted that closePath needs to be called before stroke is used.

Fill: fillStyle and fill

ctx.fillStyle = 'red'
ctx.arc(200,200,50,0,PI/3,false);
ctx.fill();

Corresponding to the stroke is fill, but this method is not very particular. Generally speaking, only closed intervals are eligible to fill, but the fill method is not required. As long as your path is not a straight line, it can be filled. That is, three points that are not on the same straight line can determine a plane. This method is really awesome, and I must be convinced.

Drawing text: stokeText and fillText

The above two methods can write a word, but the recommended usage is fillText, because it writes solid characters, while stokeText writes stroked hollow characters, which is used by most artistic characters. Of course, you can use a combination of the two if you want.

ctx.fillStyle = 'red'
ctx.font= 'bold 12px Arial';
ctx.fillText('Test',300,200);

ctx.strokeStyle = 'red'
ctx.font= 'bold 12px Arial';
ctx.strokeText('Test',400,200);

Drawing an image: drawImage

I believe that many beginners can't see this place. Isn't canvas just for drawing images, ah, it's not accurate, canvas is for drawing graphics. Specifically, it is drawImage, which can not only draw pictures on the canvas, but also draw canvas graphics. This is most used in cases such as starry sky and raindrops, and it is also the most used for canvas off-screen optimization. See the following example.

var cache = document.createElement('canvas');

cache.width = 50;

cache.height = 50;

var cacheCtx = cache.getContext('2d'); //This is a virtual canvas because it is not added to the dom node;

cacheCtx.beginPath();
cacheCtx.strokeStyle = 'red';
cacheCtx.moveTo(5,5);
cacheCtx.lineTo(20,40);
cacheCtx.lineTo(40,20);
cacheCtx.closePath();
cacheCtx.stroke();

ctx.drawImage(cache,50,50);
ctx.drawImage(cache,50,100);
ctx.drawImage(cache,100,50);
ctx.drawImage(cache,100,100);

Through the above example, we can see the application of drawImage in off-screen optimization. Why is this possible, because, like above, we want to draw four identical triangles on a canvas, which in browser performance, you can't see any lag, then if you want to draw a thousand on the screen There are 1 or 10,000 such graphics, and their positions should be changed regularly in each frame. At this time, you can obviously feel the browser's lag, because you have been manipulating the elements in the dom, so that the browser is always In the non-stop repainting, rendering the web page. But if you draw the next state in each frame, in js, first draw the background state of the next frame in the virtual canvas, and then use the drawImage method to update the canvas state in the browser, so that the web page It only needs to be rendered once in a frame, instead of rendering it all the time, which achieves the purpose of off-screen optimization, so this is also the most used scene for drawImage.

After completing the above knowledge, even if it is to review the introductory knowledge, as for why fillRect and strokeRect are not mentioned, in fact, it is a syntactic sugar provided by stroke and fill for drawing rectangles.

wonderful transformation

Maybe you, like me, are not accustomed to starting from the upper left corner of our coordinate system, and we are more accustomed to the origin of the coordinate system being in the lower left corner or the center.

Coordinate origin transformation translate method

The origin is transformed to the center of the canvas: ctx.translate(WIDTH/2, HEIGHT/2), WIDTH and HEIGHT refer to the width and height of the canvas respectively. In order to make the coordinate transformation more obvious, I drew two pieces in the same area. Similar canvases, and then let one use the original coordinate system, and the other use the translate-transformed, see the code and the result diagram for details;

<div class="red">
    <canvas id="test" width="600px" height="400px"></canvas>
    <canvas id="testa" width="598px" height="398px"></canvas>
</div>

var ctx = document.querySelector('#test').getContext('2d');
var crx = document.querySelector('#testa').getContext('2d');

ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.arc(0,0,5,0,PI*2,false);
ctx.moveTo(0,0);
ctx.lineTo(0,150);
ctx.moveTo(0,0);
ctx.lineTo(150,0);
ctx.stroke();

crx.beginPath();
crx.translate(300,200);
crx.arc(0,0,5,0,PI*2,false);
crx.strokeStyle = 'red';
crx.moveTo(0,0);
crx.lineTo(0,150);
crx.moveTo(0,0);
crx.lineTo(150,0);
crx.stroke();

Coordinate system rotation transformation rotate method

Maybe you have been in contact with canvas for a long time, but the rotate method has never been used. I just remember that the use of rotate is mentioned in the red book when drawing the hour and minute hands of the clock, but as long as you are familiar with it, the usage can be very strange. The API explicitly says rotate(angle), which means to rotate the image by angle radians around the origin. So, you need to remember two things. First: the image is rotated around the origin; second: the entire coordinate system is rotated rather than the image. Looking at the example, it is still the same as above. There is a comparison to be convincing:

ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.translate(300,200);
ctx.arc(0,0,5,0,PI*2,false);
ctx.moveTo(0,0);
ctx.lineTo(0,150);
ctx.moveTo(0,0);
ctx.lineTo(150,0);
ctx.stroke();
ctx.moveTo(0,0);
ctx.lineTo(0,-150);
ctx.stroke();

crx.beginPath();
crx.strokeStyle = 'red';
crx.translate(300,200);
crx.rotate(PI/3); //旋转60*
crx.arc(0,0,5,0,PI*2,false);
crx.moveTo(0,0);
crx.lineTo(0,150);
crx.moveTo(0,0);
crx.lineTo(150,0);
crx.stroke();
crx.moveTo(0,0);
crx.lineTo(0,-150);
crx.stroke();

与上个图相比,我将两块画布的中心都先变换到了画布的中心,作为对比,红色画笔的做了旋转变换,在分别绘制了正x,正y轴以后,在stoke方法结束一段绘制以后,又绘制了负y轴,可以看到,上一段绘制路径的rotate仍然起作用,所以rotate是对画布坐标系做了变换,而不是狭义上的绘制图像,这个区别很重要。后面在上一段代码,不用sin,cos计算,就能绘制一个正多边形,这里以6边形为例。

ctx.beginPath();
ctx.translate(300,200);
ctx.strokeStyle = 'red';
var a=0;
for(var i=1;i<7;i++){
    ctx.lineTo(0,150);
    ctx.rotate(PI/3);
    a =a + PI/3 ;
}
ctx.closePath();
ctx.stroke();
ctx.lineTo(0,0);
ctx.stroke();

不重要,但很点题的API

绘制一个普通的图形,也许上面的API也已足够,但要让你的图形有亮点,你可能还需要多了解一些,我个人觉得非常有用的两个就是阴影的绘制(shadow)与渐变色的添加(createLinearGradient)。在用canvas做星星背景时,或者飞行的流星周围的闪光,这些都是用shadow做出来的特效。而消逝的流星,头部亮,尾部暗的效果就是用渐变色做的,在以后的系列中,会结合实例多讲一些。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326191983&siteId=291194637