canvas 实现下雨和烟花效果

    技术2022-07-12  70

    下雨效果

    下雨原文参考链接

    // 该段代码实现鼠标移动时重新计算雨滴偏移量 并记录鼠标坐标 window.onmousemove = (e) => { rain.state.offsetX = parseFloat((e.clientX - width/2)/50); rain.state.mousePos = [e.clientX, e.clientY]; } // 绘制溅射雨滴时,加上偏移量 ctx.beginPath(); ctx.arc(e.x, e.y, 3, Math.random() * Math.PI * 2, 1 * Math.PI); ctx.stroke(); e.x = e.x + offsetX * Math.random()*3; e.vy = e.vy + 0.5; // e.vy 是一个负数 此处为了实现先上升后下降效果 e.y = e.y + e.vy; if (e.y > height) { dropList.splice(index, 1); }

    烟花效果

    // 绘制烟花上升时拖尾效果 FireWorks.prototype.drawTail = function(e) { const { ctx } = this; ctx.beginPath(); const gra = ctx.createLinearGradient(e.x, e.y, e.x, e.y + 40); // 线性渐变 gra.addColorStop(0, `rgba(${e.rgb.r}, ${e.rgb.g}, ${e.rgb.b}, 1`); gra.addColorStop(0.25, `rgba(${e.rgb.r}, ${e.rgb.g}, ${e.rgb.b}, 0.75`); gra.addColorStop(0.5, `rgba(${e.rgb.r}, ${e.rgb.g}, ${e.rgb.b}, 0.5`); gra.addColorStop(0.75, `rgba(${e.rgb.r}, ${e.rgb.g}, ${e.rgb.b}, 0.25`); gra.addColorStop(1, `rgba(${e.rgb.r}, ${e.rgb.g}, ${e.rgb.b}, 0`); ctx.fillStyle = gra; ctx.fillRect(e.x - e.radius + 1, e.y, 2 * e.radius - 2, 40); }

    烟花爆炸时会先生成3圈环形爆炸物,根据正弦定理算出每个点的坐标,我这里是按15度来均分 const posx = e.radius * 0.5 * a * Math.sin(15 * i * 2 * Math.PI / 360); // 根据度数计算x坐标 const posy = e.radius * 0.5 * a * Math.cos(15 * i * 2 * Math.PI / 360); // 根据度数计算y坐标

    // 初始化烟花碎屑 FireWorks.prototype.initBloom = function(e) { const { bloomList, getRgb } = this; for(let a=1;a<4;a++) { for (let i = 0; i < 7; i++) { const posx = e.radius * 0.5 * a * Math.sin(15 * i * 2 * Math.PI / 360); // 根据度数计算x坐标 const posy = e.radius * 0.5 * a * Math.cos(15 * i * 2 * Math.PI / 360); // 根据度数计算y坐标 bloomList.push({ x: e.x - posx, y: e.y - posy, speedx: parseInt(Math.random() * 10) - 5, speedy: parseInt(Math.random() * 3) - 6, opacity: 1, rgb: getRgb() }) bloomList.push({ x: e.x - posx, y: e.y + posy, speedx: parseInt(Math.random() * 10) - 5, speedy: parseInt(Math.random() * 3) - 6, opacity: 1, rgb: getRgb() }) bloomList.push({ x: e.x + posx, y: e.y - posy, speedx: parseInt(Math.random() * 10) - 5, speedy: parseInt(Math.random() * 3) - 6, opacity: 1, rgb: getRgb() }) bloomList.push({ x: e.x + posx, y: e.y + posy, speedx: parseInt(Math.random() * 10) - 5, speedy: parseInt(Math.random() * 3) - 6, opacity: 1, rgb: getRgb() }) } } }

    github 代码地址

    Processed: 0.027, SQL: 9