web前端开发个人技术博客
当前位置: 免费资源 > canvas实现烟花爆竹特效

canvas实现烟花爆竹特效

2018-06-19 分类:免费资源 作者:码云 阅读(1133)

这个canvas实现的烟花爆竹特效例子死我在网上收集的,效果很high,关键是我想通过笨栗子来提高自己的canvas,好了不多说了,基本的canvas语法就不和大家说了,我想看到这篇文章的人,基础已经学过了,所以直接上代码,看人家的思路就可以了。

canvas实现烟花爆竹特效

CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
body {

            background: #000;

            margin: 0;

        }

        canvas {

            cursor: crosshair;

            display: block;

        }

HTML代码:

1
<canvas id="canvas"></canvas>

Javascript代码:

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
// 当在canvas上动画时,最好使用requestAnimationFrame而不是setTimeout或setInterval

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,

// 当点击发射烟花时,限制每5个循环一次启动一次

limiterTotal = 5,

limiterTick = 0,

// 自动启动烟花爆竹,每80个循环一次启动一次

timerTotal = 80,

timerTick = 0,

mousedown = false,

// 鼠标x坐标,mx,

// 鼠标y坐标, 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 &lt; 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 &gt;= this.distanceToTarget) {

createParticles(this.tx, this.ty);

// 删除烟花,使用传入更新函数的索引来确定要删除的内容

fireworks.splice(index, 1);

} else {

// 目标未达到,继续旅行

this.x += vx;

this.y += vy;

}

}

// 画烟花

Firework.prototype.draw = function () {

ctx.beginPath();

// 移动到集合中最后一个被跟踪的坐标,然后画一条线到当前的x和y

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;

// 将色调设置为整个色调变量的随机数字+20

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;

// 基于传入的索引,一旦alpha足够低,就移除粒子

if (this.alpha &lt;= this.decay) {

particles.splice(index, 1);

}

}

// 画出粒子

Particle.prototype.draw = function () {

ctx.beginPath();

// 移动到集合中最后一个跟踪的坐标,然后画一条线到当前的x和y

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() {

// 这个函数将在requestAnimationFrame中运行

requestAnimFrame(loop);

//随着时间的推移,增加色彩以获得不同颜色的烟花

hue += 0.5;

// 通常,clearRect()将用于清除画布

// 我们想要创建一个拖尾效果

// 将复合操作设置为destination-out将允许我们以特定的不透明度清除画布,而不是完全擦除画布

ctx.globalCompositeOperation = 'destination-out';

// 减少alpha属性以创建更显着的路径

ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';

ctx.fillRect(0, 0, cw, ch);

// 将复合操作更改回主模式

// 当烟火和微粒相互重叠时,打火机会产生明亮的高光点

ctx.globalCompositeOperation = 'lighter';

var text = "HAPPY NEW YEAR !";

ctx.font = "50px sans-serif";

var textData = ctx.measureText(text);

ctx.fillStyle = "rgba(" + parseInt(random(0, 255)) + "," + parseInt(random(0, 255)) + "," + parseInt(random(0,

255)) + ",0.3)";

ctx.fillText(text, cw / 2 - textData.width / 2, ch / 2);

//循环遍历每个烟花,绘制它,更新它

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 &gt;= timerTotal) {

if (!mousedown) {

// 在屏幕的中下部开始烟火,然后设置随机目标坐标,随机y坐标将设置在屏幕上半部分的范围内

for (var h = 0; h &lt; 50; h++) {

fireworks.push(new Firework(cw / 2, ch / 2, random(0, cw), random(0, ch)));

}

timerTick = 0;

}

} else {

timerTick++;

}

// 限制鼠标关闭时启动烟花的速度

if (limiterTick &gt;= limiterTotal) {

if (mousedown) {

// 在屏幕底部中间启动烟火,然后将当前鼠标坐标设置为目标

fireworks.push(new Firework(cw / 2, ch / 2, mx, my));

limiterTick = 0;

}

} else {

limiterTick++;

}

}

// 鼠标事件绑定

// 更新mousemove上的鼠标坐标

canvas.addEventListener('mousemove', function (e) {

mx = e.pageX - canvas.offsetLeft;

my = e.pageY - canvas.offsetTop;

});

// 切换mousedown状态并防止选择画布

canvas.addEventListener('mousedown', function (e) {

e.preventDefault();

mousedown = true;

});

canvas.addEventListener('mouseup', function (e) {

e.preventDefault();

mousedown = false;

});

// 一旦窗户加载,我们准备好了一些烟花!

window.onload = loop;

结束语

效果很华丽,我只能帮到这里了,接下来就是看你得了,年轻人加油!

「如果觉得我的文章对您有用,请帮助本站成长」

赞(3) 打赏

觉得文章有用就打赏一下文章作者

支付宝
微信
3

觉得文章有用就打赏一下文章作者

支付宝
微信

上一篇:

下一篇:

你可能感兴趣

共有 0 条评论 - canvas实现烟花爆竹特效

博客简介

码云笔记: mybj123.com,一个关注Web前端开发技术的博客,主要记录和总结前端工作中常用的知识及我的生活。
更多博客详情请看关于博客

圈子

关注微信公众号
关注微信公众号

精彩评论

服务热线:
 13888888888

 QQ在线交流