效果圖:

start.gif
??參考效果地址:https://www.jq22.com/code922
??下面對(duì)實(shí)現(xiàn)流星效果部分的說明,可能對(duì)你有幫助

image.png
??如果在繪制時(shí),3個(gè)點(diǎn)默認(rèn)會(huì)形成一個(gè)填充圖形,所以下面用到了3點(diǎn)坐標(biāo)位置進(jìn)行了繪制,在繪制完成之后,進(jìn)行 canvas.createRadialGradient 漸變色的使用實(shí)現(xiàn)流星尾跡的效果

image.png
var wX = x + (Math.cos(range) * liuLength);
var wY = y + (Math.sin(range) * liuLength);
var x1 = x + 20;
var y1 = y;
var x2 = x;
var y2 = y - 20;
//canvas createRadialGradient 漸變
// https://www.w3school.com.cn/tags/canvas_createradialgradient.asp
// addColorStop 0 ~ 1的范圍
var rad = ctx.createRadialGradient(x, y, 0, x, y, liuLength);
rad.addColorStop(0, 'rgba(255,255,255,0.8)');
rad.addColorStop(0.1, 'rgba(255,255,255,0.2)');
rad.addColorStop(1, 'rgba(255,255,255,0)');
ctx.fillStyle = rad;

image.png
代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
margin: 0;
background: #000000;
overflow: hidden;
}
#canvas {
display: block;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
</body>
<script>
let canvas = document.getElementById("canvas")
let ctx = canvas.getContext("2d");
let w = canvas.width = window.innerWidth;
let h = canvas.height = window.innerHeight;
// https://www.w3school.com.cn/jsref/jsref_atan.asp
// atan() 方法可返回?cái)?shù)字的反正切值。
// 因?yàn)榱餍钱嬀€部分坐標(biāo)為 (0,-2) (2,0)
var range = Math.atan(-1);
let starArray = []; //星星數(shù)組
var liuArray = []; //流星數(shù)組
var liuLength = 200; //可控制流星尾跡長短
//獲取一個(gè)隨機(jī)的整數(shù)
function random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
//定義一個(gè)隨機(jī)顏色
function rndCol() {
var r = Math.random() * 1;
return `hsla(0, 0%, 100%, ${r})`;
}
//首先創(chuàng)建星星的位置等屬性,并添加到數(shù)組當(dāng)中
function save_star() {
for (let i = 0; i < 200; i++) {
let star = {
x: random(0, w),
y: random(0, h),
r: random(1, 2),
c: rndCol()
}
starArray.push(star)
}
}
save_star()
//通過根據(jù)不同位置的星星繪制不同樣式的圓,實(shí)現(xiàn)閃爍效果
function draw() {
ctx.clearRect(0, 0, w, h);
//繪制流星部分---------------------------------
//判斷條件越小 符合條件的越多,每次出現(xiàn)的流星個(gè)數(shù)更多
if (Math.random() > 0.98) {
//隨機(jī)生成一個(gè) 400 ~ 窗口寬 的流星坐標(biāo)位置
//每個(gè)流星的y軸坐標(biāo)起始點(diǎn)為 0
var a = Math.random() * (w - 400) + 400;
liuArray.push({
x: a,
cX: a
});
}
//設(shè)置流星的最大限度為 20
while (liuArray.length > 20) {
liuArray.shift()
}
for (let i = 0; i < liuArray.length; i++) {
// 每次偏移 10 ,可控制流星速度
liuArray[i].cX -= 10;
liuX(liuArray[i].cX, liuArray[i].x)
}
//繪制星星部分---------------------------------
for (let i = 0; i < starArray.length; i++) {
starArray[i].r += Math.random() * 2 - 1
//定義最大值和最小值,避免當(dāng)隨機(jī)數(shù)為負(fù)數(shù)時(shí)報(bào)錯(cuò)
starArray[i].r = Math.max(0, starArray[i].r)
starArray[i].r = Math.min(2, starArray[i].r)
let r = starArray[i].r
ctx.beginPath();
ctx.fillStyle = starArray[i].c;
ctx.arc(starArray[i].x, starArray[i].y, r, 0, Math.PI * 2); //繪制圓球
ctx.shadowBlur = 10;
ctx.shadowColor = '#ffffff';
ctx.fill();
}
}
//繪制流星方法
function liuX(x, sX) {
//y坐標(biāo)位置為之前 每次的 -=10 ,因?yàn)閤 sX 開始的時(shí)候是相等的,所以y起始坐標(biāo)為0
var y = sX - x;
var wX = x + (Math.cos(range) * liuLength);
var wY = y + (Math.sin(range) * liuLength);
var x1 = x + 2;
var y1 = y;
var x2 = x;
var y2 = y - 2;
//canvas createRadialGradient 漸變
// https://www.w3school.com.cn/tags/canvas_createradialgradient.asp
// addColorStop 0 ~ 1的范圍
var rad = ctx.createRadialGradient(x, y, 0, x, y, liuLength);
rad.addColorStop(0, 'rgba(255,255,255,0.8)');
rad.addColorStop(0.1, 'rgba(255,255,255,0.2)');
rad.addColorStop(1, 'rgba(255,255,255,0)');
ctx.fillStyle = rad;
ctx.beginPath()
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(wX, wY);
ctx.closePath();
ctx.fill();
}
function animation() {
//每一幀進(jìn)行繪制
window.requestAnimationFrame(animation)
draw()
}
animation()
</script>
</html>