“Live up to the time, the creation of non-stop, this article is participating in 2021 year-end summary essay competition”
2021 is coming to an end and I don't know what I have done in the past year... I feel that I wasted a lot of time, so I plan to use some spare time to write something to record my learning process, so as not to look back and leave nothing.Copy the code
Technology stack
Vue3, Vite, Canvas
Project structures,
How to use Vite to create a VUE3 project
The implementation process
Ideas: 1. Need to draw a simple star shape; It’s going to look something like this
2. Randomly generate n stars of different sizes in the specified area.
3. Stars can move and twinkle.
4. When the star moves out of the region, it disappears and a new one is created.
Create a star folder in the Views directory and create index.vue. Then go to step 2 and draw the star on the canvas (using the canvas ctx.lineto (x, y)) method and the Class Class
<template> <canvas id="canvas"></canvas> </template> <script setup> import { ref, onMounted } from "vue"; import BgImg from ".. /.. /assets/images/bg.jpg"; let canvas = ref(null); let ctx = ref(null); let w = ref(0); let h = ref(0); const num = 10; let stars = []; onMounted(() => { initCanvas(); For (let I = 0; i < num; i++) { let obj = new Star(); stars.push(obj); stars[i].init(); } // Draw stars to canvas for (let I = 0; i < stars.length; i++) { const star = stars[i]; star.draw(); }}); function initCanvas() { canvas.value = document.getElementById("canvas"); ctx.value = canvas.value.getContext("2d"); w.value = document.body.offsetWidth; h.value = document.body.offsetHeight; canvas.value.height = h.value; canvas.value.width = w.value; } // class Star {constructor() {this.x; this.y; this.start; } // the star initialization method initializes the star base data init() {// math.floor () returns the largest integer less than or equal to a given number this.x = 200; this.y = 200; this.start = 50; } // draw star draw() {ctx.value.beginPath(); let startM = this.start / 3; ctx.value.lineTo(this.x + startM, this.y - startM); ctx.value.lineTo(this.x + this.start, this.y); ctx.value.lineTo(this.x + startM, this.y + startM); ctx.value.lineTo(this.x, this.y + this.start); ctx.value.lineTo(this.x - startM, this.y + startM); ctx.value.lineTo(this.x - this.start, this.y); ctx.value.lineTo(this.x - startM, this.y - startM); ctx.value.lineTo(this.x, this.y - this.start); ctx.value.strokeStyle = "#fff"; ctx.value.fillStyle = "#fff"; ctx.value.fill(); ctx.value.closePath(); } } </script> <style lang="scss" scoped> #canvas { background: #000; } </style>Copy the code
The effect
So we need to set the coordinates and the size of each star to dynamic, which is obtained using math.random () and math.floor ().
Modify the init method for Star
Math.floor() {this.x = math.floor (math.random () * w.value); // Math.floor() {this.x = math.floor (math.random () * w.value); this.y = Math.floor(Math.random() * h.value); this.start = Math.floor(Math.random() * 10); }Copy the code
The effect
At this point the simple star is drawn, the next step is to make the star twinkle, here change the start value to achieve the effect of the star twinkle. (use window. RequestAnimationFrame execution animation)
<template> <canvas id="canvas"></canvas> </template> <script setup> import { ref, onMounted } from "vue"; import BgImg from ".. /.. /assets/images/bg.jpg"; let canvas = ref(null); let ctx = ref(null); let w = ref(0); let h = ref(0); const num = 10; let stars = []; // let lastTime = ref(0); let deltaTime = ref(0); let timer = ref(0); onMounted(() => { initCanvas(); For (let I = 0; i < num; i++) { let obj = new Star(); stars.push(obj); stars[i].init(); } lastTime.value = Date.now(); loop(); }); function initCanvas() { canvas.value = document.getElementById("canvas"); ctx.value = canvas.value.getContext("2d"); w.value = document.body.offsetWidth; h.value = document.body.offsetHeight; canvas.value.height = h.value; canvas.value.width = w.value; } function loop() { window.requestAnimationFrame(loop); let nowTime = Date.now(); deltaTime.value = nowTime - lastTime.value; lastTime.value = Date.now(); timer.value += deltaTime.value; if (timer.value > 160) { drawStar(); timer.value = 0; } } function drawStar() { ctx.value.clearRect(0, 0, w.value, h.value); // Draw stars to canvas for (let I = 0; i < stars.length; i++) { const star = stars[i]; star.update(); star.draw(); }} class Star {constructor() {this.x; this.y; this.start; } // the star initialization method initialises the star base data init() {// math.floor () returns the largest integer less than or equal to a given number this.x = math.floor (math.random () * w.value); this.y = Math.floor(Math.random() * h.value); this.start = Math.floor(Math.random() * 10); } update() {this.start += 1; this.start %= 5; } // draw stars draw() {ctx.value.save(); ctx.value.beginPath(); let startM = this.start / 3; ctx.value.lineTo(this.x + startM, this.y - startM); ctx.value.lineTo(this.x + this.start, this.y); ctx.value.lineTo(this.x + startM, this.y + startM); ctx.value.lineTo(this.x, this.y + this.start); ctx.value.lineTo(this.x - startM, this.y + startM); ctx.value.lineTo(this.x - this.start, this.y); ctx.value.lineTo(this.x - startM, this.y - startM); ctx.value.lineTo(this.x, this.y - this.start); ctx.value.strokeStyle = "#fff"; ctx.value.fillStyle = "#fff"; ctx.value.fill(); ctx.value.closePath(); ctx.value.stroke(); ctx.value.restore(); } } </script> <style lang="scss" scoped> #canvas { background: #000; } </style>Copy the code
The effectAt this point, the star can twinkle, but the position is still fixed so we change the star coordinates during the update.
// Update the star constructor() {this.x; this.y; this.xNum; this.yNum; this.start; } // the star initialization method initialises the star base data init() {// math.floor () returns the largest integer less than or equal to a given number this.x = math.floor (math.random () * w.value); this.y = Math.floor(Math.random() * h.value); this.start = Math.floor(Math.random() * 10); This.xnum = math.random () * 3-1.5; This.ynum = math.random () * 3-1.5; } update() {this.x += this.xnum * deltatime. value * 0.3; This. Y += this.yNum * deltatime. value * 0.3; this.start += 1; this.start %= 5; }Copy the code
The effectThe next step is to determine whether the star has moved out of the region and then to create a new star.
Update () {this.x += this.xnum * deltatime.value * 0.3; This. Y += this.yNum * deltatime. value * 0.3; this.start += 1; this.start %= 5; / / when the x or y or x > when < 0 w or y < h determine the stars is beyond the area when the if (this. X < 0 | | this. Y < 0 | | this. X > w.v alue | | this. Y > h.v alue) { this.init(); }}Copy the code
The effectHere, the basic function is realized, the black background is not good, and then take some time to adjust the background….
The code address