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:


is an HTML element that can be drawn using a script (usually JavaScript). For example, it can be used to draw diagrams, make picture compositions, or make simple (and not-so-simple) animations

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.