欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript實現(xiàn)煙花綻放動畫效果

 更新時間:2020年08月04日 15:14:00   作者:aTeacher  
這篇文章主要介紹了JavaScript如何實現(xiàn)煙花綻放動畫效果,文中講解非常細致,代碼幫助大家更好的理解和學習,感興趣的朋友可以了解下

      先編寫一個煙花綻放的動畫效果。

      放煙花時,一個煙花可分為兩個階段:(1)煙花上升到空中;(2)煙花炸開成碎片,炸開的碎片慢慢消散。

      為此抽象出兩個對象類:Firework和Particle。其中,F(xiàn)irework用于表示一個煙花對象,Particle用于表示一個煙花炸開后的各碎片。

      Firework對象類定義6個屬性:表示煙花上升軌跡中各點的坐標(x,y)、煙花弧狀軌跡的偏轉(zhuǎn)角度angle、上升階段水平和垂直方向的位移改變量xSpeed和ySpeed、煙花的色彩色相hue。

      坐標屬性值y的初始值取畫布的高度,表示煙花從地面上升到空中,其余各屬性的初始值采用隨機數(shù)確定。具體定義如下:

  function Firework()

  {

   this.x = canvas.width/4*(1+3*Math.random());

   this.y = canvas.height - 15;

   this.angle = Math.random() * Math.PI / 4 - Math.PI / 6;

   this.xSpeed = Math.sin(this.angle) *(6+Math.random()*7);

   this.ySpeed = -Math.cos(this.angle) *(6+Math.random()*7);

   this.hue = Math.floor(Math.random() * 360);

  }

      Firework對象類定義3個方法:繪制煙花上升軌跡的方法draw()、煙花上升時坐標改變方法update()和煙花炸開方法explode()。繪制煙花軌跡時,在各點(x,y)處繪制一個寬度為5、高度為15的填充小矩形表示一個軌跡點。煙花上升時,垂直方向速度ySpeed初始值為負的,每次上升時,ySpeed加上一個正值,表示上升在減速,當ySpeed的值大于0時,煙花上升到頂了(不能再上升),就炸開為70個碎片。具體方法的實現(xiàn)見后面的HTML文件內(nèi)容。

       Particle對象類定義8個屬性:表示碎片散開軌跡中各點的坐標(x,y)、碎片弧狀軌跡的偏轉(zhuǎn)角度angle、散開時水平和垂直方向的位移改變量xSpeed和ySpeed、碎片的色彩色相hue、表示碎片小圓的半徑size、碎片的亮度lightness。

  function Particle(x,y,hue)

  {

   this.x = x;

   this.y = y;

   this.hue = hue;

   this.lightness = 50;

   this.size = 15 + Math.random() * 10;

   this.angle = Math.random() * 2 * Math.PI;

   this.xSpeed = Math.cos(this.angle) *(1+Math.random() * 6);

   this.ySpeed = Math.sin(this.angle) *(1+Math.random() * 6);

  }

       Particle對象類定義2個方法:繪制碎片散開軌跡的方法draw()、碎片散開時坐標改變方法update()。碎片散開時逐漸變小(屬性size值減量),當size值小于1時,從碎片數(shù)組中刪除該碎片,表示碎片已消亡。

       定義兩個數(shù)組var fireworks=[];和var particles=[];分別存儲煙花對象和炸開的碎片對象。

       模擬動畫的函數(shù)loop中,每隔一段時間(用count計數(shù)來實現(xiàn))向fireworks數(shù)組中添加一個煙花對象,煙花對象上升到頂炸開后,從fireworks數(shù)組中刪除該對象元素,然后向particles數(shù)組中添加70個碎片對象。

      遍歷兩個數(shù)組的各對象,分別調(diào)用它們的draw()和update()方法。

編寫的完整HTML文件內(nèi)容如下。

