Laws are created and discovered, and memory is the derivation and extraction of laws
Recently, I have been learning front-end visualization and doing some interesting demos. When learning canvas, I remembered that the first task assigned to us by the computer graphics teacher in college was to draw a clock. At that time, we used c# to draw, but now we find it more convenient to draw by using the command method of canvas. I will record and share it here.
- Consider what a clock is made of:
- The dial
- The time scale
- The hour hand
- Minute hand
- The second hand
- So let’s design a class that provides the following methods:
- Create the dial
- Drawing scale
- Draw the hour hand
- Draw a minute hand
- Draw the second hand
- Draw by second
- Class is as follows:
// clock.ts This file requires TSC compilation
class Clock {
/ / dial canvas
canvas = null;
// Draw context
context = null;
// Time scale text
timeText = [ "XII"."I"."II"."III"."IV"."V"."VI"."VII"."VIII"."IX"."X"."XI" ];
// Time scale Angle
timeTheta = Array.from({ length: 12 }, (_, i) = > (i / 12) * 2 * Math.PI);
// Dial width
width = 100;
// Dial height
height = 100;
// constructor
constructor(el) {
this.initClockBoard(el);
this.width = this.canvas.width;
this.height = this.canvas.height;
this.start();
}
// Initialize the dial
initClockBoard(el){}// Initialize the timescale
drawTimeText(){}// Draw the time needle
drawTimeCircle(r = 100, color = "blue", theta = -0.5 * Math.PI){}// Draw the second hand
drawSecondCircle(size = 200, color = 'blue'){}// Draw the minute hand
drawMinuteCircle(size = 180,color = 'yellow'){}// Draw an hour hand
drawHourCircle(size = 150,color = 'red'){}// The timer draws the time to walk
drawTimer(){}/ / starter
start(){}}Copy the code
Thus, we can create a clock by passing the Canvas element directly to initialization:
const clock = new Clock('canvas')
Copy the code
The corresponding HTML is simpler:
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="Width = device - width, initial - scale = 1.0" />
<title>candbox</title>
<style>
canvas {
width: 256px;
height: 256px;
border: 1px solid # 333;
}
</style>
<script src="clock.js"></script>
</head>
<body>
<canvas width="512" height="512"></canvas>
<script src="index.js"></script>
</body>
</html>
Copy the code
Now let’s take a look at how simple each method is. Right
Initialize the dial
The dial only needs to load the canvas:
// Initialize the dial
initClockBoard(el) {
this.canvas = document.querySelector(el);
this.context = this.canvas.getContext("2d");
}
Copy the code
Of course, more strict judgment can be made on the input parameters here, and the canvas obtained more can be standardized, which is omitted here
Initialize the time scale
The time scale is to bisect a disk from 1 to 12. Let’s divide the Angle 2π of the whole circle into 12 parts and draw them in 12 positions the same distance from the dot:
// Initialize the timescale
drawTimeText() {
this.context.save();
this.context.clearRect(0.0.this.width, this.height);
this.context.translate(this.width / 2.this.height / 2);
this.timeText.forEach((text, i) = > {
this.context.save();
this.context.rotate(this.timeTheta[i]);
this.context.font = "20px Arial";
this.context.fillStyle = "black";
this.context.fillText(text, 0, -220);
this.context.restore();
});
this.context.restore();
}
Copy the code
Drawing time needle
Here we simply use the sector as the needle representation, drawing the sector is also relatively simple:
// Draw the time needle
drawTimeCircle(r = 100, color = "blue", theta = -0.5 * Math.PI) {
this.context.save();
this.context.beginPath();
this.context.arc(this.width / 2.this.height / 2, r, -0.5 * Math.PI, theta);
this.context.lineTo(this.width / 2.this.height / 2);
this.context.fillStyle = color;
this.context.fill();
this.context.restore();
}
Copy the code
Draw the second hand hour hand
We only need to draw the hour hand through the previous method of drawing the time hand, and we need to provide the length, color and Angle of each hour hand. The Angle can be converted according to the time ratio. Two points need to be paid attention to:
- When drawing the hour hand, the system is 24 hours, but the dial is 12 hours, so when the time is greater than 12, you need to do the corresponding conversion
- The dial and scale need to be redrawn when the time is carried
Details are as follows:
// Draw the second hand
drawSecondCircle(size = 200, color = 'blue') {
const second = new Date().getSeconds();
const secondTheta = -0.5 * Math.PI + (second / 60) * 2 * Math.PI;
if (second === 0) {
this.context.clearRect(0.0.this.width, this.height);
this.drawTimeText();
}
this.drawTimeCircle(size, color, secondTheta);
}
// Draw the minute hand
drawMinuteCircle(size = 180,color = 'yellow') {
const minute = new Date().getMinutes();
const minuteTheta = -0.5 * Math.PI + (minute / 60) * 2 * Math.PI;
if (minute === 0) {
this.context.clearRect(0.0.this.width, this.height);
this.drawTimeText();
}
this.drawTimeCircle(size, color, minuteTheta);
}
// Draw an hour hand
drawHourCircle(size = 150,color = 'red') {
const hour = new Date().getHours();
const hourTheta =
-0.5 * Math.PI +
(hour / 12 > 1 ? hour / 12 - 1 : hour / 12) * 2 * Math.PI;
if (hour === 0) {
this.context.clearRect(0.0.this.width, this.height);
this.drawTimeText();
}
this.drawTimeCircle(size, color, hourTheta);
}
Copy the code
Draw time walk
RequestAnimationFrame () {return arrow () {return arrow () {return arrow () {return arrow () {return arrow ();
// The timer draws the time to walk
drawTimer() {
this.drawTimeText();
this.drawSecondCircle();
this.drawMinuteCircle();
this.drawHourCircle();
requestAnimationFrame(() = > {
this.drawTimer();
});
}
Copy the code
Start the function
Use the frame function to call the timewalk function
/ / starter
start() {
requestAnimationFrame(() = > {
this.drawTimer();
});
}
Copy the code
A final look at the results:
The attached code