每週一點canvas動畫代碼文件
在上一節《每週一點canvas動畫》——3D物理效果中,咱們介紹了3維環境下的速度與加速度效果。這一節,咱們繼續介紹另外兩個物理效果:重力和屏幕環繞。html
三維繫統中實現重力效果的方式與二維的狀況同樣,設定一個重力值,好比g=0.2
。而後,在動畫循環中將它做用於物體豎直方向的速度上。雖然原理上沒有什麼大的變化,可是多了一個維度實現出來的效果確實至關具備視覺衝擊力的。ok,一圖勝千言,與其在這聽我嘚吧嘚吧嘚,還不如直接上個效果圖。git
在動畫中,咱們爲小球的下落設置了一個邊界——至關於地面,並與反彈的效果結合在一塊兒,當小球觸碰到地面發生反彈。與二維繫統中的效果一模一樣。下面是核心代碼,具體代碼請看gravity.html
:github
。。。 function move(ball){ ball.vy += gravity; //重力加速度 ball.xpos += ball.vx; ball.ypos += ball.vy; ball.zpos += ball.vz; if (ball.ypos > floor) { //觸地反彈 ball.ypos = floor; ball.vy *= bounce; } if(ball.zpos > -fl){ //3維場景設置 var scale = fl/(fl + ball.zpos); ball.scaleX = ball.scaleY = scale; ball.x = vpX + ball.xpos * scale; ball.y = vpY + ball.ypos * scale; ball.visible = true; }else{ ball.visible = false; } } 。。。
屏幕環繞是咱們今天的重頭戲,與二維環境中的概念同樣。所謂屏幕環繞就是從屏幕的這端消失,相應的從屏幕的另外一邊出來。對應到三維的環境中,咱們就多了一個緯度的選擇。下面咱們介紹第一個效果——森林canvas
繪製森林前咱們要作的第一個準備工做是繪製森林的基本組成單元——tree。在這裏我提供了3個樹的類文件。segmentfault
與球類文件的引入和使用方式同樣,下面咱們展現一下三種文件的繪製效果。bash
簡單樹的繪製效果如圖所示,若是你想要讓它的枝條更多,再多加兩條樹枝就能夠了。類文件tree.js
,沒有什麼特別的,只是用到簡單的lineTo
,moveTo
等API。動畫
二叉樹的類文件名爲binaryTree.js
。與簡單樹的原理不同,二叉樹的原理是採用遞歸的方法實現樹枝與樹幹的繪製。繪製效果如圖:this
具體代碼以下:spa
/* gen: 樹枝的節點代數,默認是6個節點*/ /* angle: 每次在節點樹枝的旋轉角度*/ /* branchLength: 樹枝的長度*/ function Tree(color, angle, genNum, branchLength){ this.x = 0; this.y = 0; this.xpos = 0; this.ypos = 0; this.zpos = 0 this.scaleX = 0.85; this.scaleY = 0.85; this.gen = 0; this.alpha = 1; this.color = utils.parseColor(color); this.angle = (angle === undefined) ? 0.3 : angle; this.genNum = (genNum === undefined) ? 6 : genNum; this.branchLength = (branchLength === undefined) ? 40 : branchLength; } Tree.prototype.draw = function(ctx){ ctx.save() ctx.translate(this.x, this.y); this.branch(ctx, 0); //初始角度爲0, 繪製樹幹 ctx.restore(); } Tree.prototype.branch= function(ctx, initAngle){ this.gen++; ctx.save(); ctx.strokeStyle = this.color; ctx.rotate(initAngle); ctx.scale(this.scaleX, this.scaleY); ctx.beginPath(); ctx.moveTo(0, 0); ctx.translate(0, -this.branchLength); ctx.lineTo(0, 0); ctx.stroke(); if(this.gen <= this.genNum){ //判斷當前的節點代數是否大於設置的節點數 this.branch(ctx, this.angle); //畫右邊樹枝 this.branch(ctx, -this.angle); //畫左側樹枝 } ctx.restore(); this.gen--; }
二叉樹的造型已經與咱們現實中的樹木結構有類似之處了。下一步咱們就經過這種繪製二叉樹的方法來實現天然樹。prototype
天然樹的原理與二叉樹的原理徹底同樣,不一樣之處在於對樹枝的分叉設置了更多的隨機性。也就是說,不會像咱們上面看到的同樣,樹枝的分叉那麼有對稱性。而且,在樹枝的末端繪製樹葉。ok,下面展現一下用canvas繪製的藝術品。
怎麼樣,帥氣吧!是否是跟真的樹如出一轍。代碼有點長,我在這就不列出來了,具體代碼請查看binaryTree.js
。若是你想體驗不一樣的繪製效果請查看natureTree.html
。在這個文件中,你能夠對一些主要的參數進行控制來實現不一樣的繪製效果。
無限森林的效果,就是使用屏幕環繞的原理。當物體的z
軸座標超過設定的位置就回到初始位置。下面咱們看看效果圖。爲了讓動畫的效果更流暢,咱們採用第一種簡單樹來作,請各位看官原諒個人渣電腦實在是太老舊了。
若是你的電腦配置不錯,能夠換成其餘兩種樹試試。效果必定更好哦!核心代碼以下:
... function move (tree) { tree.xpos += vx; tree.ypos += vy; tree.zpos += vz; if(tree.ypos < floor){ //讓樹的Y軸座標落在設置好的地面上 tree.ypos = floor; } if (tree.zpos < -fl) { //若是z座標超出了屏幕回到一個老遠的位置 tree.zpos += 10000; } if (tree.zpos > 10000 - fl) { //若是z軸的座標超過了咱們設置的距離, 讓它回到一個近的位置 tree.zpos -= 10000; } //3維環境設置 var scale = fl / (fl + tree.zpos); tree.scaleX = tree.scaleY = scale; tree.x = vpX + tree.xpos * scale; tree.y = vpY + tree.ypos * scale; tree.alpha = scale; } ...
森林的運動經過鍵盤的方向鍵來控制。具體代碼請查看tree-2.html
。
星海使用的仍是咱們的球類文件,不一樣之處在於球體的着色上使用的是canvas
的放射漸變來造成光暈效果。具體代碼請看ball3d-s.js
... var gradient = context.createRadialGradient(0, 0, 0, 0, 0, this.radius ); gradient.addColorStop(0,"rgba(255,255,255,1)"); gradient.addColorStop(0.2,"rgba(0,255,255,1)"); gradient.addColorStop(0.3,"rgba(0,0,100,1)"); gradient.addColorStop(1,"rgba(0,0,0,0.1)"); context.fillStyle = gradient; ...
效果圖以下:
默認狀況下,小球是有一個豎直向上的速度,經過方向鍵來控制做用於球體上的加速度,以此來達到物體運動的效果。代碼基本上沒有變化,在這我就不列舉了。詳細代碼請查看star.html
本節的內容到這就結束了,下一節,咱們介紹3維環境下的旋轉與碰撞。