首頁  >  文章  >  web前端  >  用HTML5中的Canvas結合公式繪製粒子運動的教學_html5教學技巧

用HTML5中的Canvas結合公式繪製粒子運動的教學_html5教學技巧

WBOY
WBOY原創
2016-05-16 15:46:381813瀏覽

最近想弄一個網頁,把自己學HTML5過程中做的部分DEMO放上去做集合,但是,如果就僅僅做個網頁把所有DEMO一個一個排列又覺得太難看了。就想,既然學了canvas,那就來折騰下瀏覽器,做個小小的開場動畫吧。

開場動畫的效果,想了一會兒,決定用粒子,因為覺得粒子比較好玩。還記得以前我寫的第一篇技術博文,就是講文字圖片粒子化的:文字圖片粒子化 , 那時就僅僅做的是直線運動,順便加了一點3D效果。運動公式很簡單。所以就想這個開場動畫就做的更動感一點吧。

先上DEMO:http://2.axescanvas.sinaapp.com/demoHome/index.html

效果是不是比直線的運動更有動感呢?而且也確實很簡單,別忘了這篇文章的題目,小小滴公式,大大滴樂趣。要做出這樣的效果,用的就只是我們國中。 。或是高中時候的物理知識,加速運動,減速運動的公式囉。所以確實是小小滴公式。樓主很喜歡折騰一些酷炫的東西,雖然可能平常工作上用不上,但是,這樂趣確實很讓人著迷啊。而且,做下這些也可以加強一下程式設計的思考能力哈。

廢話不多說,進入主題啦。就簡單的解釋一下原理吧~~~

粒子運動的核心程式碼就這麼一點:
 

XML/HTML Code複製內容到剪貼簿
  1. 更新:函數(時間){   
  2.             this.x = this.vx* 時間;  
  3.             this.y = this.vy* 時間;  
  4.     
  5.             if(!this.globleDown&&this.y>0){   >
  6. 0){                   var yc =no 🎜>
  7.                 var 
  8. xc =xc =p. 🎜>     
  9.                 
  10. this.jl                         var 
  11. za = >
  12. za
  13.  = >                     var ax
  14.  >
  15.                     
  16. ay                     vx  =
  17.                     
  18. vythisvythisvy
  19.                      this.vx
  20.   vx;                   this.vy = vy;  
  21.     
  22.             }其他 {                    var 重力
  23.                   var vy 🎜>
  24.     
  25.                 if(this.y>
  26. canvas.height){ 🎜>>canvas.height){                       vyvy
  27. vy                }  
  28.     
  29.                 this.vy = vy;  
  30.             }   
  31.         },   
粒子總共有兩種狀態,一種是自由落體,一種就是受到吸力。自由落體就不說了。說吸力前先貼出粒子的性質:
 



