0

I have a problem getting my KineticJS animations to stop().

I have three KineticJS image objects on the same layer, and I have added a KineticJS animation to each of those KineticJS image objects. However only one of the image objects shows any animation. It also won't stop animating in response to anim.stop(), unless I stop() the animations for all three objects (including the ones which are not actually visually animating).

My question is: is it even possible to add multiple independent animations on seprate objects/images/shapes to a single layer and still be able to start() / stop() each animation individually? Or do I need to create an individual layer for each KineticJS image object?

In a nutshell (hacked down version), my code is as follows:

stage = new Kinetic.Stage({container: "container", width: windowWidth, height: windowHeight});

layer = new Kinetic.Layer();

var kinObjArr = [];

for (var i=0; i < 3; i++) {
    kinObjArr[i] = new Kinetic.Image({image: myHTMLImage});

    kinObjArr[i].anim = new Kinetic.Animation({
        func: function(frame) {
            kinObjArr[i].setX(30 * Math.sin(frame.time * 2 * Math.PI / 500) + 100);
        },
        node: layer
    });

    kinObjArr[i].anim.start();

    kinObjArr[i].on('touchstart', function(){
        this.anim.stop();    // <----- Doesn't stop
        layer.draw();
    });

} // for

stage.add(layer);

Basically only the last KineticJS image in the list will be animated and it can only be stopped when all 3 images have been touched/clicked.

2 Answers2

5

classic closure problem. you need to use an anonymous function to induce scope, or break out all of your logic into its own function. Here's an article about Javascript closure:

How do JavaScript closures work?

KineticJS supports an unlimited number of Animations (until of course, you run out of memory)

Community
  • 1
  • 1
Eric Rowell
  • 5,191
  • 23
  • 22
0

Thanks for the response Eric. I read that article and it bent my head out of shape, but I think I got it in the end. I choose your second option and it works like a charm:

(again, this is a hacked version of my actual code, haven't tested this snippet)

stage = new Kinetic.Stage({container: "container", width: windowWidth, height: windowHeight});

layer = new Kinetic.Layer();

var kinObjArr = [];

function myFunc(i) {
    kinObjArr[i] = new Kinetic.Image({image: myHTMLImage});

    kinObjArr[i].anim = new Kinetic.Animation({
        func: function(frame) {
            kinObjArr[i].setX(30 * Math.sin(frame.time * 2 * Math.PI / 500) + 100);
        },
        node: layer
    });

    kinObjArr[i].anim.start();

    kinObjArr[i].on('touchstart', function(){
        this.anim.stop();    // <----- Stops now
        layer.draw();
    });
} // function myFunc


for (var i=0; i < 3; i++) {
    myFunc(i);
} // for

stage.add(layer);