<html> 
<head> 
<title>煙花綻放</title> 
</head>
<body>
<canvas id="myCanvas" width="800" height="600" style="border:3px double #996633;background:black;">
</canvas>
<script type="text/javascript">
  var canvas=document.getElementById('myCanvas');
  ctx= canvas.getContext('2d');
  var fireworks=[];
  var particles=[];
  var counter = 0;

  function Firework()
  {
   this.x = canvas.width/4*(1+3*Math.random());
   this.y = canvas.height - 15;
   this.angle = Math.random() * Math.PI / 4 - Math.PI / 6;
   this.xSpeed = Math.sin(this.angle) *(6+Math.random()*7);
   this.ySpeed = -Math.cos(this.angle) *(6+Math.random()*7);
   this.hue = Math.floor(Math.random() * 360);
  }
  Firework.prototype.draw= function() 
  {
   ctx.save();
   ctx.translate(this.x, this.y);
   ctx.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2);
   ctx.fillStyle =`hsl(${this.hue}, 100%, 50%)`;
   ctx.fillRect(0, 0, 5, 15);
   ctx.restore();
  }
  Firework.prototype.update= function() 
  {
   this.x = this.x + this.xSpeed;
   this.y = this.y + this.ySpeed;
   this.ySpeed += 0.1;
  }
  Firework.prototype.explode= function() 
  {
    for (var i = 0; i < 70; i++) 
    {
     particles.push(new Particle(this.x, this.y, this.hue));
    }
  }

  function Particle(x,y,hue) 
  {
   this.x = x;
   this.y = y;
   this.hue = hue;
   this.lightness = 50;
   this.size = 15 + Math.random() * 10;
   this.angle = Math.random() * 2 * Math.PI;
   this.xSpeed = Math.cos(this.angle) *(1+Math.random() * 6);
   this.ySpeed = Math.sin(this.angle) *(1+Math.random() * 6);
  }
  Particle.prototype.draw= function() 
  {
    ctx.fillStyle = `hsl(${this.hue}, 100%, ${this.lightness}%)`;
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
    ctx.closePath();
    ctx.fill();
  }
  Particle.prototype.update= function(index) 
  {
    this.ySpeed += 0.05;
    this.size = this.size*0.95;
    this.x = this.x + this.xSpeed;
    this.y = this.y + this.ySpeed;
    if (this.size<1) 
    {
      particles.splice(index,1);
    }
  }
  function loop() 
  {
   ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
   ctx.fillRect(0,0,canvas.width,canvas.height);
   counter++;
   if (counter==15) 
   {
     fireworks.push(new Firework());
     counter=0;
   }
   var i=fireworks.length;
   while (i--) 
   {
     fireworks[i].draw();
     fireworks[i].update();
     if (fireworks[i].ySpeed > 0) 
     {
       fireworks[i].explode();
       fireworks.splice(i, 1);
     }
   }
   var i=particles.length;
   while (i--) 
   {   
     particles[i].draw();
     particles[i].update(i);
   }
   requestAnimationFrame(loop);
  }
 loop();
</script>
</body> 
</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器窗口中呈現(xiàn)出如圖所示的煙花綻放動畫效果。

      實現(xiàn)了煙花綻放的效果,我們還可以繼續(xù)讓一定區(qū)域內(nèi)的綻放的煙花碎片拼成“Happy New Year”粒子文本。

      編寫如下的HTML代碼。

<html> 
<head> 
<title>迎新年煙花綻放</title> 
<style>
 body { margin: 0; background: black; }
 canvas { position: absolute; }
