IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    放个烟花迎接龙年春节吧

    南城FE发表于 2024-01-27 16:47:33
    love 0

    不知不觉即将迎来2024龙年春节了。龙的形象在中国传统文化中有着广泛的应用,比如在传统文化中,龙代表着权力、威严、吉祥和神灵的象征,同时也是生命力和繁荣的象征。

    今天的文章将用原生JavaScript和Canvas API实现一个烟花的效果,效果如下所示,在放烟花的过程中将「龙年大吉」的文字逐渐显示出来。

    接下来开始具体的代码实现过程,针对重点实现代码进行解析,详情完整代码请看源码实现。烟花效果通常由多个元素组成,包括烟花、粒子、画布等。以下是对代码中关键部分的详细解析:

    Fireworks 类

    Fireworks 类定义了烟花的行为,包括创建、绘制和更新烟花。其中的 canvasLoop 方法用于循环绘制画布,drawFireworks 方法用于绘制烟花的效果,updateFireworks 方法用于更新烟花的位置和状态。

    // Fireworks 类
    var Fireworks = function () {
      // ... 省略部分代码 ...
      self.canvasLoop = function () {
        // 循环绘制画布
        window.requestAnimationFrame(self.canvasLoop, self.canvas);
        self.ctx.globalCompositeOperation = 'destination-out';
        self.ctx.fillStyle = 'rgba(0,0,0,' + self.clearAlpha / 100 + ')';
        self.ctx.fillRect(0, 0, self.cw, self.ch);
        self.updateFireworks();
        self.updateParticles();
        self.drawFireworks();
        self.drawParticles();
      };
      // ... 省略部分代码 ...
      self.drawFireworks = function () {
        // 绘制烟花效果
      };
      self.updateFireworks = function () {
        // 更新烟花状态
      };
      self.createParticles = function () {
        // 绘制粒子效果
      };
      self.updateParticles = function () {
        // 更新粒子状态
      };
    };

    Particle 类

    Particle 类表示烟花中的粒子,包括粒子的位置、速度、颜色等属性。在代码中,粒子的更新和绘制分别由 update 和 draw 方法实现。

    // Particle 类
    class Particle {
      constructor(pos, target, vel, color, radius) {
        // 粒子属性的初始化
        this.pos = pos;
        this.target = target;
        this.vel = vel;
        this.color = color;
        this.radius = radius;
        this.direction = 0;
      }
      set(type, value) {
        this[type] = value;
      }
      // 更新粒子状态
      update() {
        this.radius = 2;
        this.vel.x = (this.pos.x - this.target.x) / drag;
        this.vel.y = (this.pos.y - this.target.y) / drag;
        this.pos.x -= this.vel.x;
        this.pos.y -= this.vel.y;
      }
      // 绘制粒子
      draw() {
        ctx.beginPath();
        ctx.fillStyle = this.color;
        ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI * 2);
        ctx.fill();
      }
    }

    changeText 函数

    changeText 函数用于在画布上绘制文字,并根据文字生成粒子效果(调用Particle类)。它通过获取画布上的像素数据,根据像素的不透明度生成粒子,并将这些粒子添加到 particles 数组中。

    function changeText(text) {
      var current = 0,
        temp, radius, color;
      ctx.fillStyle = "#fff";
      ctx.font = "160px 宋体";
      ctx.fillText(text, can.width * 0.5 - ctx.measureText(text).width * 0.5, can.height * 0.5 + 60);
      var data = ctx.getImageData(0, 0, can.width, can.height).data;
      for (i = 0; i < data.length; i += 12) {
        if (data[i] !== 0 && (Math.random() * 10) >= 7.8) {
          radius = max_radius - Math.random() * min_radius;
          temp = { x: (i / 4) % can.width, y: ((i / 4) / can.width) };
          color = colors[0];
          var p = new Particle(
            temp, { x: (i / 4) % can.width, y: ((i / 4) / can.width) }, { x: 0, y: 0 },
            color,
            radius);
          particles.push(p);
          ++current;
        }
      }
      particles.splice(current, particles.length - current);
    }

    在程序初始化执行时运行changeText("龙年大吉"),这样即可触发对传入文字逐渐显示的烟花效果。

    draw 函数

    draw 函数用于绘制单个粒子,根据传入的参数绘制指定位置和颜色的圆形粒子。

    function draw(obj) {
      ctx.beginPath();
      ctx.arc(obj.target.x, obj.target.y, obj.radius, 0, 2 * Math.PI);
      ctx.fillStyle = obj.color;
      ctx.fill();
    }

    init 函数

    init 函数是整个烟花效果的初始化函数,它通过循环绘制粒子的方式实现烟花效果。在每一帧中,它会绘制下一个粒子,并根据条件创建新的烟花效果。

    function init() {
      id = window.requestAnimationFrame(init)
      if (t >= particles.length - 1) {
        window.cancelAnimationFrame(id)
      }
      draw(particles[t])
      t++;
      var rand = function (rMi, rMa) { return ~~((Math.random() * (rMa - rMi + 1)) + rMi); }
      if (t % 8 == 0) {
        fworks.currentHue = rand(0, 360);
        fworks.createFireworks(window.innerWidth / 2, window. innerHeight, particles[t].pos.x, particles[t].pos.y);
      }
    }

    以上是对代码中关键部分的解析,通过这些代码,即可实现一个炫丽的烟花效果,部分代码量较大没有完整贴出,有兴趣可以查阅源码了解。

    点击鼠标放烟花

    基于以上代码,监听鼠标事件,用户点击时通过createFireworks创建新的烟花。

    self.canvas.addEventListener('mousedown', function (e) {
      self.mx = e.pageX - self.canvas.offsetLeft;
      self.my = e.pageY - self.canvas.offsetTop;
      self.currentHue = rand(self.hueMin, self.hueMax);
      self.createFireworks(self.cw / 2, self.ch, self.mx, self.my);
    });

    点击效果如下:

    最后

    本文利用原生JavaScript和Canvas API创造出一个很不错烟花视觉效果,并在烟花中逐渐显示出「龙年大吉」的文字,有兴趣可以修改代码传入其他文字的效果。

    关注公众号回复【 20240127 】可获取完整源代码~

    参考

    原效果参考,代码有所删改:www.jq22.com/jquery-info17933


    看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

    专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)



沪ICP备19023445号-2号
友情链接