Introduction to canvas: Summary of Countdown Projects Made with canvas

Keywords: Javascript

Project demonstration

This project is a video on the Mucho Internet. This article summarizes its own learning.

lattice

To draw numbers in canvas, you can use dot matrix.

Below is the lattice layout of 5. 1 represents to draw and 0 represents not to draw. Here the number is 10*7 grid system, colon is 10*4 grid system.

[
  [1, 1, 1, 1, 1, 1, 1],
  [1, 1, 0, 0, 0, 0, 0],
  [1, 1, 0, 0, 0, 0, 0],
  [1, 1, 1, 1, 1, 1, 0],
  [0, 0, 0, 0, 0, 1, 1],
  [0, 0, 0, 0, 0, 1, 1],
  [0, 0, 0, 0, 0, 1, 1],
  [0, 0, 0, 0, 0, 1, 1],
  [1, 1, 0, 0, 0, 1, 1],
  [0, 1, 1, 1, 1, 1, 0]
]

With this grid system, we can draw the numbers.

Digital Drawing

In canvas, how to draw numbers with circles? How to determine the x-axis coordinates and y-axis coordinates of the center of a circle?

ctx.arc(
  x + j * 2 * (radius + 1) + (radius + 1),
  y + i * 2 * (radius + 1) + (radius + 1),
  radius,
  0,
  2 * Math.PI
)

Suppose the radius of a circle is R.

  • The radius of the circle is R, and the box of the bounding box is R+1, so the length of each box is 2*(R+1).
  • Assuming that the vertex of the lattice is (x,y), i represents the row and j represents the column.
  • So the coordinates of position (i,j) are:

    • X-axis coordinates: x + j*2*(R+1)+(R+1)
    • Y axis coordinates: y + i*2*(R+1)+(R+1)

Here x + j*2*(R+1) is drawn to the front of the bounding box, plus (R+1), so that the drawn point is at the center of the circle.

How to locate the second number

How to determine the starting position of the second number?

Margin Left plus the position of the first number. Our digital lattice is seven columns, and the space occupied by one number is 14*(R+1). In order to make the distance between two digits free, we use 15.

Note that the third position is a colon, and we use a 10 * 4 lattice system for colons, so when drawing the fourth number, add 9 instead of 15.

renderDigit(marginLeft, marginTop, parseInt(hour / 10), ctx);
renderDigit(marginLeft + 15 * (radius + 1), marginTop, parseInt(hour % 10), ctx);
renderDigit(marginLeft + 30 * (radius + 1), marginTop, 10, ctx);
renderDigit(marginLeft + 39 * (radius + 1), marginTop, parseInt(minutes / 10), ctx);
renderDigit(marginLeft + 54 * (radius + 1), marginTop, parseInt(minutes % 10), ctx);
renderDigit(marginLeft + 69 * (radius + 1), marginTop, 10, ctx);
renderDigit(marginLeft + 78 * (radius + 1), marginTop, parseInt(seconds / 10), ctx);
renderDigit(marginLeft + 93 * (radius + 1), marginTop, parseInt(seconds % 10), ctx);

Update figures

How to display the effect of time moving on the screen?

  1. Display the countdown on the screen to get the next time next next Show Time Seconds
  2. Compare the current time with the next time (just compare seconds)
  3. If nextSeconds is not curSeconds, it means that time has changed and the current time needs to be updated.
let nextShowTimeSeconds = getCurrentShowTimeSeconds();

  let nextHour = parseInt(nextShowTimeSeconds / 3600);
  let nextMinutes = parseInt((nextShowTimeSeconds - nextHour * 3600) / 60);
  let nextSeconds = nextShowTimeSeconds % 60;

  let curHour = parseInt(curShowTimeSeconds / 3600);
  let curMinutes = parseInt((curShowTimeSeconds - curHour * 3600) / 60);
  let curSeconds = curShowTimeSeconds % 60;

  if (nextSeconds !== curSeconds) {
    curShowTimeSeconds = nextShowTimeSeconds;
  }

Drawing Colorful Balls

Time has moved. When time changes, how can we make a colorful ball appear in the position of time?

When the time changes, let the colorful ball appear on the page.

Here we need to judge every time, call the addBall function when the time changes.

