Basics of canvas


This article can be used as a basic reference of canvas. Basically covers all the canvas content, of course, does not include the use of canvas to deal with advanced applications.


The basic problems are as follows:

Draw a line

The basic architecture is as follows

ctx.beginPath(); //  Start drawing lines, there are no parameters in them
ctx.moveTo(x,y); //  Define starting point
ctx.lineTo(x,y); //  Defining process points
//You can also define line width and line color
ctx.stroke();  //  Start scribing. There are no parameters in it


//It's simple 


Control line width

ctx.lineWidth = 20; //  The default unit is px


The line color definition can use:

ctx.strokeStyle = "#fff";


The format of defining both ends of a line is:

context.lineCap = 'butt';

The attribute has three values: but, round and square. They are as follows:

Basics of canvas


Used to describe the connection between multiple paths. The basic values are: round, begin, miter.

      context.moveTo(379, 150);
      context.lineTo(429, 50);
      context.lineTo(479, 150);
      context.lineJoin = 'bevel';

Details are as follows:

Basics of canvas


Curves and segments
Basic area: arc, conic, Bezier curve.


The basic format is as follows:

ctx.arcTo(cx1, cy1, x2, y2, radius);

Again, use moveto or lineto to determine the first starting point.

    context.moveTo(100, 225);             // P0
    context.arcTo(228, 40, 530, 70, 89); // P1, P2 and the radius
    context.lineTo(530, 70);             // P2 

Above, P2 uses lineto. Does that make any difference? yes , we have.
If lineto is not defined, the arc may not pass to P2, because the actual algorithm of the arc is:

Basics of canvas

It only determines the size of the range of the final arc and does not focus on whether the P2 point is connected. If no lineto is defined, the result is:

Basics of canvas

Quadratic Curve

This method is used to draw a conic

ctx.quadraticCurveTo(cpx, cpy, x, y);

He usually combinesmoveToTo find three points and determine the quadratic function.

ctx.moveTo(50,20);  //  Points on the x-axis (50,20)
ctx.quadraticCurveTo(230, 30, 50, 100); //  The control points were (230,30).
//In addition, the point on the x-axis is (50100)

Basics of canvas

bezier Curve

The tag is used to draw Bezier curve, that is, the shape of the line can be determined by defining four points

//There are two control points and one datum point defined here
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);

There are four points mentioned above, and another point is defined by moveto. The basic format is as follows:

ctx.bezierCurveTo(230, 30, 150, 60, 50, 100);

As shown in the figure:

Basics of canvas

The actual calculation method is to take the midpoint, and then take the tangent through the midpoint.

Basics of canvas


Basic simple graphics are: circle, ellipse, custom graphics
Graphics is usually combined with CTX. Fill() to trigger rendering.


This API is used to draw one on canvas.

//The basic format is
ctx.rect(x, y, width, height);

//Or use a combination of the two
ctx.fillRect(x, y, width, height);

It should be easy to see what API is used for.
Rect default color isblack. Of course, you can also usefillStyleTo change the color of the display.

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

Rectangular box

The above form is used to draw graphic content. Next, we can use strokerect() to draw a rectangular border.
The basic format is as follows:

ctx.strokeRect(x, y, width, height);

Practical drawing.

ctx.strokeStyle = "green";
ctx.strokeRect(10, 10, 100, 100);

Here, you can use stroke directly without triggering rendering in the display. Draw a border. Of course, you can use line related attributes, such as defining line width.

ctx.lineWidth = 5;

In fact, rect can also be used to draw a rectangle

      context.rect(188, 50, 200, 100);
      context.fillStyle = 'yellow';
      context.lineWidth = 7;
      context.strokeStyle = 'black';
      context.stroke();  //  Triggers the effect of drawing borders


The basic format is as follows:

//The default is counterclockwise
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

Startangle calculates the angle clockwise from the positive direction of the X axis.
Detailed Demo:

ctx.arc(75, 75, 50, 0, 2 * Math.PI);

//Circle clockwise
ctx.arc(75, 75, 50, 0, 2 * Math.PI,false);

