The Canvas API provides the ability to draw graphics through JavaScript. It is widely used in animation, game graphics, data visualization, photo processing and real-time video processing. This article will briefly introduce canvas. Most of the content of this article comes from THE CANVAS tutorial of MDN. If you want to know more about Canvas, you can go to see it.

I met a canvas

/ / 1 with chestnuts<canvas id="tutorial" width="150" height="150"></canvas>
Copy the code

This is a Canvas tag, which looks no different from ordinary HTML tags. Importantly, we can obtain its rendering context through the Canvas tag. All canvas apis are exposed through this rendering context, and the following apis are also based on this context.

Canvas translates to canvas, so next we will introduce the API of Canvas by comparison with canvas.

var canvas = document.getElementById("tutorial");
var ctx = canvas.getContext("2d");
Copy the code

Drawing graphics

In the Canvas coordinate system, the upper left corner of an element is the coordinate origin and the coordinate axis extends to the lower right. All graphs are drawn relative to the origin. By default, 1 grid unit corresponds to 1 pixel. The rectangular coordinates in the figure above are (x, y). Unlike SVG, Canvas only provides one basic graph: rectangle, but we can draw any graph we want with path.

Draw a rectangle

Canvas provides three rectangle apis that can be retrieved from the rendering context. All apis accept four arguments: x, y, width, height.

function draw() {
  var canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");

    ctx.fillRect(25.25.100.100);
    ctx.clearRect(45.45.60.60);
    ctx.strokeRect(50.50.50.50); }}Copy the code

FillRect and strokeRect “fill” and “stroke” a rectangular area, respectively. Calling them immediately draws to the canvas. ClearRect acts like an eraser to clear specific rectangular areas. The result is shown below:

Draw the path

A path consists of a series of points through which we can draw any graph we want. The steps to draw a path are as follows:

  1. throughbeginPathCreate a path and create a path cache with the current coordinates as the starting point.
  2. Then through the drawing command to draw the path, the drawn line, arc and so on into the cache, so as to combine the graph.
  3. The lastclosePathAn optional line is drawn between the current coordinate and the starting point, and you can fill or stroke the path.

The process is similar to drawing, with strokes, strokes, and fillings using the same mental model of the real world. The highlight is the draw command for Step 2: The lineTo, arc , [bezierCurveTo ()] (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo), and other command to draw a straight line, arc, and respectively Bezier curve path. The moveTo command takes x and y parameters and moves the pen to the specified X and Y coordinates. Let’s say I have a slightly more complicated chestnut, and I draw pac-Man.

Path reuse

In The case of Pac-Man, we repeatedly call roundedRect to generate rounded rectangles. Canvas provides a method for path reuse, which is Path2D. Through Path2D, we can create path objects, call draw commands, and even merge two path objects. Using pac-Man’s rounded rectangle function as an example, the code after Using Path2D:

// A utility function to draw a rectangle with rounded corners.
function roundedRect(ctx, x, y, width, height, radius) {
  const path = new Path2D();
  path.moveTo(x, y + radius);
  path.lineTo(x, y + height - radius);
  path.arcTo(x, y + height, x + radius, y + height, radius);
  path.lineTo(x + width - radius, y + height);
  path.arcTo(x + width, y + height, x + width, y + height - radius, radius);
  path.lineTo(x + width, y + radius);
  path.arcTo(x + width, y, x + width - radius, y, radius);
  path.lineTo(x + radius, y);
  path.arcTo(x, y, x, y + radius, radius);

  ctx.stroke(path);
}
Copy the code

Add style?

Canvas keeps the state of brush and canvas through state machine. We can change the state of brush through API to draw different patterns of graphics. For example, change the style of fill and stroke with fillStyle and strokeStyle, change the size of brush with lineWidth, and so on. CreateLinearGradient, [createPattern(image, Type)] (https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createPattern) to draw gradients and background images, go here.

Text rendering

Read the original article

Coordinate transformation

Read the original article

Add some animation?

The limitation of Canvas animation is that the state (size, color, coordinate, etc.) of the graph cannot be changed after the graph is drawn. Unlike familiar HTML elements, DOM elements can also be animated after rendering, such as displacement and scaling. For the above reasons, animation in canvas requires following steps:

  1. Clear the canvas using methods such as clearRect
  2. Save the initial state of the canvas
  3. Draw the current animation frame, this step you may modify the canvas state
  4. Restore the canvas to its original state.

Here is a clock animation chestnut, we encapsulate the different graphics as objects, draw the graphics only need to call the object’s draw method, this unified programming model.

class Hour {
  constructor(ctx) {
    this.ctx = ctx;
  }
  draw() {
    this.ctx.lineWidth = 14;
    this.ctx.beginPath();
    this.ctx.moveTo(- 20.0);
    this.ctx.lineTo(80.0);
    this.ctx.stroke(); }}Copy the code

We update the state of the canvas with each frame we draw. In order not to contaminate the state of the canvas for the next frame, we need to keep calling save and Restore to save and roll back the state of the canvas.

This chapter briefly introduces the basic knowledge of Canvas, and the next article will cover event processing, collision detection and other contents in Canvas, and use these to achieve some cool effects, please look forward to it.


I am writing a series of data Visualization tutorials and experiences, which you can read in the following ways.