Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing Fabric.js animations in sequence using onComplete

What I want is this:

http://jsfiddle.net/gJz6C/3/

But I want each box to pop in in sequence instead of all at once. I know that fabricjs has the onComplete attribute for this. I'm not so great at javascript and the one example I could find, here: http://fabricjs.com/shadows/, was not so transparent to me. I thought I had a clever solution though, to have a function that draws a single box, then calls itself onComplete, and doesn't do anything if it has been called 10 times. Here's the code and a jsfiddle at the end of it:

var canvas = new fabric.Canvas('canvas1')

function drawbox(seq) {
    if (seq<11) {
        var rect=new fabric.Rect({
            left: seq*25+25,
            top: 10,
            fill: 'red',
            width: 0,
            height: 0,
        });

        canvas.add(rect)

        rect.animate('width',20, {
            onChange:canvas.renderAll.bind(canvas),
            duration: 1000,
            easing: fabric.util.ease.easeOutElastic,
        });

        rect.animate('height',20, {
            onChange:canvas.renderAll.bind(canvas),
            duration: 1000,
            easing: fabric.util.ease.easeOutElastic,
            onComplete: drawbox(seq+1)
        });
    }
}

drawbox(1)

http://jsfiddle.net/bszM5/2/

As you can see from the jsfiddle though, this still draws all the boxes at once or, if you put also put an onComplete attribute in the width animation, it basically stalls the whole tab process for a second, then draws them all at once. Am I misunderstanding how onComplete is used?

like image 303
AustinC Avatar asked Apr 28 '26 16:04

AustinC


2 Answers

The problem is that you pass in onComplete not function but its result.

rect.animate('height',20, {
   onChange:canvas.renderAll.bind(canvas),
   duration: 1000,
   easing: fabric.util.ease.easeOutElastic,
   onComplete: function() {
     // Here
     drawbox(seq+1);
   }
});
like image 140
Lyubimov Roman Avatar answered Apr 30 '26 05:04

Lyubimov Roman


If i guess, you want to animate box one at a time, then you should use settimeout function.

          var canvas = new fabric.Canvas('canvas1')

          function drawbox(seq) {
           if (seq<11) {
            var rect=new fabric.Rect({
              left: seq*25+25,
              top: 10,
              fill: 'red',
              width: 0,
              height: 0,
        });

        canvas.add(rect)
        setTimeout(function(){
        rect.animate('width',20, {
            onChange:canvas.renderAll.bind(canvas),
            duration: 1000,
            easing: fabric.util.ease.easeOutElastic,
        });

        rect.animate('height',20, {
            onChange:canvas.renderAll.bind(canvas),
            duration: 1000,
            easing: fabric.util.ease.easeOutElastic,
            onComplete: drawbox(seq+1)
        });
       },1000);     
    }
}

drawbox(1)
like image 26
Sandeep Pal Avatar answered Apr 30 '26 04:04

Sandeep Pal



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!