canvas焰火特效
程序员文章站
2022-05-28 22:07:02
...
之前在抖音上看到了一个很漂亮的焰火效果。这会儿有时间就用canvas实现了一下。
演示地址:http://suohb.com/work/firework4.htm
先看效果:(静态图片看不太出效果,请直接查看演示地址,考验电脑CPU的时候到了)
实现原理:
焰火特效运用到的物理知识就是抛物线运动。
看起来很复杂的焰火实际上就是一条条的抛物线。
从一个中心点向四周方向抛出一个质点。将质点的轨迹画出来,就是焰火效果了。
//每一个质点对象
1 var obj = {
2 x: x,//当前X坐标
3 y: y,//当前Y坐标
4 sx: Math.cos(deg)*curSpeed,//X轴方向速度
5 sy: Math.sin(deg)*curSpeed,//Y轴方向速度
6 len: len level*10*Math.random(),//焰火显示长度(这么多质点连接起来)
7 limit: limit level*10*Math.random(),//质点移动最大步数
8 color: color,//焰火颜色
9 level: level,//焰火等级(因为特效是二级焰火,可以做多级)
10 list:[{x:x,y:y}]//质点轨迹(将这些轨迹连起来就是焰火的其中一条线)
11 };
//向360度方向生成一批质点,形成一个焰火元素
1 function addFire(x,y,color,level){
2 curLevel = level ;
3 var lineLen = 10 level*20 Math.random()*10,
4 deg ,
5 speed = 1 Math.random()*level*.4 ,
6 len = 15 Math.random()*level*6,
7 limit = len 4 Math.random()*level;
8 for(var i = 0 ; i < lineLen ; i ){
9 deg = i*(Math.PI*2/lineLen) Math.random() ;
10 var curSpeed = speed Math.random();
11 var obj = 质点对象
12 list.push(obj);
13 }
14 }
//更新质点位置,并将新位置插入质点轨迹之中
1 function reviewFire(){
2 for(var i = 0 ; i <list.length ; i ){
3 let obj = list[i];
4 obj.x = obj.sx ;
5 obj.y = obj.sy ;
6 obj.sy = G ;//抛物运动中的重力加速度
7 obj.list.push({x:obj.x,y:obj.y});
8 obj.list = obj.list.slice(-obj.len);
9 }
10 }
//画出轨迹即可
1 function drawFire(){
2 cxt.clearRect(0,0,pageWidth,pageHeight);
3 var obj ;
4 for(var i = 0 ; i < list.length ; i ){
5 obj = list[i] ;
6 cxt.beginPath();
7 for(var j = 0 ; j < obj.list.length ; j ){
8 if(i == 0)
9 cxt.moveTo(obj.list[j].x ,obj.list[j].y);
10 else{
11 cxt.lineTo(obj.list[j].x ,obj.list[j].y);
12 }
13 }
14 cxt.strokeStyle = obj.color ;
15 cxt.lineWidth = obj.level ;
16 cxt.stroke();
17 }
18 }
完整代码:
1 <!doctype html>
2 <html>
3 <head>
4 <meta http-equiv="Pragma" content="no-cache" />
5 <meta http-equiv="Cache-Control" content="no-cache" />
6 <meta http-equiv="Expires" content="0" />
7 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
8 <meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
9 <title>焰火特效-长按二维码关注公众号,了解更多特效</title>
10 <style type="text/css">
11 html{
12 height: 100%;
13 }
14 html,body,ul,li,canvas{
15 margin: 0;
16 padding: 0;
17 }
18
19 </style>
20 </head>
21 <body bgcolor="#000000">
22 <canvas id="knife"></canvas>
23 <img src="../images/qr.jpg" style="position:fixed;bottom:0;width:100px;height:100px;right:0;">
24 </body>
25 <script>
26 var canvas = document.getElementById("knife");
27 canvas.style.position = "absolute" ;
28 canvas.style.top = 0 ;
29 var pageWidth = window.innerWidth ;
30 var pageHeight = window.innerHeight ;
31 canvas.width = window.innerWidth ;
32 canvas.height = window.innerHeight ;
33 var cxt = canvas.getContext("2d");
34 var list = [] ;
35 var G = 0.036 ;
36 var colors = ["#8b008b","#ff69b4","#7fff00","#1e90ff","#00bfff","#0FF","#7cfc00","#ffd700","#ffdead","#f00"];
37 var curLevel = 0 ;
38 var curColor = 0 ;
39
40 function addFire(x,y,color,level){
41 curLevel = level ;
42 var lineLen = 10 level*20 Math.random()*10,
43 deg ,
44 speed = 1 Math.random()*level*.4 ,
45 len = 15 Math.random()*level*6,
46 limit = len 4 Math.random()*level;
47 for(var i = 0 ; i < lineLen ; i ){
48 deg = i*(Math.PI*2/lineLen) Math.random() ;
49 var curSpeed = speed Math.random();
50 var obj = {
51 x: x,
52 y: y,
53 sx: Math.cos(deg)*curSpeed,
54 sy: Math.sin(deg)*curSpeed,
55 len: len level*10*Math.random(),
56 limit: limit level*10*Math.random(),
57 color: color,
58 level: level,
59 list:[{x:x,y:y}]
60 };
61 list.push(obj);
62 }
63 }
64 function reviewFire(){
65 for(var i = 0 ; i <list.length ; i ){
66 let obj = list[i];
67 obj.x = obj.sx ;
68 obj.y = obj.sy ;
69 obj.sy = G ;
70 obj.list.push({x:obj.x,y:obj.y});
71 obj.list = obj.list.slice(-obj.len);
72 }
73 }
74 function drawFire(){
75 cxt.clearRect(0,0,pageWidth,pageHeight);
76 var obj ;
77 for(var i = 0 ; i < list.length ; i ){
78 obj = list[i] ;
79 cxt.beginPath();
80 for(var j = 0 ; j < obj.list.length ; j ){
81 if(i == 0)
82 cxt.moveTo(obj.list[j].x ,obj.list[j].y);
83 else{
84 cxt.lineTo(obj.list[j].x ,obj.list[j].y);
85 }
86 }
87 cxt.strokeStyle = obj.color ;
88 cxt.lineWidth = obj.level ;
89 cxt.stroke();
90 }
91 }
92 function step(){
93 if(curLevel == 1 && list.length == 0){
94 addFire(pageWidth/2,100,colors[curColor % colors.length],2);
95 }
96 reviewFire();
97 drawFire();
98 requestAnimationFrame(step)
99 }
100 requestAnimationFrame(step)
101 addFire(pageWidth/2,100,colors[curColor % colors.length],2);
102 </script>
103 </html>
了解更多特效,请关注我的微信公众号:
上一篇: Matlab绘图
下一篇: MATLAB04:基础绘图