Canvas 烟花效果
一个非常简陋的没什么含金量的小效果
<html>
<head>
<meta charset="utf-8">
<title>title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#cv {
background: #000;
}
style>
head>
<body>
<canvas id="cv">canvas>
<script>
const cv = document.getElementById('cv');
const ctx = cv.getContext('2d');
const ctxFun = {
cw: window.innerWidth,
ch: window.innerHeight,
initCv() {
cv.width = this.cw;
cv.height = this.ch;
},
clean() {
ctx.clearRect(0, 0, this.cw, this.ch);
},
rn(x, y) {
return Math.round(Math.random() * (y - x) + x);
},
color() {
return `${this.rn(80, 255)},${this.rn(80, 255)},${this.rn(80, 255)}`;
},
line(sx, sy, ex, ey, w, c) {
ctx.beginPath();
ctx.lineWidth = w;
ctx.strokeStyle = c;
ctx.moveTo(sx, sy);
ctx.lineTo(ex, ey);
ctx.stroke();
},
circle(x, y, r, c) {
ctx.beginPath();
ctx.fillStyle = c;
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();
}
};
class Line {
static arr = [];
static bg = ctxFun.color();
constructor(sx, sy, ex, ey) {
this.sx = sx;
this.sy = sy;
this.ex = ex;
this.ey = ey;
this.opa = 1;
}
static draw() {
Line.arr.forEach((item, i) => {
ctxFun.line(item.sx, item.sy, item.ex, item.ey, 5, `rgba(${Line.bg}, ${item.opa})`);
item.opa -= .05;
if(item.opa <= 0) Line.arr.splice(i, 1);
});
}
}
class Boom {
static arr = [];
constructor(x, y, r, bg, deg, sr, v) {
this.x = x + sr * Math.cos(deg);
this.y = y + sr * Math.sin(deg);
this.r = r;
this.v = v;
this.deg = deg;
this.bg = bg;
this.opa = .01;
}
static draw() {
this.arr.forEach((item, i) => {
ctxFun.circle(item.x, item.y, item.r, `rgba(${item.bg},${item.opa})`);
item.r = item.v > 0 ? item.r + .1 : item.r - .08;
item.opa = item.v > 0 ? item.opa + .2 : item.r - .2;
item.x += item.v <= 0 ? 0 : item.v * Math.cos(item.deg);
item.y += item.v <= 0 ? .2 : (item.v * Math.sin(item.deg));
item.v -= item.v > 0 ? .04 : 0;
if(item.opa <= 0) this.arr.splice(i, 1);
});
}
}
const Game = {
initFn() {
ctxFun.initCv();
},
bindEvent() {
window.onresize = () => {
ctxFun.initCv();
};
let op = { x: null, y: null };
document.onmousemove = function(me) {
const np = {
x: me.offsetX,
y: me.offsetY
};
if(op.x) Line.arr.push(new Line(op.x, op.y, np.x, np.y));
op = np;
};
cv.onclick = (e) => {
const boomNum = ctxFun.rn(100, 400);
const bg = ctxFun.color();
for(let i = 0; i < boomNum; i++) {
const x = e.offsetX,
y = e.offsetY,
r = ctxFun.rn(1, 4),
v = Math.random() * 2.4,
deg = Math.random() * Math.PI * 2,
sr = ctxFun.rn(0, 150);
Boom.arr.push(new Boom(x, y, r, bg, deg, sr, v));
}
};
},
bindAnimation() {
setInterval(() => {
ctxFun.clean();
Line.draw();
Boom.draw();
}, 10);
setInterval(() => {
Line.bg = ctxFun.color();
}, 5000);
}
};
Game.initFn();
Game.bindEvent();
Game.bindAnimation();
script>
body>
html>