Canvas动画CPU问题

时间:2016-05-15 10:59:37

标签: canvas fabricjs

我们正在使用带有Sprite的fabricjs动画缓和,它有点滞后。我们还检查没有fabricjs的其他canvas项目,他们也吃了很多cpu。在画布下有解决这个问题的好方法吗?

2 个答案:

答案 0 :(得分:0)

免责声明:我不是FabricJS大师!

所以轻轻地进行我的分析......: - )

为什么在涉及多个对象时动画可能会滞后

正如@ Blindman67在他的评论中暗示的那样,FabricJS" smart"对象太重而无法以非常大的数量进行动画处理。

  • 智能==事件感知,代码可控(很好!)。
  • 重= =资源密集型(不太好!)。

如果您的动画几乎没有响应......

您可以尝试将重新渲染分组,以便在动画周期中进行更少的重绘

  • 不要为任何动画设置onChange回调。
  • 当动画开始时,创建一个单独的requestAnimationFrame(又名rAF)回调,并且只在这个单独的rAF循环中重新渲染(使用canvas.renderAll)。
  • 限制rAF回调循环以一种减少滞后但仍具有视觉吸引力的速度射击。

备注:

默认情况下,FabricJS使用的rAF循环将尝试以60fps循环。在每个动画对象上分配onChange回调几乎肯定会导致动画循环以每秒60帧的速度重绘。

分组导致所有重绘都在一个动画循环中完成,这样重新渲染就可以在低于60fps的压力下完成 - 也许是30fps。这种较慢的fps可能不会影响动画效果,但会给CPU + GPU两倍的时间进行渲染!

为了提供帮助,rAF循环带有一个timestamp参数,您可以使用该参数来限制循环以低于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);
}

答案 1 :(得分:0)

该解决方案对我来说不太好。 我提出一个找到的解决方案。 诀窍是将画布转换为svg,然后再对其应用动画。现在,没有风扇噪音!!

渲染画布后

    canvas.loadFromJSON(state, 
     canvas.renderAll.bind(canvas), 
    function (o, object) {

   })

您可以将其转换为SVG字符串

 var svg = canvas.toSVG();

现在,请确保还有更好的方法,例如:

svg = svg.replace('<text', '<text id="im"');
svg = svg.replace('<image style', '<image class="ima" style').replace('<image style', '<image class="ima" style');
$('body').html(svg);
$('#im').css(
    {
        'animation-duration': dur+'s',
        'transform-origin': '50% 50%',
        'animation-name': 'lefter'
    }
);
$('.ima').css(
    {
        'animation-duration': dur+'s',
        'transform-origin': '50% 50%',
        'animation-name': 'righter'
    }
);

别忘了添加动画CSS:

svg {
        position: absolute;
        width: 100%;
        height: 100%;
        top: 0px;
        left: 0px
    }



    @keyframes lefter {
        0% {
            transform: translate(0, 0);
        }

        100% {
            transform: translate(30px, 0);
        }
    }



    @keyframes righter {
        0% {
            transform: translate(0, 0);
        }

        100% {
            transform: scale(1.03);
        }
    }

在我的应用程序中,正在运行axios + polifyll + Fabric