</style>
</head>
<body>
<canvas id="myCanvas1"></canvas>
<canvas id="myCanvas2"></canvas>
<canvas id="myCanvas3"></canvas>
<script type="text/javascript">
  function Particle(x, y, hue)
  {
   this.x = x;
   this.y = y;
   this.hue = hue;
   this.lightness = 50;
   this.size = 15 + Math.random() * 10;
   this.angle = Math.random() * 2 * Math.PI;
   this.xSpeed = Math.cos(this.angle) * (1 + Math.random() * 6);
   this.ySpeed = Math.sin(this.angle) * (1 + Math.random() * 6);
   this.target = getTarget();
   this.timer = 0;
  }
  Particle.prototype.draw= function() 
  {
   ctx2.fillStyle =`hsl(${this.hue}, 100%, ${this.lightness}%)`;
   ctx2.beginPath();
   ctx2.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
   ctx2.closePath();
   ctx2.fill();
  }
  Particle.prototype.update= function(idx) 
  {
   if (this.target) 
   {
     var dx = this.target.x - this.x;
     var dy = this.target.y - this.y;
     var dist = Math.sqrt(dx * dx + dy * dy);
     var a = Math.atan2(dy, dx);
     var tx = Math.cos(a) * 5;
     var ty = Math.sin(a) * 5;
     this.size = lerp(this.size, 1.5, 0.05);
     if (dist < 5) 
     {
       this.lightness = lerp(this.lightness, 100, 0.01);
       this.xSpeed = this.ySpeed = 0;
       this.x = lerp(this.x, this.target.x + fidelity / 2, 0.05);
       this.y = lerp(this.y, this.target.y + fidelity / 2, 0.05);
       this.timer += 1;
     }
     else if (dist < 10) 
     {
       this.lightness = lerp(this.lightness, 100, 0.01);
       this.xSpeed = lerp(this.xSpeed, tx, 0.1);
       this.ySpeed = lerp(this.ySpeed, ty, 0.1);
       this.timer += 1;
     } 
     else
     {
       this.xSpeed = lerp(this.xSpeed, tx, 0.02);
       this.ySpeed = lerp(this.ySpeed, ty, 0.02);
     }
   } 
   else
   {
     this.ySpeed += 0.05;
     this.size = this.size*0.95;
     if (this.size<1) 
     {
       particles.splice(idx,1);
     }
   }
   this.x = this.x + this.xSpeed;
   this.y = this.y + this.ySpeed;
  }

  function Firework() 
  {
   this.x = canvas2.width*(1+ 3*Math.random())/4;
   this.y = canvas2.height - 15;
   this.angle = Math.random() * Math.PI / 4 - Math.PI / 6;
   this.xSpeed = Math.sin(this.angle) * (6 + Math.random() * 7);
   this.ySpeed = -Math.cos(this.angle) * (6 + Math.random() * 7);
   this.hue = Math.floor(Math.random() * 360);
  }
  Firework.prototype.draw= function() 
  {
   ctx2.save();
   ctx2.translate(this.x, this.y);
   ctx2.rotate(Math.atan2(this.ySpeed, this.xSpeed) + Math.PI / 2);
   ctx2.fillStyle = `hsl(${this.hue}, 100%, 50%)`;
   ctx2.fillRect(0, 0, 5, 15);
   ctx2.restore();
  }
  Firework.prototype.update= function() 
  {
   this.x = this.x + this.xSpeed;
   this.y = this.y + this.ySpeed;
   this.ySpeed += 0.1;
  }
  Firework.prototype.explode= function() 
  {
   for (var i = 0; i < 70; i++) 
   {
     particles.push(new Particle(this.x, this.y, this.hue));
   }
  }

  function lerp(a, b, t)
  {
    return Math.abs(b - a)> 0.1 ? a + t * (b - a) : b;
  }
  function getTarget() 
  {
    if (targets.length > 0) 
    {
      var idx = Math.floor(Math.random() * targets.length);
      var { x, y } = targets[idx];
      targets.splice(idx, 1);
      x += canvas2.width / 2 - textWidth / 2;
      y += canvas2.height / 2 - fontSize / 2;
      return { x, y };
    }
  }

  var canvas1=document.getElementById('myCanvas1');
  ctx1= canvas1.getContext('2d');
  var canvas2=document.getElementById('myCanvas2');
  ctx2= canvas2.getContext('2d');
  var canvas3=document.getElementById('myCanvas3');
  ctx3= canvas3.getContext('2d');
  var fontSize = 200;
  var fireworks = [];
  var particles = [];
  var targets = [];
  var fidelity = 3;
  var counter = 0;
  canvas2.width = canvas3.width = window.innerWidth;
  canvas2.height = canvas3.height = window.innerHeight;
  ctx1.fillStyle = '#000';
  var text = 'Happy New Year';
  var textWidth = 999999;
  while (textWidth > window.innerWidth) 
  {
   ctx1.font = `900 ${fontSize--}px Arial`;
   textWidth = ctx1.measureText(text).width;
  }
  canvas1.width = textWidth;
  canvas1.height = fontSize * 1.5;
  ctx1.font = `900 ${fontSize}px Arial`;
  ctx1.fillText(text, 0, fontSize);
  var imgData = ctx1.getImageData(0, 0, canvas1.width, canvas1.height);
  for (var i = 0, max = imgData.data.length; i < max; i += 4) 
  {
    var alpha = imgData.data[i + 3];
    var x = Math.floor(i / 4) % imgData.width;
    var y = Math.floor(i / 4 / imgData.width);
    if (alpha && x % fidelity === 0 && y % fidelity === 0) 
    {
      targets.push({ x, y });
    }
  }
  ctx3.fillStyle = '#FFF';
  ctx3.shadowColor = '#FFF';
  ctx3.shadowBlur = 25;

  function loop() 
  {
   ctx2.fillStyle = "rgba(0, 0, 0, .1)";
   ctx2.fillRect(0, 0, canvas2.width, canvas2.height);
   counter += 1;
   if (counter==15) 
   {
     fireworks.push(new Firework());
     counter=0;
   }
   var i=fireworks.length;
   while (i--) 
   {
     fireworks[i].draw();
     fireworks[i].update();
     if (fireworks[i].ySpeed > 0) 
     {
       fireworks[i].explode();
       fireworks.splice(i, 1);
     }
   }
   var i=particles.length;
   while (i--) 
   {   
     particles[i].draw();
     particles[i].update(i);
     if (particles[i].timer >= 100 || particles[i].lightness >= 99) 
     {
       ctx3.fillRect(particles[i].target.x, particles[i].target.y, fidelity + 1, fidelity + 1);
       particles.splice(i, 1);
     }
   }
   requestAnimationFrame(loop);
  }
  loop();
