Reference:

  • Canvas – Dive Into HTML5
  • Canvas | MDN – Web API interface reference
  • HTML5 Canvas Tutorials for Beginners | Become a Canvas Pro

Use the tag

on the page to create a Canvas canvas, a 2D plane, and render the specified image, such as shape, image, text, pattern, etc.

Create a canvas

The canvas is created using the tag

, which has the following attributes (DOM elements)

  • widthWidth of canvas
  • heightHeight of canvas

You can set the canvas size using CSS or JavaScript

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

let windowWidth = document.documentElement.clientWidth;
let windowHeight = document.documentElement.clientHeight;

// Set canvas size (full screen)
canvas.width = windowWidth;
canvas.height = windowHeight;
Copy the code

Canvas uses coordinate system to locate the image. In a two-dimensional image, the coordinate value of (0,0) in the upper left corner increases to the right (x value) and down (y value) in turn

This DOM element has the method getContext to get the contents of the Canvas and return an object with richer methods that can be thought of as a “brush” and can draw different shapes by calling its different methods and passing different parameters

<body>
    <canvas id="c" width="200" height="200"></canvas>
    <script>
        let c = document.querySelector('#c');   // Get the Canvas element using the id attribute
        let ctx = c.getContext("2d");   // Use the method getContext to get the contents of the canvas, passing the argument 2d to get the canvas flat contents
    </script>
</body>
Copy the code

Save and restore the canvas state

Use CTX’s methods save() and Restore () to save and restore the canvas state, making it easier to switch between styles to paint different shapes.

The canvas states that can be saved include:

  • Current transformation matrix (Rotate, scale, move)
  • strokeStyle
  • fillStyle
  • font
  • globalAlpha
  • lineWidth
  • lineCap
  • lineJoin
  • miterLimit
  • shadowOffsetX
  • shadowOffsetY
  • shadowBlur
  • shadowColor
  • globalCompositeOperation
  • textAlign
  • textBaseline
  • Current clipping area

Erase the canvas clearRect

Use the CTX method clearRect(posX, posY, Width, height) to erase specific areas of the canvas

// Set the parameter to the size of the canvas, erasing the entire canvas
ctx.clearRect(0.0, c.width, c.height);
Copy the code

Basic graphics

rectangular

Use CTX method fillRect() or strokeRect() to draw a solid or hollow rectangle, passing different parameters to customize the appearance of the rectangle fillRect(posX, posY, width, height)

The default color is black, which can be changed with the following properties:

  • attributefillStyleSet the fill color
  • attributestrokeStyleSets the border color property
ctx.fillStyle = "blue";
// Start at (0,0) and draw a 50px x 50px blue rectangle
ctx.fillRect(0.0.50.50);
Copy the code

The path

You can create a Path through CTX in various ways to draw a complex shape

  • Method of usebeginPath()Declare that a new path needs to be created
  • Method of usemoveTo(x, y)lineTo(x, y)Creates a path. The previous method determines the starting point of the path, which is equivalent to moving the “brush” to the specified coordinates. The latter method creates a path based on the current coordinates and the coordinates given by the method
  • methodsfill()stroke()End the path drawing and create a solid or hollow figure
// Draw the outer border of a square
ctx.strokeRect(50.50.100.100);

// Draw the path
ctx.beginPath(); // Declare to start drawing a line segment
ctx.moveTo(75.75); // Set the starting point, equivalent to moving (lifting) the brush
ctx.lineTo(125.75); Draw a line / /
ctx.lineTo(125.125); Draw a line / /
ctx.lineTo(75.75); Draw a line / /
ctx.fill(); // Draw the fill graph according to the path
Copy the code

An arc or circle

Draw the arc using CTX method arc, using radians

ctx.beginPath();   // The path must be declared before drawing to avoid being connected to the previous path
// Draw a circle with radius 30
ctx.arc(300.500.30.0.Math.PI * 2.false);
ctx.strokeStyle = 'green'
ctx.stroke();
Copy the code

color

Use the CTX attribute fillStyle or strokeStyle to set the fill or wireframe color, supporting about 140 color names or RGB hexadecimal codes declared using the CSS specification

The colors set by ⚠️ apply only to shapes created after the command is executed.

The text

Use the CTX method fillText(string, x, y) or strokeText(string, x, y) to draw hollow or solid text based on the position of the lower-left corner of the string.

  • usectxThe properties of thefontSet the font style and font size, using CSS by defaultfontProperty same syntax, default font and size are10px sans-serif
  • usectxThe properties of thetextAlignSets the text alignment. Optional values include
    • startThe default value
    • end
    • left
    • right
    • center
  • usectxThe properties of thefillStylestrokeStyleSet the fill color
  • usectxThe properties of thelineWidthSet border width

image

Draw an image and drawImage

Use CTX’s darwImage() method to draw pictures, other canvases, or videos on a canvas for copying, adding special effects, and so on. You can also increase or decrease the size of the image to draw certain parts of the image.

// Cut the image and position the clipped part on the canvas:
ctx.drawImage(img, sx, sy, swidth, sheight, x, y, width, height);
Copy the code

Passable parameter value

parameter describe
img Image, canvas, or video (object) source
sx Optional. Beginning to shearxCoordinate position.
sy Optional. Beginning to shearyCoordinate position.
swidth Optional. The width of the clipped image.
sheight Optional. The height of the clipped image.
x Placing an image on a canvasxCoordinate position.
y Placing an image on a canvasyCoordinate position.
width Optional. The width of the image to use. (Stretch or zoom out image)
height Optional. The height of the image to use. (Stretch or zoom out image)
// Create a new image element and add it to the canvas
let img = new Image();
img.src = "http://lorempixel.com/300/300";   // Set the image source
// Since image loading is asynchronous, use the onload() method to wait until the image is loaded before executing the callback function
img.onload = function() {
  // draw the image img onto the canvas at (0,0)
  ctx.drawImage(img, 0.0, c.width, c.height);
};
Copy the code

Download the image toDataURL

Output the image on the canvas using the Canvas object C method toDataURL(), which creates a string that represents the image on the canvas and supports output of images in various formats.

// Output the image to saveImage
let savedImage = c.toDataURL();

// Open the image saved by the variable
window.open(savedImage);
Copy the code

ImageData ImageData

A canvas can be used as a pixel image, using the CTX method getImageData to get an image data object from the canvas, or using the CTX method createImageData to initialize an empty image data object. The modified data is set back using the CTX method putImageData.

The image data object contains three attributes of the image

  • The width of thewidth
  • highlyheight
  • datadataStore RGB data and Alpha values for each pixel (range 0-255, where 0 is transparent and 255 is fully visible), generally usedUint8ClampedArrayArray representation, each of the four elements of the array represents one pixel point information, namely RGBA value

Obtain or modify image data using the following methods:

  • CreateImageData (Width, height, imageData)Initialize an empty image data object
  • getImageData(x, y, width, height)Copies the pixel data of the specified rectangle on the canvas, starting at(x,y)And for the widewidthHigh forheight
  • putImageData(imagedata, dx, dy, dirtyX, dirtyY, dirtyWidth, dirtyHeight)Stores data to the background canvas
let imgData = ctx.getImage(0.0, c.width, c.height);

function paintGreen(imagData) {
  let numPix = imgData.data.length / 4;
  // Set the canvas to green every 10 pixels
  for (let i = 0; i < numPix; i++) {
    if(i % 10= = =0) {
      // Set the Green value of the ith pixel to 255 (the background color needs to be white, otherwise the red and blue values need to be edited
      imgData.data[i*4 + 1] = 255;
      // Set the Alpha value of the ith pixel to 255 (opaque)
      imgData.data[i*4 + 3] = 255; }}// Store the modified image data back to the background canvas
  ctx.putImageData(imgData, 0.0);
}

paintGreen(imgData);
Copy the code
// Convert color images to black and white (gray) images
let img = new Image();
img.src = "test.jpg";
img.onload = function() {
    ctx.drawImage(img, 0.0, c.width, c.height);
    imgData = ctx.getImageData(0.0, c.width, c.height);
    gray(imgData); // Call the grayscale function
}