if (parseInt(curHour / 10) !== parseInt(nextHour / 10)) {
  addBall(marginLeft, marginTop, parseInt(curHour / 10));
}
if (parseInt(curHour % 10) !== parseInt(nextHour % 10)) {
  addBall(marginLeft + 15 * (radius + 1), marginTop, parseInt(curHour % 10));
}
if (parseInt(curMinutes / 10) !== parseInt(nextMinutes / 10)) {
  addBall(marginLeft + 39 * (radius + 1), marginTop, parseInt(curMinutes / 10));
}
if (parseInt(curMinutes % 10) !== parseInt(nextMinutes % 10)) {
  addBall(marginLeft + 54 * (radius + 1), marginTop,parseInt(curMinutes % 10));
}
if (parseInt(curSeconds / 10) !== parseInt(nextSeconds / 10)) {
  addBall(marginLeft + 78 * (radius + 1), marginTop, parseInt(curSeconds / 10));
}
if (parseInt(curSeconds % 10) !== parseInt(nextSeconds % 10)) {
  addBall(marginLeft + 93 * (radius + 1), marginTop, parseInt(curSeconds % 10));
}

addBall

The addBall function renders a sphere at a specified position.

The addBall function takes three parameters, the x coordinate of the sphere, the y coordinate and the number.

Traversing through all the numbers here, if the ball is 1, it needs to be drawn at that location and added to the balls.

function addBall(x, y, num) {
  digit[num].forEach((element, i) => {
    element.forEach((item, j) => {
      let aBall = {};
      if (item === 1) {
        aBall = {
          x: x + j * 2 * (radius + 1) + (radius + 1),
          y: y + i * 2 * (radius + 1) + (radius + 1),
          g: 1.5 + Math.random(), //acceleration
          vx: Math.pow(-1, Math.ceil(Math.random() * 1000)) * 4, //Is the preceding paragraph - 1 or 1?
          vy: -5,
          color: colors[Math.floor(Math.random() * colors.length)]
        };
      }
      balls.push(aBall);
    });
  });
}

aball is a small ball to be drawn on the screen. It receives seven parameters:

  • x: x coordinates
  • y: Y coordinates
  • r: Radius
  • g: Acceleration
  • vx: x-axis velocity
  • vy: y-axis velocity
  • color:

Here we focus on the role of the three attributes of g, vx and vy. What we use here is junior high school physics knowledge - speed and acceleration.

ball = {x:512, y:100, r:20, g:1.5, vx:-4, vy:0, color:'#058'}

Update Ball

After the ball has been drawn, it needs to be landed.

Comparing and traversing the array balls of small balls, let the x and y coordinates of each ball add the velocity on its own axis, and the y axis velocity vy add the acceleration of the ball. So there's a small ball landing effect.

balls.forEach(ball => {
  ball.x += ball.vx;
  ball.y += ball.vy;
  ball.vy += ball.g;
});

Ground Detection

Or in an array traversed by balls.

How do you know if the ball has landed?

If the y-axis coordinates of the sphere are greater than or equal to the height of the screen minus the radius of the sphere, then the sphere has touched the bottom. There needs to be a rebound effect.

When rebounding, there are resistance coefficients affected by air resistance.

Updating the y coordinates of the ball and the velocity of the y axis will give the ball a rebound effect.

if (ball.y >= windowHeight - radius) {
  ball.y = windowHeight - radius;
  ball.vy = -ball.vy * 0.6;
}

After running this program line for a period of time, you will find a special carton. This is because we have been adding balls and not deleting them.

console.log(balls.length)

When updating the balls, printing the length of balls will find that it keeps increasing, no matter how much memory your computer has, it will eventually be occupied, so you have to limit the length of the balls array.

optimization

The optimization technique here is to detect whether the ball is on the screen or not, and delete it if it is not on the screen.

let cnt = 0;
balls.forEach(ball => {
  if (ball.x + radius > 0 && ball.x - radius < windowWidth) {
    balls[cnt++] = ball;
  }
});

How to detect whether the ball is detected on the screen?

Or use the above method to detect landing.

The x coordinates of the sphere + the radius of the sphere > 0 and the X coordinates of the sphere - the radius of the sphere < the radius of the canvas, indicating that the sphere is inside the canvas.

Use cnt to count and place the required balls in front of balls

So the former CNT balls are also in the canvas, just delete the ball after cnt.

while (balls.length > Math.min(300, cnt)) {
  balls.pop();
}

Math.min (300, cnt) means that if cnt > 300, take 300, otherwise take cnt.

Its function is to control the number of effects on the screen.

summary

The greatest benefit of doing this animation is:

  1. Drawing Numbers Using Lattice System
  2. The ball landing is a simple original physical knowledge.
  3. Ball landing detection method

Posted by firedrop on Sun, 08 Sep 2019 08:15:05 -0700