For example, draw another semicircle.

      context.arc(288, 75, 70, 0, Math.PI, false);
      context.closePath();  //  Closed graph
      context.lineWidth = 5;
      context.fillStyle = 'red';
      context.strokeStyle = '#550000';


This API is recently proposed and relatively new. Therefore, compatibility needs to be considered. The basic format is as follows:

//X and Y determine the position of major axis and minor axis
//Rotation is in the positive direction of x-axis and in accordance with the setting of anticlockwise, which is also in radian
//Startangle and endangle are also in the positive direction of the X axis
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);

His angle representation is in radians.
Here is an example

ctx.ellipse(100, 100, 50, 75, 45 * Math.PI/180, 0, 2 * Math.PI);

The picture shows:

Basics of canvas

Of course, you can also use fill and so on to fill in the relevant colors.

Custom graphics

If you want to draw a custom graph, you need to combine the line related labels. Finally, use closepath() to display the closed graph.
The actual function of the closepath API is to do nothing when your current point coincides with the starting point. Otherwise, the current point and the starting point are connected with a straight line to form a closed graph, so that fill correlation can be used to fill.

      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');

      // begin custom shape
      context.moveTo(170, 80);
      context.bezierCurveTo(130, 100, 130, 150, 230, 150);
      context.bezierCurveTo(250, 180, 320, 180, 340, 150);
      context.bezierCurveTo(420, 150, 420, 120, 390, 100);
      context.bezierCurveTo(430, 40, 370, 30, 340, 50);
      context.bezierCurveTo(320, 5, 250, 20, 250, 50);
      context.bezierCurveTo(200, 5, 150, 20, 170, 80);

      // complete custom shape
      context.lineWidth = 5;
      context.strokeStyle = 'blue';

Finally, you must remember to use closepath () to achieve the effect of complete graphics.


About filling: basic color filling, gradient filling, picture filling. There are two basic color fills, fillStyle and stroke style. The two basic shapes as like as two peas:

//Fill in basic color values, such as # FFF
ctx.fillStyle = color;
//Fill in gradient values, such as those created by createlinear
ctx.fillStyle = gradient;
//Values usually used for mapping
ctx.fillStyle = pattern;

Color fill

That is to say, fill in the RGB value.

ctx.fillStyle = "blue";

Gradient fill

There are two kinds of gradients, one is a linear gradient: createlinear gradient (), the other is a central gradient: createradial gradient(). They can use a common API: addcolorstop(). To set the interval color. The basic format is as follows:

addColorStop(offset, color);
  • Offset: a number between [0,1]

  • Color: the value of RGB

var gradient = ctx.createLinearGradient(0,0,200,0);
ctx.fillStyle = gradient;


The contents of linear gradient are as follows:

ctx.createLinearGradient(x0, y0, x1, y1);

Two points determine a straight line, and then the color gradient according to this line segment.


Basics of canvas

The code is:



The content of the center gradient is as follows:

ctx.createRadialGradient(x0, y0, r0, x1, y1, r1);

And above is two circles, and then in order, the color gradient, of course, the middle can also add multiple segments.


Basics of canvas

The code is:

        let gradient = ctx.createRadialGradient(200,200,0,200,200,160);

Pattern – Map

This area should be regarded as the best place for canvas, and the key point to combine with the elements related to graphics. The format is:

ctx.createPattern(image, repetition);
  • Image: there are many values for this type, such as image, video, cavnas, imagedata, blob, etc.

    • HTMLImageElement (< img>)

    • HTMLVideoElement (< video>)

    • HTMLCanvasElement (< canvas>)

    • CanvasRenderingContext2D

    • ImageBitmap

    • ImageData

    • Blob

  • Repetition: the content of this value is very simple, which is equivalent to the background. It is used to set the repetition form of the image.

    • Repeat (default)

    • repeat-x

    • repeat-y

    • no-repeat

Here is a list of maps:

