canvas 实现下雨和烟花效果

下雨效果

下雨原文参考链接

最终的下雨效果

 // 该段代码实现鼠标移动时重新计算雨滴偏移量 并记录鼠标坐标
 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 代码地址

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值