I am participating in the Mid-Autumn Festival Creative Submission contest, please see: Mid-Autumn Festival Creative Submission Contest for details
preface
Hi, I’m a dream chaser. Mid-Autumn Festival is coming, I wish you a happy Mid-Autumn Festival in advance!! In nineteen nineteen, I wrote an article to teach you how to implement a Canvas Smart drawing board. Why do you say this? Yes, canvas will be used to realize the full moon Mid-Autumn Festival and the shooting star night sky. Let’s cut the crap and get started.
Results show
Online preview address
The source address
The concrete effect is like this, in fact, these contents: moon, stars, meteors.
What is canvas and what can it do?
MDN documents:
To put it simply, Canvas is a newly added component of HTML5. It is like a screen on which various charts and animations can be drawn with JavaScript.
Use object-oriented programming to achieve the effect
Writing HTML
The processing logic is placed in a separate JS file: main.js
<! 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>The bright moon in the sky, enjoy a happy night</title>
<style>
* {
margin: 0;
padding: 0;
}
canvas {
position: fixed;
top: 0;
left: 0;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script src="./main.js"></script>
</body>
</html>
Copy the code
Initialize the
let canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
width = window.innerWidth,
height = window.innerHeight,
count = 0,
meteors = []; // Set the following parameters
canvas.width = width;
canvas.height = height;
Copy the code
The moon class
The createRadialGradient method of canvas is mainly used to achieve radial gradient effect.
class Moon {
constructor(context, width, height) {
this.context = context;
this.width = width;
this.height = height;
this.circle_x = width / 2; // Rotate the X coordinate of the center of the orbit
this.circle_y = width; // Rotate the Y coordinate of the center of the orbit
this.circle_r = width; // The radius of the rotation trajectory
this.angle = Math.atan2(Math.sqrt(width * width * 3 / 4), -width / 2); // The Angle of the rotation trajectory
this.startAngle = Math.atan2(Math.sqrt(width * width * 3 / 4), -width / 2 - 400); // Start rotation Angle
this.endAngle = Math.atan2(Math.sqrt(width * width * 3 / 4), width / 2 + 200); // End rotation Angle
this.x = 0; // The x-coordinate of the moon
this.y = 0; // The y-coordinate of the moon
}
draw() {
const { context, x, y, width, height } = this;
// createRadialGradient implements radial gradient
const gradient = context.createRadialGradient(x, y, 50, x, y, 600);
gradient.addColorStop(0.'rgb(255, 255, 255)');
gradient.addColorStop(0.01.'rgb(70, 80, 80)');
gradient.addColorStop(0.2.'rgb(40, 40, 50)');
gradient.addColorStop(0.4.'rgb(20, 20, 30)');
gradient.addColorStop(1.'#080d23');
// Save method: a method to put the current state on the stack and save all the states of the canvas
context.save();
context.fillStyle = gradient; / / fill
context.fillRect(0.0, width, height); // Draw a rectangle filled with content
context.restore(); // Restore the canvas to its most recent saved state
}
// Make the moon move
move() {
const { circle_x, circle_y, circle_r, angle, startAngle, endAngle } = this;
this.angle = angle - 0.0001;
if (this.angle <= endAngle) {
this.angle = startAngle;
}
this.x = circle_x + (circle_r * Math.cos(angle));
this.y = circle_y - (circle_r * Math.sin(angle)) + 50; }}Copy the code
The star class
The getStars method is used to generate a set of stars, and all the stars are stored in the stars of the instance. The blink effect can be achieved by calling the blink function, mainly by randomly changing the radius of each star.
class Stars {
constructor(context, width, height, amount) {
this.context = context;
this.width = width;
this.height = height;
// The star collection is generated by the method
this.stars = this.getStars(amount);
}
// Get the specified number of stars
getStars(amount) {
let stars = [];
while (amount--) {
stars.push({
x: Math.random() * this.width,
y: Math.random() * this.height,
r: Math.random() + 0.5})},return stars;
}
/ / describe
draw() {
const { context } = this;
context.save();
context.fillStyle = 'white';
this.stars.forEach(star= > {
context.beginPath();
context.arc(star.x, star.y, star.r, 0.2 * Math.PI);
context.fill();
})
context.restore();
}
// Twinkle, make the radius of the star increase or decrease randomly, to achieve the effect of twinkle and twinkle
blink() {
this.stars = this.stars.map(star= > {
const sign = Math.random() > 0.5 ? 1 : -1;
star.r += sign * 0.2;
if (star.r < 0) {
star.r = -star.r;
} else if (star.r > 1) {
star.r -= 0.2;
}
returnstar; }}})Copy the code
Meteor class
Flow method, determine whether the current meteor out of bounds, the so-called out of bounds, that is, out of the field of vision, on the destruction of meteor instance, recycling memory.
How do meteors work?
Meteor actually has meteor head and meteor tail, meteor head is a semicircular composition, meteor tail is a triangle composition, and then the overall inclination of 45 degrees, and filling with a radial gradient, to achieve a good meteor effect.
class Meteor {
constructor(context, x, h) {
this.context = context;
this.x = x;
this.y = 0;
this.h = h;
this.vx = -(5 + Math.random() * 5);
this.vy = -this.vx;
this.len = Math.random() * 300 + 100;
}
flow() {
// Determine the meteor is out of bounds
if (this.x < -this.len || this.y > this.h + this.len) {
return false;
}
this.x += this.vx;
this.y += this.vy;
return true;
}
draw() {
const { context } = this;
// Radial gradient, from the meteor head to the center of the circle, the greater the radius, the higher the transparency
let gradient = context.createRadialGradient(this.x, this.y, 0.this.x, this.y, this.len);
const PI = Math.PI;
gradient.addColorStop(0.'rgba(255, 255, 255, 1)');
gradient.addColorStop(1.'rgba(0, 0, 0, 0)');
context.save();
context.fillStyle = gradient;
context.beginPath();
// Meteor head, half circle
context.arc(this.x, this.y, 0.5, PI / 4.5 * PI / 4);
// Draw meteor tail, triangle
context.lineTo(this.x + this.len, this.y - this.len); context.closePath(); context.fill(); context.restore(); }}// Generate a meteor
const meteorGenerator = () = > {
const x = Math.random() * width;
meteors.push(new Meteor(context, x, height));
}
Copy the code
Each frame of animation generates a function
All animation is done through frames. Call the frame method to generate each frame of animation.
// Instantiate the stars and moon
let moon = new Moon(context, width, height),
stars = new Stars(context, width, height, 200);
// Generate a function for each frame
const frame = () = > {
count++;
// Stars blink every 10 frames to save computing resources
count % 10= =0 && stars.blink();
// Every 300 frames, a meteor streaks across the night sky
count % 300= =0 && meteorGenerator();
moon.move();
moon.draw();
stars.draw();
meteors.forEach((meteor, index, arr) = > {
// If the meteor is out of view, destroy the meteor instance and reclaim memory
if (meteor.flow()) {
meteor.draw();
} else {
arr.splice(index, 1);
}
})
requestAnimationFrame(frame);
}
frame();
Copy the code
Summary of properties and methods used by the canvas
- createRadialGradient
- addColorStop
- save
- fillStyle
- fillRect
- restore
- beginPath
- arc
- fill
- lineTo
- closePath
reference
- Draw a moon, night sky and meteor on canvas
- Draw the stars on canvas
- Paint meteor night sky on canvas
- Canvas meteor moon star galaxy
If there are any mistakes in this article, please correct them in the comments section. If this article helped you or you liked it, please like it and follow it.