var img = new Image();
img.src = '';
img.onload = function() {
  var pattern = ctx.createPattern(img, 'repeat');
  ctx.fillStyle = pattern;

Image processing

There are a lot of API related to image processing. Here’s the most basic one, drawimage(). It has three basic forms

void ctx.drawImage(image, dx, dy);
void ctx.drawImage(image, dx, dy, dWidth, dHeight);
void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

Let’s talk about it respectively

Simple drawing

void ctx.drawImage(image, dx, dy);

Three simple parameters are used to determine the position of the image on canvas without any scaling.

Basics of canvas

Zoom draw

The basic format is as follows:

void ctx.drawImage(image, dx, dy, dWidth, dHeight);

Through, dwidth and dheight to determine the size of the painting in canvas, you can zoom in and out.

Basics of canvas

The code is:

let img = new Image();
img.onload = function(){
img.src = "...";

Crop drawing

The basic format is as follows:

void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);

SX, sy, swidth and sheight are used to determine the region of the original image.

Basics of canvas

The specific codes are as follows:

let img = new Image();
img.onload = function(){
img.src = "...";

Font processing

In canvas, there is also a trick to display text. In terms of words, there is nothing special about the basic style, szie, color, etc. Generally, it is used together with filltext / stoketext API to draw. The difference between the two APIs is also very common, that is, simple filling solid font and boundary font.

context.font = 'italic 40pt Calibri';
context.fillText('Hello World!', 150, 100);

First of all, these two APIs. Their format is basically the same

ctx.strokeText(text, x, y [, maxWidth]);
  • x. Y is used to determine the starting point of the lower left corner of text. It’s important. It’s the lower left corner!

  • Maxwidth: used to determine the width of the text rendering. If the font is large, it will be automatically reduced and will not wrap.

Basics of canvas

The code is:

ctx.font="20px serif";
ctx.strokeText("I dont Know how to Do",20,20,200);

Font – Font

To define the simplest font, use:


The value of value is the value of the general CSS font attribute. The default is 10px sans serif

ctx.font = "48px serif";

Here, you can also use the relatively new API fontface() to use online fonts:

var f = new FontFace("font-name", "url(x)");
  f.load().then(function() {
    ctx.font="20px font-name";

Font color

The color of the font is the same as that of the figure abovefillStyleandstrokeStyleI won’t go into details here.

Font border thickness

If you define the thickness, you can also use linewidth.

Arrangement of fonts

The basic format is as follows:

//The default is start
ctx.textAlign = "left" || "right" || "center" || "start" || "end";

Here, it is not used to define the arrangement position of the font in canvas, but to define the position of the reference point relative to the font.
The common layout is center layout

Basics of canvas

The code is:

ctx.font="20px serif";
ctx.strokeText("I dont Know how to Do",200,200);

Other values, such as left and right, are drawn relative to the point.
For example, take right / end:

Basics of canvas

Baseline position

The basic format is as follows:

//The default value is: ideographic
ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";

Similar to baseline, this attribute is used to determine where the baseline is in the font. In positioning, the line is not moving, the word is moving.
For details:

Basics of canvas

Measurement font

If you want to know the width of the current font, you can usemeasureTextAPI. The basic use is also very simple:

var text = ctx.measureText("foo"); // TextMetrics object
text.width; // 16;

Of course, many other measurements are mounted on the object returned by this property, but the compatibility is poor. The key point is that the API can be combined to draw the font content of the branch. To put it simply, it is to determine whether the rendered string exceeds the width of the line by splitting the string, and then decide whether to add lineheight to the y-axis value of the identification point.
Let’s look at an algorithm

function wrapText(context, text, x, y, maxWidth, lineHeight) {
        //Split characters by using '' (not for Chinese here)
        var words = text.split(' ');
        var line = '';

        for(var n = 0; n < words.length; n++) {
         //Judgment line
          var testLine = line + words[n] + ' ';
          //Measures the width of the rendering
          var metrics = context.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > maxWidth && n > 0) {
           //More than, the next line
            context.fillText(line, x, y);
            line = words[n] + ' ';
            y += lineHeight;
          else {
            line = testLine;
        context.fillText(line, x, y);
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var maxWidth = 400;
      var lineHeight = 25;
      var x = (canvas.width - maxWidth) / 2;
      var y = 60;
      var text = 'All the world \'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.';

      context.font = '16pt Calibri';
      context.fillStyle = '#333';

      wrapText(context, text, x, y, maxWidth, lineHeight);

Transformation in canvas

About change, the most basic is translate, scale, skew and so on. In canvas, these are based on the canvas coordinate system.


This is the change used to translate the origin. The basic format is as follows:

ctx.translate(x, y);
  • x: The moving direction of the current coordinate system in the X axis

  • y: The movement direction of the current coordinate in the Y axis

Of course, there is a corresponding 2D transformation matrix, which is the same as the transform attribute. You can use the following transformations:

ctx.setTransform(1, 0, 0, 1, x, y);


This is used to rotate the coordinate system. The basic format is as follows:

//The parameter inside is radian, which can be converted by using math. PI

For example:

ctx.rotate(45 * Math.PI / 180);

When rotating, the value of the rotation angle in the matrix is expressed according to the sin function.

ctx.setTransform(cos θ, sin θ,- sin θ, cos θ, 0,0) // is CS SC


The basic format is as follows:

ctx.scale(x, y);

It means:

  • x: Enlarge / reduce the x-axis by x times. That is, the set pixel value is multiplied by the valuexValue

  • y: Enlarge / reduce the y-axis by Y times. That is, the set pixel value is multiplied by the valueyValue

Watch a demo:

ctx.scale(10, 3);
//The final result is to draw a rectangle with width: 100 and height: 30 at (100,30).

In addition, you can use this property to invert:

ctx.scale(-1, 1); //  X-axis symmetry
ctx.font = "48px serif";
ctx.fillText("Hello world!", - 320, 120); //  The value of the x-axis needs to be set to a negative number
ctx.setTransform(1, 0, 0, 1, 0, 0); //  Restore coordinates

It corresponds to the expression of matrix

setTransform(A, 0, 0, B, 0,0);
//X-axis magnification a
//Y-axis magnification B

Matrix transformation

There is no difference between API of matrix transformation and CSS3 animation

ctx.setTransform(a, b, c, d, e, f);

The most commonly used is for coordinate restoration. Because each transformation covers the last change, the coordinate is usually restored by the following method:


However, in addition to this method, other transformations are based on the changed coordinates.


The API is somewhat different from settransform. Settransform is equivalent to reset, and transform will be based on the result of the previous transform, and then transform. It is used in a similar way to settransform.

ctx.transform(a, b, c, d, e, f);


It’s equivalent tosetTransform(1,0,0,1,0,0)The packaging of the product.


state stack

In canvas, because there are many operations sometimes, it may cause the coordinates to be transformed back and forth. At this time, you can use the state management in & restoreThese two methods are equivalent to stack’spush & popmethod. One goes in and one goes out. So what do these states hold?

  • Deformation operation, basic movement, scaling, rotation, matrix transformation, etc.

  • Clipping Region

  • dash list

  • And related strokes, filling state. For example: stroke style, fillStyle, global alpha, linewidth, linecap, linejoin.

However, it is only saved as a state. When combined with restore, it will play its due effect.;
ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);
//Restore the original fillStyle content
ctx.fillRect(150, 75, 100, 100);


Layer merging in canvas involves shadow, clipping and other effects.

shadow effect

There are four APIs for shadow in canvas.

  • shadowBlur

  • shadowColor

  • shadowOffsetX

  • shadowOffsetY

Here are the details:


This is used to add shadows. The basic format is:

ctx.shadowBlur = level;

The default value of level is 0, indicating that there is no shadow. In addition, negative, infinity or Nan cannot be used. The meaning of level expression is only to specify the range of shadow blur. It should be noted that once you set the shadow blur, all elements drawn on canvas will be shaded, even transparent elements. Therefore, in general, you can manually withdraw:

ctx.shadowBlur = 0;

Alternatively, save and restore are combined to perform state rollback.;
ctx.shadowBlur = 5;


Used to set the color value of shadows. The default is opaque black.

Basics of canvas

The basic format is as follows:

//Color is "black" by default
ctx.shadowColor = color;


This is actually the same as the shadow effect set by box shadow, which is used to define the offset of the shadow relative to the original figure. The basic format is as follows:

//The default value of offset is 0, which is equivalent to the pixel value on canvas
//It can be negative, but not infinity or Nan
ctx.shadowOffsetX = offset;

Examples are:

//Moving shadows on the x-axis
ctx.shadowOffsetX = 10;
//Move shadow on Y axis
ctx.shadowOffsetY = 10;


In canvas, defining colors only supports RGB format. If you want to set transparent colors, you need to useglobalAlphaProperty value. The basic format is as follows:

//Value is [0.0,1.0] 
//The default value is 0.0, which means opaque
ctx.globalAlpha = value;

Watch a demo:

ctx.globalAlpha = 0.5;

ctx.fillStyle = "blue";
ctx.fillRect(10, 10, 100, 100);

ctx.fillStyle = "red";
ctx.fillRect(50, 50, 100, 100);

Basics of canvas

Cutting effect

In canvas, it is generally used toclipAPI to cut the screen. The basic format is as follows:

//Most commonly used
void ctx.clip();
//There are two main types of fillrules, which will be explained later
void ctx.clip(fillRule);
//Here is the path to be drawn when the parameter is passed to the clip
void ctx.clip(path, fillRule);


First, explain fillrule
There are two common fillrules, one is non zero, the other is even odd. The main function is to determine whether the overlapping region belongs to the clipping region. OK, what is overlapping area? namely:

Basics of canvas

In this case, how can canvas judge whether such areas overlap?
The default algorithm is nonzero.


Basics of canvas

Its specific process is to select a P point in the overlapping area, and then randomly make an infinite ray according to a direction, detect the intersection of the line and the boundary, and judge whether the contact position is clockwise or counterclockwise. If it is clockwise, then – 1, if it is counter clockwise, then + 1. If the final result is 0, it means that the area is outside, otherwise it is inside.
So, if the result above is – 2, not 0, it means it’s inside.

even-odd rule

Basics of canvas

The main convention of this algorithm is to count the times of intersection between ray and boundary. If it is even, it means it is not inside. If it is odd, it means it is inside.

Therefore, according to the algorithm, if the above result is 2 (even), it is not internal.

In most cases, though, you don’t need to care too much about it. Next, let’s practice how to draw the clipping region. Here, we can putclipThink of the method as a stroke method. Before clip, draw the path manually. After drawing, you can trigger clip to clip.


The actual style is:

Basics of canvas

Effect of overlapping layers

The API used for layer overlap is as follows:globalCompositeOperation. It is mainly used to specify the effect of drawing two overlapping layers. The basic format is as follows:

globalCompositeOperation = type

For basic values, please refer to:Globalcompositeoperation – value content

Image processing of canvas

The content of image processing in canvas is not much. There are basically three APIs: createimagedata(), putimagedata(), getimagedata(). The first one is used for screen capture, and the second / third one is used to obtain the basic information of images. There is a more important concept about image, which is imagedata.

  • Imagedata: it’s actually the complete image content. It is the upper layer representation of the bottom pixel, which has three attributes attached.

    • Width: the width of a picture

    • Height: the height of a picture

    • Data: Yes Uint8ClampedArrayFormat, actually a one-dimensional array, in order, each pixel occupies 4 bits, which contains the content of RGBA, each bit is a number of 0-255 size. Finally, the transparency is a little special. The value of [0-255] means that it is opaque. If you need to use RGBA in CSS, you need to/255. For example:[0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255], 4 points.

  • The most common way to get imagedata is throughcreateImageData. Note that imagedata cannot be obtained through image, and imagedata can only be obtained and created through createimagedata.

ctx.rect(10, 10, 100, 100);

let imagedata = ctx.createImageData(100, 100);


It is used to manually create an empty image content. The default pixels are transparent black. The basic format is:

ImageData ctx.createImageData(width, height);
ImageData ctx.createImageData(imagedata);
  • Width / height: used to set the size of the current imgobj.

  • Imagedata: get a known size of imgobj. Note that this is not a copy, just the width / height of copy imagedata.

At present, its purpose is unknown~


The API is often used as image analysis, because it can directly obtain the content of pixels on canvas, and then perform related operations. The basic format is as follows:

ctx.getImageData(x, y, width, height);
  • x. Y is used to specify the starting point of the intercepted pixel

  • Width / height is used to specify the width / height of the intercepted pixel

For example:

let new_one = ctx.getImageData(0,0,2,2);

The most important use of this attribute is to use it as a color picker. Pass in the coordinates in canvas to get the color value of the specified position.

let new_one = ctx.getImageData(0,0,1,1);
let backColor = function(data){
       return `(${data[0]},${data[1]},${data[2]},${data[3]/255})`;


This attribute is often used to fill in pixels. The basic format is as follows:

void ctx.putImageData(imagedata, dx, dy);
void ctx.putImageData(imagedata, dx, dy, startX, startY, width, height);

Let’s talk about the second form

  • DX / Y represents the drawing on canvas

  • Startx / Y represents the actual position relative to the picture

  • Width / height represents the width / height obtained

The specific meaning is as follows:

var imagedata = ctx.getImageData(0,0,100,100); //  Get part of the image information
ctx.putImageData(imagedata, 150, 0, 20, 20, 25, 25);

Basics of canvas

This method is often used for zooming in, previewing, grayscale processing, exporting pictures, etc. For details, please refer to:Image pixel processing. All in all, putimagedata is often used to process the image itself, while DrawImage is often used to create another new canvas.

Generate URI

This should be a quick way to generate image formats. The algorithm converts the pixels in the image into sequence values (that is, text). We can directly put the text into img.src to display the image.
To generate a URI in canvas, you need to use:

canvas.toDataURL(type, encoderOptions);

The API is directly linked to canvas.

  • Type: used to set the export image type. The default is image / PNG. The optional values are: image / jpeg, image / webp (supported by chrome).

  • Encoder options [number]: used to set the compression ratio. Only useful for image / JPEG or webp. The value is usually 0-1. The default value is 0.92.

The basic format of datauri is as follows:

//For example:

The generated datauri is determined by the size of the canvas.

var canvas = document.getElementById("canvas"); // canvas size: 5x5
var dataURL = canvas.toDataURL(); //  The generated size is 5x5

However, no image can generate a datauri. Due to memory constraints, some browsers also limit the length of the datauri. For example, opera is limited to 65000 characters.

Canvas Animation

Using canvas to do animation, we need to understand the curtain cover — erase, draw. The basic APIs are clearrect, request animation


The API is used to clear a screen. The basic format is as follows:

ctx.clearRect(x, y, width, height);

Used to clear the contents of a specified area.

  • x. Y: used to specify the starting position of the area

  • Width, height: Specifies the width and height of the area

In general, it is usually used to clear the entire canvas content.

ctx.clearRect(0, 0, canvas.width, canvas.height);

Using the request animation frame

Mainly rely on the loop call RAF, to achieve smooth animation. Watch a demo

Basics of canvas

var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
  // online
 earth.src = '';
  sun.src = '';
  moon.src = '';

  // local
  earth.src = 'Canvas_earth.png';

function draw(){
  let canvas = document.getElementsByTagName('canvas')[0],
      ctx = canvas.getContext('2d'),
      width = canvas.width,
      height = canvas.height;
    // ctx.globalCompositeOperation = 'destination-over';
    ctx.fillStyle= 'rgba(0,0,0,0.4)';
    ctx.strokeStyle = 'rgba(0,50,50,0.5)';
    // ctx.fill();;
    let date = new Date();

    ctx.rotate ((2*Math.PI)*1*(date.getSeconds()/60 + date.getMilliseconds()/60000) );
    ctx.rotate ((2*Math.PI)*25*(date.getSeconds()/60 + date.getMilliseconds()/60000) );