| 12
 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
 
 | <!DOCTYPE html><html>
 
 <head>
 <title>动画(烟花+长尾)</title>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta name="description" content="图形系统开发实战:基础篇 示例">
 <meta name="author" content="hjq">
 <meta name="keywords" content="canvas,ladder,javascript">
 <script src="/examples/canvas-qa/canvas_1b/js/helper.js"></script>
 </head>
 
 <body style="overflow: hidden; margin:10px;">
 <canvas id="canvas" width="800" height="400" style="border:solid 1px #CCCCCC;"></canvas>
 <h3>点击画布可产生烟花</h3>
 </body>
 <script>
 
 let canvas = document.getElementById('canvas');
 let ctx = canvas.getContext('2d');
 let fireworks = [];
 let debug = false, times = 0;
 
 
 ctx.fillStyle = "rgb(0,0,0)";
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 
 drawGrid('lightgray', 0, 0, ctx);
 
 
 
 
 class Firework {
 constructor(x, y) {
 this.x = x;
 this.y = y;
 
 
 this.sparkCount = 10;
 
 this.sparkSize = 2;
 
 this.sparkRadius = 10;
 
 
 this.gravity = 1;
 
 this.speed = 2;
 
 this.decay = 0.98;
 }
 
 
 draw() {
 for (let i = 0; i < this.sparkCount; i++) {
 let angle = i * 360 / this.sparkCount;
 let cx = this.x + Math.cos(toRadians(angle)) * this.sparkRadius
 let cy = this.y + Math.sin(toRadians(angle)) * this.sparkRadius
 ctx.beginPath();
 ctx.arc(cx, cy, this.sparkSize, Math.PI * 2, false);
 ctx.closePath();
 ctx.fillStyle = "#FF0000";
 ctx.fill();
 }
 }
 
 
 update() {
 
 this.y += this.gravity;
 
 this.sparkRadius = this.sparkRadius + this.speed;
 
 this.speed = this.speed * this.decay;
 
 this.sparkSize = this.sparkSize < 7 ? this.sparkSize + 0.02 : this.sparkSize;
 return this.sparkRadius < 100;
 }
 }
 
 
 function frame() {
 
 if (times % 6 === 0 || debug === false) {
 
 ctx.fillStyle = "rgba(0, 0, 0, 0.05)";
 ctx.fillRect(0, 0, canvas.width, canvas.height);
 drawGrid('lightgray', 0, 0, ctx);
 
 
 for (let i = fireworks.length - 1; i >= 0; i--) {
 fireworks[i].draw();
 if (!fireworks[i].update()) {
 fireworks.splice(i, 1);
 }
 }
 }
 window.requestAnimationFrame(frame);
 }
 window.requestAnimationFrame(frame);
 
 
 canvas.addEventListener('click', function (e) {
 fireworks.push(new Firework(e.offsetX, e.offsetY));
 });
 
 </script>
 
 </html>
 
 |