// Grayscale function
function gray(imagData) {
    let numPix = imgData.data.length / 4;

    for (let i = 0; i < numPix; i++) {
        let gray = (imgData.data[i*4] + imgData.data[i*4+1] + imgData.data[i*4+2) /3
        imgData.data[i*4] = gray;
        imgData.data[i*4+1] = gray;
        imgData.data[i*4+2] = gray;
        imgData.data[i*4 + 3] = 255;
    }
    ctx.putImageData(imgData, 0.0);
}
Copy the code

Transform operation

⚠️ Any transformations of the following Settings apply to shapes created after executing this command.

The zoom scale

Use CTX’s scale(x,y) method to multiply the x and y values of the shape created after this command by the given coefficients, i.e., the corresponding magnification

Mobile translate

Use CTX’s method Translate (x,y) to move the shape created by this command x pixels horizontally and y pixels vertically.

Rotate the rotate

The CTX method rotate(angleRadians) rotates an object (usually) by a certain radian around its center

💡 radian = degree * (math.pi /180)

animation

Reference:

  • You need to know about requestAnimationFrame
  • requestAnimationFrame for Smart Animating
  • Animating with requestAnimationFrame
  • Window. The reference | MDN requestAnimationFrame – Web API interface

Use the requestAnimationFrame method, which acts as a timer (similar to setTimeout and setInterval) that allows the browser to loop the screen (render) in frames

The requestAnimationFrame method takes an animation execution function as an argument. This function is executed once in each frame, and can render each frame and determine whether the animation is finished based on the condition. If the animation is not finished, The requestAnimationFrame call continues and the function itself is passed in as an argument (a circular call).

function animationWidth() {
  let div = document.getElementById('box');
  div.style.width = parseInt(div.style.width) + 1 + 'px';

  if(parseInt(div.style.width) < 200) {
    requestAnimationFrame(animationWidth)
  }
}

animationWidth();
Copy the code

💡 put the video on the canvas, through the method requestAnimationFrame can be smoothly “draw frame” when the video is playing, that is, extract its frame image, using the ImageData ImageData processing pixel of various methods, can add special effects for the video.

The 💡 game loop is a series of events that run continuously while using an app or game, and requestAnimationFrame does most of the heavy lifting to ensure that the app is running as fast as possible at 60 frames per second while actively viewing the app.

interaction

Interaction is achieved by listening for various events and modifying various attributes of canvas elements in event handlers.

Handling keyboard input

Handle keyboard input events with the help of the Kibo framework, allowing references to key values rather than their keycode values

let k = new Kibo();
k.down(\['up'.'w'\].function() {
    // Do something cool on the canvas
});

k.up(\['enter'.'q'\].function() {
    // Do other stuff.
});
Copy the code

Handling mouse input

The canvas element

can also receive mouse-related events, and the key is to determine where the user clicks on the canvas.

The properties clientX and clientY of the mouse click event object record the click’s position relative to the browser window globally, and use the properties offsetLeft and offsetTop of each element to get the offset of the canvas element relative to the top left corner of the browser (0,0). Subtract the offsetLeft and offsetTop values from clientX and clientY to get the position of the user click relative to the canvas.

function handleMouseClick(event) {
        x = event.clientX - c.offsetLeft;
        y = event.clientY - c.offsetTop;
        console.log("x, y:" + x + "," + y);
}

c.addEventListener("click", handleMouseClick, false);
Copy the code

Integrated application of

Create a circle that moves through the canvas and changes the fill color after “bumping” the edges.

📁 index. HTML

<! DOCTYPEhtml>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    canvas {
      border: 1px solid orange;
      /* background: orange */
    }
  </style>
</head>

<body>
  <! -- <h1>Canvas</h1> -->
  <canvas></canvas>
  <script src="canvas.js"></script>
</body>

</html>
Copy the code

📁 canvas. Js

// Get the canvas's context, which is equivalent to a brush
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

let windowWidth = document.documentElement.clientWidth;
let windowHeight = document.documentElement.clientHeight;

// execute once the first time the page loads
setCanvas();

// Perform redraw after each window adjustment and optimize with anti-shake
window.onresize = debounce(() = > {
  setCanvas()
}, 300);


/ / animation
let radius = 50;
// Randomly generate the initial coordinates of the center of the circle, taking care not to cross the canvas boundary
let x = Math.random() * (windowWidth - radius * 2) + radius;
let y = Math.random() * (windowHeight - radius * 2) + radius;
// Speed of circular motion
let dx = (Math.random() - 0.5) * 30;
let dy = (Math.random() - 0.5) * 30;

animate();

/ / image stabilization
function debounce(fn, delay) {
  let timer = null;
  return function () {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(fn, delay); }}// Set canvas size (full screen)
function setCanvas() {
  canvas.width = windowWidth;
  canvas.height = windowHeight;
}

// Generate random RGB values
function randomColor() {
  let r = parseInt(Math.random() * 255) + 1;
  let g = parseInt(Math.random() * 255) + 1;
  let b = parseInt(Math.random() * 255) + 1;
  return `${r}.${g}.${b}`
}

/ / animation
function animate() {
  // Clear the canvas before drawing
  ctx.clearRect(0.0, windowWidth, windowHeight);

  if (x + radius > windowWidth || x - radius < 0) {
    dx = -dx;
    // Use randomly generated colors
    ctx.fillStyle = `rgba(${randomColor()}`, 0.5)
  }
  if (y + radius > windowHeight || y - radius < 0) {
    dy = -dy;
    ctx.fillStyle = `rgba(${randomColor()}`, 0.5)
  }

  ctx.beginPath();
  ctx.arc(x, y, radius, 0.Math.PI * 2.false);
  ctx.fill();
  
  // requestAnimationFrame acts as a timer (similar to setTimeout and setInterval) that allows the browser to perform a screen (render) loop in frames
// The requestAnimationFrame method takes an animation execution function as an argument. This function is executed once in each frame, and can render each frame and determine whether it is finished based on the condition. If the animation is not finished, the call continues
  requestAnimationFrame(animate);
  
  // When the shape is about to move away from the canvas, change its motion direction
  x += dx;
  y += dy;
}
Copy the code

The effect