2016-05-15 235 views
0

我們正在使用fabricjs動畫緩和與雪碧,它有點滯後。我們還檢查其他帆布項目沒有fabricjs,他們也吃了很多cpu。在畫布下解決這個問題有什麼好方法嗎?畫布動畫CPU問題

+0

有很多的方法來提高遊戲的速度。您應該在中型機器上以全幀率60fps獲得數百個精靈。但是你不提供代碼,所以我們不能告訴你問題在哪裏以及如何克服它們。 – Blindman67

+0

不知道要顯示什麼代碼,只需使用Fabricjs的'Sprite'自定義函數和''animate'官方的布料就可以了。通過這種組合,CPU在10個對象後變得瘋狂。 –

+0

如果我在寫遊戲,我會做的最後一件事就是使用第三方接口。要繪製一個沒有第三方東西的精靈'函數drawSprite(img,x,y,cx,cy,sx,sy,rot,alpha){ctx.setTransform(sx,0,0,sy,x,y); ctx.rotate(ROT); ctx.globalAlpha =阿爾法; ctx.drawImage(img,0,0,img.width,img.height,-cx,-cy,img.width,img.height)}'在它的中心繪製一個圖像'cx','cy'在'x '''''縮放'sx','sy',旋轉'rot'和淡出'alpha'。一臺6歲的筆記本電腦可以做到每秒60000次。問問自己,fabric.js提供了什麼,如果沒有它,幾行代碼就無法做到。順便說一句,它不適用於遊戲 – Blindman67

回答

0

聲明:我不是FabricJS大師!

於是隨便拿我的分析... :-)

爲什麼當許多對象參與

正如他的評論@ Blindman67意味着你的動畫可能會滯後,FabricJS的「智能」對象太重,無法大量生成動畫。

  • 智能==事件感知,代碼可控(尼斯!)。
  • 重==資源密集型(不太好看!)。

如果你的動畫是幾乎但並非非常敏感...

您可以嘗試分組的重新渲染動畫週期期間做更少的重繪。

  • 不要爲任何動畫設置onChange回調。
  • 當動畫開始時,創建一個單獨的​​(又名rAF)回調,並且只在這個單獨的rAF循環中重新渲染(使用canvas.renderAll)。
  • 調節rAF回調循環以減少滯後但仍視覺吸引力的速度發射。

注:

默認情況下,英國皇家空軍循環,FabricJS用途將嘗試循環在60fps。在每個動畫對象上分配onChange回調幾乎肯定會導致該動畫循環以每秒60幀的速度重繪。

分組會導致所有重繪都在一個動畫循環中完成,因此可以以低於壓倒性60fps(也許30fps)的速度完成重新渲染。這個較慢的fps可能不會損害動畫效果,但會給CPU + GPU兩次做渲染!

爲了提供幫助,rAF循環帶有一個時間戳參數,您可以使用該參數來限制循環以低於60fps的速度執行代碼。

這裏的起始碼爲您建立在

// animation related vars 
var fps=30; 
var delay=1000/fps; 
var nextTime=0; 
var isAnimating=true; 
requestAnimationFrame(animate); 

// Usage: 
// * call startAnimating() 
// * Set many objects to .animate 
// * Optionally, when all animating objects report "onComplete" 
//  call stopAnimating() 

function startAnimating(){ 
    // set the isAnimating flag to start the animation loop 
    isAnimating=true; 
} 

function stopAnimating(){ 
    isAnimating=false; 
} 

function animate(time){ 
    // if we're not animating anything or if desired delay 
    // hasn't occurred, just request another loop and return 
    if(!isAnimating || time<nextTime){ 
     requestAnimationFrame(animate); 
     return; 
    } 
    // set nextTime to the next elapsed time 
    nextTime=time+delay; 
    // re-render everything 
    canvas.renderAll(); 
    // request another loop 
    requestAnimationFrame(animate); 
}