</script>
</body> 
</html>

      在瀏覽器中打開包含這段HTML代碼的html文件,可以看到在瀏覽器窗口中呈現(xiàn)出如圖所示的煙花綻放迎新年動畫效果。圖2中為了控制圖片的大小,刪除了大量的中間幀,因此和實際運行的效果有所不同。

以上就是JavaScript實現(xiàn)煙花綻放動畫效果的詳細內(nèi)容,更多關(guān)于JavaScript動畫效果的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js 事件對象 鼠標滾輪效果演示說明

    js 事件對象 鼠標滾輪效果演示說明

    第三篇,繼續(xù)總結(jié)事件對象 先看看監(jiān)聽鼠標滾輪事件能幫我們做什么
    2010-05-05
  • 你不知道的Git?log還有這種用法

    你不知道的Git?log還有這種用法

    這篇文章主要為大家介紹了你不知道的Git?log竟然還有這種用法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • JavaScript利用多彩線條擺出心形效果的示例代碼

    JavaScript利用多彩線條擺出心形效果的示例代碼

    這篇文章主要為大家詳細介紹了如何利用JavaScript語言實現(xiàn)多彩線條擺出心形效果,文中的實現(xiàn)步驟講解詳細,快跟隨小編一起動手嘗試一下吧
    2022-07-07
  • 淺析js封裝和作用域

    淺析js封裝和作用域

    在編寫web軟件時,遇到一些可以共用js的情況,于是就想著如何封裝js代碼。基本需求很簡單,其實就是根據(jù)不同的情況封裝js代碼
    2013-07-07
  • Javascript刷新頁面的實例

    Javascript刷新頁面的實例

    這篇文章主要介紹了Javascript刷新頁面的實例的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • 微信小程序與h5的相互跳轉(zhuǎn)場景分析

    微信小程序與h5的相互跳轉(zhuǎn)場景分析

    這篇文章主要介紹了微信小程序與h5的相互跳轉(zhuǎn)場景分析,在微信小程序內(nèi)編寫webview文件,通過webview去跳轉(zhuǎn)h5,loadUrl為h5的地址,非嵌套,h5需要跳轉(zhuǎn)打開某個微信小程序,需要的朋友可以參考下
    2023-10-10
  • js 時間函數(shù)應用加、減、比較、格式轉(zhuǎn)換的示例代碼

    js 時間函數(shù)應用加、減、比較、格式轉(zhuǎn)換的示例代碼

    時間函數(shù)應用加、減、比較、格式轉(zhuǎn)換等等,具體實現(xiàn)如下,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • electron如何使用typescript

    electron如何使用typescript

    引入 TypeScript 到 Electron 項目可以幫助你捕捉錯誤并在編寫代碼時提供更好的自動完成和文檔,這篇文章主要介紹了electron使用typescript的步驟,需要的朋友可以參考下
    2024-04-04
  • WEEX環(huán)境搭建與入門詳解

    WEEX環(huán)境搭建與入門詳解

    這篇文章主要介紹了WEEX環(huán)境搭建與入門詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-10-10
  • JS判斷瀏覽器是否安裝flash插件的簡單方法

    JS判斷瀏覽器是否安裝flash插件的簡單方法

    下面小編就為大家?guī)硪黄狫S判斷瀏覽器是否安裝flash插件的簡單方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09

最新評論