Lilrom
Lilrom

Reputation: 15

Prototype animation in Kinetic JS

I would like to make a "prototype" of animations for a future game. But I'm totally a noob in kineticJS.

I have an object where I make all my functions:

var app = {}

I have a function init to build a layer, a stage and declare that I will use requestAnimationFrame:

init: function(){

    layer = new Kinetic.Layer();

    DrawingTab = [];

    stage = new Kinetic.Stage({
        container: 'canvasDemo',
        width: 800,
        height: 600
    });

    window.requestAnimFrame = (function(){
        return  window.requestAnimationFrame ||
        window.webkitRequestAnimationFrame   ||
        window.mozRequestAnimationFrame      ||
        function(callback){
            window.setTimeout(callback, 1000 / 60);
        };
    })();

}

Secondly, I've got one function to build my rects:

createObject: function(){
    rect = new Kinetic.Rect({
        x: 50,
        y: 50,
        width: 150,
        height: 150,
        fill: 'black',
        name: 'batteur',
        id: 'batteur'
    });

    rect1 = new Kinetic.Rect({
        x: 300,
        y: 50,
        width: 150,
        height: 150,
        fill: 'black',
        name: 'batteur1',
        id: 'batteur1'
    });

    rect2 = new Kinetic.Rect({
        x: 550,
        y: 50,
        width: 150,
        height: 150,
        fill: 'black',
        name: 'batteur2',
        id: 'batteur2'
    });

    layer.add(rect);
    layer.add(rect1);
    layer.add(rect2);

    stage.add(layer);

    DrawingTab.push(rect,rect1,rect2,rect3,rect4,rect5);

}

That's all I did. And then, I want to know how to animate like that:

I hope explanations are clear and something will can help me, because I'm totally lost.

Upvotes: 0

Views: 616

Answers (3)

Eric Rowell
Eric Rowell

Reputation: 5219

You should use Kinetic.Animation for animations because it optimizes redraws. Here's an example

If your game is using sprites, you should be using the Sprite shape. Here's an example of that

Upvotes: 1

Gustavo Carvalho
Gustavo Carvalho

Reputation: 2878

You don't need requestAnimationFrame or Kinetic.Animation to handle this, considering the kind of animation you want. Only use animations if you need to change the animation status every frame.

See this working DEMO.

Using setInterval and setTimeout the application became more performant.

I reduce the time of change of color to 5 seconds and the time to click to 2 seconds, just to quickly visualization of the features.

Here is the code added:

// times (make changes according)
var timeToChange = 5000; // 5 seconds 
var timeToClick = 2000; // 2 seconds

// render all rects
layer.drawScene();

// add a logical rect for each rect in DrawingTab
var LogicalTab = [];
for (var i = 0; i < DrawingTab.length; ++i) {
    LogicalTab.push({
        isPressed: false,
        frame: 0
    });
}

// return a random integer between (min, max)
function random(min, max) {
    return Math.round(Math.random() * (max - min) + min);
};

// define colors
var colors = ["red", "green", "blue"];

// reset state of current rect
function reset(n) {
    var drect = DrawingTab[n];
    var lrect = LogicalTab[n];

    // check if current rect was clicked
    setTimeout(function () {
        if (!lrect.isPressed) {
            drect.setFill("black");

            // redraw scene
            layer.drawScene();
            lrect.frame = 0;
        }

        // turn off click event
        drect.off("click");
    }, timeToClick);
}

// start the animation
var start = setInterval(function () {
    // select a rect randomly
    var rand = random(0, 2);
    var drect = DrawingTab[rand];
    var lrect = LogicalTab[rand];

    // change color
    drect.setFill(colors[lrect.frame]);

    // redraw scene
    layer.drawScene();

    // flag that current rect is not clicked
    lrect.isPressed = false;

    // check for click events
    drect.on("click", function () {
        // flag that current rect is clicked
        lrect.isPressed = true;

        // hold current color
        lrect.frame++;
        lrect.frame = lrect.frame % colors.length;
    });

    // reset current rect (only if it is not clicked)
    reset(rand);

}, timeToChange);

Upvotes: 0

2295
2295

Reputation: 3

I'm a newbye here, but I hope I'm able to help. KineticJS don't need requestAnimationFrame, because it has already something that handles animations. so first of all I think you should have a look to this page

if you want to make the rect's color change every 20 s, you may do something like this:

var anim = new Kinetic.Animation(function(frame) {
                if(frame.time > 20000)
                {
                    frame.time = 0;
                    colors = ['red', 'blue', 'violet'];
                    ora = colors[Math.floor(Math.random()*3)];      
                    DrawingTab[Math.floor(Math.random*6)].setAttrs({fill: ora});
                }
            },layer);

then, for the 5sec stuff, I tried to write something

var currentRect = { value:0, hasClicked : true };
var anim2 = new Kinetic.Animation(function(frame) {
    if(frame.time > 20000)
    {
            frame.time = 0;
            colors = ['red', 'lightblue', 'violet'];
            ora = colors[Math.floor(Math.random()*3)];
            currentRect.hasClicked = false;
            currentRect.value=Math.floor(Math.random()*6);
            DrawingTab[currentRect.value].setAttrs({fill: ora});
    }
    if (!currentRect.hasClicked && frame.time>5000)
    {
        DrawingTab[currentRect.value].setAttrs({fill: 'black'});
        currentRect.hasClicked = true;
    }

    DrawingTab[currentRect.value].on('click',function(){ if (frame.time<=5000) currentRect.hasClicked = true;});
},layer);

    anim2.start();

I've just tried something similiar and it looks like it's working :)

p.s. sorry about my english, I'm only a poor italian student

p.p.s. I'm sure the code can be optimized, but for now I think it can be alright

Upvotes: 0

Related Questions