2016-05-15 190 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); 
}