canvas焰火特效

shb190802 2018-03-11 原文

canvas焰火特效

之前在抖音上看到了一个很漂亮的焰火效果。这会儿有时间就用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>

 

了解更多特效,请关注我的微信公众号:

发表于 2018-03-11 15:43 木兮 阅读() 评论() 编辑 收藏

 

版权声明:本文为shb190802原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/shb190802/p/8544427.html

canvas焰火特效的更多相关文章

随机推荐

  1. Eclipse上安装websphere

    Eclipse上安装websphere 参考:https://blog.csdn.net/qq_2626423 […]...

  2. Docker镜像和仓库

    Docker镜像和仓库 docker镜像是启动容器的构建基石,是由文件系统叠加而成;最底层是一个引导文件系统, […]...

  3. synchronized实现原理

    Java中每一个对象都可以作为锁,这是synchronized实现同步的基础: 普通同步方法,锁是当前实例对象 […]...

  4. Excel——MATCH函数

    使用 MATCH 函数在范围单元格中搜索特定的项,然后返回该项在此区域中的相对位置。 1.参数说明: MATC […]...

  5. Linux运维跳槽必备的40道面试精华题(转)

    下面是一名资深Linux运维求职数十家公司总结的Linux运维面试精华,助力大家年后跳槽找个高薪好工作。   […]...

  6. 进化树 题解

    测试点时限 1s 测试点内存 128M  分析题目: 第一眼看上我们会想到建树,能否成功建树??? 我们从边入 […]...

  7. C# 8中的范围类型(Range Type)

    C# 8.0中加入了一个新的范围类型(Range Type)。 这里我们首先展示一些代码,并一步一步为代码添加 […]...

  8. 《3D打印与工业制造》—— 读书笔记

    《3D打印与工业制造》—— 读书笔记 原创内容,学习不易,转载请注明出处! 一、读后感—— “WO […]...

展开目录

目录导航