zoukankan      html  css  js  c++  java
  • 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;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>

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

  • 相关阅读:
    Spring_Bean的配置方式
    Nginx Ingress设置账号密码
    2.2.4 加减运算与溢出
    2.2.5-2 补码乘法
    2.2.3 移位运算
    flask钩子函数
    flask的cookie、session
    循环冗余校验码
    海明校验码
    python中的 __call__()
  • 原文地址:https://www.cnblogs.com/shb190802/p/8544427.html
Copyright © 2011-2022 走看看