# JS 实现烟花特效

# 快速导航

# 实例效果

Canvas is not supported in your browser.

# 实例代码

点击即可查看代码
<template>
  <div class="wrapper">
      <canvas  id="canvas">Canvas is not supported in your browser.</canvas>
  </div>
</template>
<script>
// 烟花特效
 export default {
   name: "fireWorkEffect",
   data() {
     return {

     }
   },
   mounted() {
      this.drawCanvas();
   },
   methods: {
     drawCanvas() {
       window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } })();
       var canvas = document.getElementById("canvas"),
        ctx = canvas.getContext("2d"),
        cw = window.innerWidth,
        ch = window.innerHeight,
        fireworks = [],
        particles = [],
        hue = 120,
        limiterTotal = 5,
        limiterTick = 0,
        timerTotal = 80,
        timerTick = 0,
        mousedown = false,
        mx, my;
    canvas.width = cw;
    canvas.height = ch;

    function random(min, max) { return Math.random() * (max - min) + min }

    function calculateDistance(p1x, p1y, p2x, p2y) { var xDistance = p1x - p2x,
            yDistance = p1y - p2y; return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)) }

    function Firework(sx, sy, tx, ty) { this.x = sx;
        this.y = sy;
        this.sx = sx;
        this.sy = sy;
        this.tx = tx;
        this.ty = ty;
        this.distanceToTarget = calculateDistance(sx, sy, tx, ty);
        this.distanceTraveled = 0;
        this.coordinates = [];
        this.coordinateCount = 3; while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]) } this.angle = Math.atan2(ty - sy, tx - sx);
        this.speed = 2;
        this.acceleration = 1.05;
        this.brightness = random(50, 70);
        this.targetRadius = 1 } Firework.prototype.update = function(index) { this.coordinates.pop();
        this.coordinates.unshift([this.x, this.y]); if (this.targetRadius < 8) { this.targetRadius += 0.3 } else { this.targetRadius = 1 } this.speed *= this.acceleration; var vx = Math.cos(this.angle) * this.speed,
            vy = Math.sin(this.angle) * this.speed;
        this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy); if (this.distanceTraveled >= this.distanceToTarget) { createParticles(this.tx, this.ty);
            fireworks.splice(index, 1) } else { this.x += vx;
            this.y += vy } };
    Firework.prototype.draw = function() { ctx.beginPath();
        ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
        ctx.lineTo(this.x, this.y);
        ctx.strokeStyle = "hsl(" + hue + ", 100%, " + this.brightness + "%)";
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2);
        ctx.stroke() };

    function Particle(x, y) { this.x = x;
        this.y = y;
        this.coordinates = [];
        this.coordinateCount = 5;
        while (this.coordinateCount--) { this.coordinates.push([this.x, this.y]) } this.angle = random(0, Math.PI * 2);
        this.speed = random(1, 10);
        this.friction = 0.95;
        this.gravity = 1;
        this.hue = random(hue - 20, hue + 20);
        this.brightness = random(50, 80);
        this.alpha = 1;
        this.decay = random(0.015, 0.03) }
        Particle.prototype.update = function(index) { this.coordinates.pop();
        this.coordinates.unshift([this.x, this.y]);
        this.speed *= this.friction;
        this.x += Math.cos(this.angle) * this.speed;
        this.y += Math.sin(this.angle) * this.speed + this.gravity;
        this.alpha -= this.decay; if (this.alpha <= this.decay) { particles.splice(index, 1) } };
    Particle.prototype.draw = function() { ctx.beginPath();
        ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
        ctx.lineTo(this.x, this.y);
        ctx.strokeStyle = "hsla(" + this.hue + ", 100%, " + this.brightness + "%, " + this.alpha + ")";
        ctx.stroke() };

    function createParticles(x, y) { var particleCount = 30; while (particleCount--) { particles.push(new Particle(x, y)) } }

    function loop() { requestAnimFrame(loop);
        hue += 0.5;
        ctx.globalCompositeOperation = "destination-out";
        ctx.fillStyle = "rgba(0, 0, 0, 0.5)";
        ctx.fillRect(0, 0, cw, ch);
        ctx.globalCompositeOperation = "lighter";
        var i = fireworks.length; while (i--) { fireworks[i].draw();
            fireworks[i].update(i) } var i = particles.length; while (i--) { particles[i].draw();
            particles[i].update(i) } if (timerTick >= timerTotal) { if (!mousedown) { fireworks.push(new Firework(cw / 2, ch, random(0, cw), random(0, ch / 2)));
                timerTick = 0 } } else { timerTick++ } if (limiterTick >= limiterTotal) { if (mousedown) { fireworks.push(new Firework(cw / 2, ch, mx, my));
                limiterTick = 0 } } else { limiterTick++ } }
            canvas.addEventListener("mousemove", function(e) { mx = e.pageX - canvas.offsetLeft;
        my = e.pageY - canvas.offsetTop });
    canvas.addEventListener("mousedown", function(e) { e.preventDefault();
        mousedown = true });
    canvas.addEventListener("mouseup", function(e) { e.preventDefault();
        mousedown = false });
    window.onload = loop;
     }
   },



 }


</script>

<style lang="scss" scoped>
 .wrapper {
        background: #000;
        margin: 0;
    }

    canvas {
        cursor: crosshair;
        display: block;
    }
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
白色

关注公众号

一个走心,有温度的号,同千万同行一起交流学习

加作者微信

扫二维码 备注 【加群】

扫码易购

福利推荐