Search code examples
javascriptanimationkineticjs

Kinetic.js slow on Firefox


I'm having a lot of trouble getting a smooth animation using Kinetic.js in Firefox. It looks great in Chrome and Safari, and even looks more-or-less okay in IE9, but Firefox is jerky. I tried using both the built-in Kinetic.Animate, and requestAnimationFrame, and both ended up looking the same. Any ideas?

<div id="container"></div>

<script>
$(function() {
    var stage = new Kinetic.Stage({
      container: 'container',
      width: 1000,
      height: 1000
    });

    var layer = new Kinetic.Layer();

    var blackRect = new Kinetic.Rect({
      x: 700,
      y: 650,
      width: 300,
      height: 620,
      fill: "black",
      offset: [150, 620]
    });

    var colorRect = new Kinetic.Rect({
      x: 300,
      y: 650,
      width: 300,
      height: 620,
      fill: "blue",
      offset: [150, 620]
    });

    layer.add(blackRect);
    layer.add(colorRect);
    stage.add(layer);

    function oscillate(node, time) {
      var period = 5400;
      var phase = 1200;
      var amplitude = 1.2;
      var shift = amplitude * Math.cos(phase + time * 2 * Math.PI / period);
      node.setPosition(node.getX() + shift, node.getY());
    }

    function rotate(node, time) {
      var period = 5400;
      var amplitude = 0.08;
      node.setRotation((amplitude * Math.sin(time * 2 * Math.PI / period) ));
    }

    function render(time) {

      layer.draw();
    }


    var anim = new Kinetic.Animation(function (frame) {
      oscillate(blackRect, frame.time);
      oscillate(colorRect, frame.time);

      rotate(blackRect, frame.time);
      rotate(colorRect, frame.time);
    }, layer);

    anim.start();
});
</script>

Edit: Here is the above example: http://jsfiddle.net/cantino/yr8Zr/


Solution

  • Yes, FF currently produces less-smooth animations.

    You can get smoother-but-slower animation results by:

    • Using frame.timeDiff to throttle the frames-per-second,
    • And reducing your amplitude.

    If smoother-but-slower breaks your design you can use the custom Kinetic.Shape to get "closer to the metal".

    With Kinetic.Shape, you get a canvas context to draw on instead of relying on the easier (but less performant) Kinetic.Rect.