Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add animation between two objects in Fabric js

I have a very basic application that let's you create shapes and connect them with a line. To do that you would do the following.

Example

1. Click new animation
2. add rectangle
3. add child
4. add circle

You can move the shapes around , drag, and resize. I was wondering if it is possible to add a animation between two objects. So for example a small round circle ball would animate on the line between two objects. I have checked out demos on animation page in fabric js but not sure if it is possible to do from object b.

Here is the FIDDLE.

like image 724
user1010101 Avatar asked Sep 19 '15 16:09

user1010101


1 Answers

I don't know if you can use the built in animation function in fabric because as you say these objects might be moving around themselves. But you can make something like this quite easily manually using a bit of Math:

enter image description here

You could do this by treating it like a wave oscillating between 0 and 1. The correct formula for this function is:

enter image description here

  • When the "angle" is 0, or a multiple of 2π the amplitude is 0, so the ball is at object1's center
  • When the "angle" is a multiple of π, the amplitude is 1 and the ball is at object2's center
  • When the amplitude is 0.5, the ball is in between the two objects

You can just increase the angle based on the time, on whatever period, or duration you want.

var animateBallBetweenObjects = function (obj1, obj2) {

    // Add the "ball"

    var circle = new fabric.Circle({
        radius: 10,
        fill: 'blue',
        left: obj1.getCenterPoint().x,
        top: obj1.getCenterPoint().y,
        originX: 'center',
        originY: 'middle',
        selectable: false
    });

    canvas.add(circle);

    var period = 1000;
    var amplitude = 0;
    var angle = 0;
    var prevTime = Date.now();

    var loop = function () {

        // Calculate the new amplitude

        var now = Date.now();
        var elapsed = now - prevTime;
        prevTime = now;
        angle += Math.PI * (elapsed / (period * 0.5));
        amplitude = 0.5 * (Math.sin(angle - (0.5 * Math.PI)) + 1);

        // Set the new position

        var obj1Center = obj1.getCenterPoint();
        var obj2Center = obj2.getCenterPoint();

        circle.setLeft(obj1Center.x + (amplitude * (obj2Center.x - obj1Center.x)));
        circle.setTop(obj1Center.y + (amplitude * (obj2Center.y - obj1Center.y)));
        canvas.renderAll();

        requestAnimationFrame(loop);
    }

    // Animate as fast as possible

    requestAnimationFrame(loop);
};

FIDDLE with it here.

like image 157
Matt Harrison Avatar answered Sep 19 '22 03:09

Matt Harrison