JavaScript Code
複製內容到剪貼簿
  1. var Dot = function(x,y,vx,vy,tox,toy,,color){           
  2. this.x=x;            
  3. this.y=y;            
  4. this.vx=vx;            
  5. this.vy=vy;            
  6. this.nextox = tox;            
  7. this.nextoy = toy;            
  8. this.color = color;            
  9. this.visible = true        this
  10. .globleDown = false;         this.setEnd(tox , toy);   
  11.     }   
  12.     
  13. setEnd:
  14. function
  15. (tox , toy){   
  16.                 this
  17. .tox = x;
  18.                 this.toy = 🎜>this
  19. .toy =  y;
  20.                 var yc 🎜>this
  21. .y;   
  22.                 var xc 🎜>this .x;            },   
  23.   

    x,y就是粒子的位置,vx是粒子水平速度,vy是粒子的垂直速度,nexttox之類知不知道都無所謂,只是暫時保存變數的。 tox,和toy就是粒子的目的地位置。

    首先,先給所有粒子一個目的地,這個目的地下面再說。也就是要粒子到達的地方,然後再定義一個變數za作為加速度,具體數值的話,就自己多測試下就會有大概參數的了,我設成20,感覺就差不多了。 za是粒子與目的地之間連線的加速度,所以,我們透過粒子的位置和目的地的位置,透過簡單的三角函數,就可以把粒子的水平加速度和垂直加速度求出來了,就這段
     

    JavaScript Code複製內容到剪貼簿
    1. var ax = za*(xc/this.jl),  
    2.  ay = za*(yc/this.jl),     

    有了水平加速度和垂直加速度後,接下來就更簡單了,直接計算水平速度和垂直速度的增量,從而改變水平速度和垂直速度的值
     

    XML/HTML Code複製內容到剪貼簿
    1. vx = (this.vx ax*time)*0.97,   
    2. vy = (this.vy ay*time)*0.97;  

    之所以要乘於0.97是為了模擬能量損耗,粒子才會減速。 time是每一幀的時間差

    計算出速度後就更新粒子位置就行了。
     

    XML/HTML Code複製內容到剪貼簿
    1. this.x  = this.vx*time;   
    2. this.y  = this.vy*time;  

    因為粒子在飛行過程中,與目的地之間的連線方向是不停改變的,所以每一幀都要重新計算粒子的水平加速度和垂直加速度。

    運動原理就是如此,是否很簡單呢。

    運動原理說完了,再扯一下上面那個動畫的具體實現吧:動畫初始化,在一個離屏canvas上把想要的字或圖片畫出來,然後再透過getImageData這個方法取得離屏canvas的像素。然後用一個循環,把離屏canvas中有繪製的區域找出來,因為imageData裡的data值就是一個rgba數組,所以我們判斷最後一個的值也就是透明度大於128就是有繪製過的區域。然後取得該區域的xy值,為了防止粒子物件過多導致頁面卡頓,所以我們就限制一下粒子的數量,取像素的時候x值和y值每次遞增2,從而減少粒子數量。
     

    XML/HTML Code複製內容到剪貼簿
    1. this.osCanvas = 文件.createElement("canvas"); 🎜         var 
    2. osCtx = 這個             
    3. this.osCanvas.width = 
    4. 1000 = 1000        this.osCanvas.height = 
    5. 150 = 150>;     
    6.         
    7. osCtx.textAlign
    8.  = 
    9.         osCtx.textBaseline = 
    10.         
    11. osCtx.font="70px ="70px =
    12. "70px 
    13. ="70px  微軟雅黑,黑體,黑體。 >         osCtx.fillStyle = 
    14.         osCtx.fillText("歡迎光臨"、this.osCanvas.width/2、this.osCanvas.height/2-40);            osCtx.fillText("到 wAxes'HOME", this.osCanvas.width/2, this.osCanvas.height/2 40);           var 
    15. bigImageData
    16.  = 
    17. osCtx
    18.  = osCtx = 
    19. Atx              = [];   
    20.     
    21.          for(var x=
    22. 0
    23. ;x
    24. bigImageData.width;x =2){                for(var y=0=0
    25. =0=0=0=0
    26. =
    27. bigImageData.height;y =2){   
    28.                 var 
    29. i  = big                 if(bigImageData.data[i 3]
    30. >
    31.                     var                          Math.random()
    32. >
    33.                         -Math.random()*canvas.height*2,     -Math.random()*canvas.height*2,   
    34.                         0,   
    35.                         0,   
    36.                         x (canvas.width/2-this.osvasS.width/2), idth/2),
    37.                         y (canvas.height/2-this.osCanvas.height/2),  y (canvas.height/2-this.osCanvas.height/2),   y (canvas.height/2-this.osCanvas.height/2),   
    38.                          在上gba(" bigImageData. 🎜>
    39.                     );  
    40.                     dot.setEnd(canvas.width/2,canvas.height/2)   
    41.                     dots.push(dot);   
    42.                 }   
    43.             }   
    44.         }   
    45. 透過循環取得到耳機的位置xy值後,把適合給耳機的位置,成為耳機的目的地。 然後動畫開始,就可以做出文字圖片耳機化的效果了。
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn