How to animate a diagonal line with TweenMax/EaselJS

1.2k views Asked by At

I have a constellation which i want to connect with lines. These lines need to be animated from a start point to an end point. I've provided an image to illustrate what i need as an end result:

enter image description here

All of these stars and lines are drawn with HTML5 canvas using easelJS. Provided bellow is my code so far, the "this.paths" variable contains x and y positions.

var graphics = this.shape.graphics;

graphics.beginStroke('#ffffff');
graphics.setStrokeStyle(1);

for(var i = 0; i < this.path.length; i++)
{
    var path = this.path[i];

    graphics.moveTo(path[0].x / 2, path[0].y / 2);
    graphics.lineTo(path[0].x / 2, path[0].y / 2);
    graphics.lineTo(path[1].x / 2, path[1].y / 2);
}

this.shape.alpha = 0.6;

Thanks in advance.

1

There are 1 answers

5
vitr On BEST ANSWER

all that you need is already in this demo
http://www.createjs.com/demos/tweenjs/tween_sparktable
you've got a set of coordinates like (x1,y1) and (x2,y2). Now you need to use the Equation of a Straight Line and draw the lines dot by dot for smooth animation, just play with delays for satisfactory results. Seriously, the demo covers all of this and more, you even can edit it right there! I've played with the code a bit and here is your diagonal line, just paste this code there and run enter image description here

var stage;
var prevPoint, dataProvider, rect = new createjs.Rectangle(20,20,700,360);
var bar, container, currentClip;
var selectedFunction, selectedItem, selectedIndex = 0;
var resetRuninng = false, startTimeout;
var clips = [];
var activeTween;

function init() {
    stage = new createjs.Stage("testCanvas");

    var Ease = createjs.Ease; // shortcut.
    dataProvider = [
        {type: "divider", label: "Ease Equations"},

    ];

    var eases = document.getElementById("eases");
    var cloneElement = document.createElement("a");
    cloneElement.href = "#";

    for (var i = 0, l = dataProvider.length; i < l; i++) {
        var item = dataProvider[i];

        if (item.type == "divider") {
            element = document.createElement("span");
            element.innerHTML = item.label;
            eases.appendChild(element);
            continue;
        }

        var element = cloneElement.cloneNode(true);
        element.id = i;
        element.onclick = selectItem;
        element.innerHTML = item.label;
        eases.appendChild(element);

        if (item.label == "linear") {
            selectedItem = element;
            element.className = "selected";
        }
    }

    createjs.Ticker.setFPS(60);
    createjs.Ticker.addEventListener("tick", tick);

    prevPoint = new createjs.Point(rect.x, rect.y);

    container = stage.addChild(new createjs.Container());
    bar = container.addChild(new createjs.Shape()
                                     .set({alpha:0.7, x:rect.x, y:rect.y}));
    bar.graphics.f("#000").setStrokeStyle(1)

    stage.update();

    startTimeout = setTimeout(run, 1000);
}

function stop() {
    Ticker.off("tick", tick);
}

function selectItem() {
    clearTimeout(startTimeout);
    if (clips.length > 0) { fade(); }

    if (selectedItem != null && selectedItem != this) {
        selectedItem.className = "";
    }

    selectedItem = this;
    selectedIndex = this.id;
    selectedItem.className = "selected";
    selectedFunction = dataProvider[selectedIndex].type;

    resetRuninng = true;
    //createjs.Tween.get(bar, {override: true}).to({x: rect.x}, 500).call(resetComplete);
    return false;
}

function run(easeType) {
    currentClip = stage.addChild(new createjs.Shape());
    clips.push(currentClip);
    prevPoint.setValues(rect.x, rect.y);
    activeTween = createjs.Tween.get(bar, {override: true}).to({x: rect.x+rect.width}, 1500, easeType);
}

function resetComplete() {
    bar.x = rect.x;
    resetRuninng = false;
    currentClip = null;
    prevPoint.setValues(rect.x, rect.y);

    run(selectedFunction);
}

function tick(event) {
    if (!resetRuninng && currentClip != null) {
        var hue = (selectedIndex / dataProvider.length) * 360;
        var g = currentClip.graphics
                .setStrokeStyle(1, "round", "round")
                .beginStroke(createjs.Graphics.getHSL(hue, 50, 50))
                .moveTo(prevPoint.x, prevPoint.y);

        prevPoint.x = bar.x;
        prevPoint.y = rect.x+ activeTween.position/1500 * rect.height;

        g.lineTo(prevPoint.x, prevPoint.y);

        stage.update(event);
    } else if (resetRuninng) {
        stage.update(event);
    }
}

function fade() {
    for (var i = 0; i < clips.length; i++) {
        var clip = clips[i];
        createjs.Tween.get(clip, {override: true})
                .to({alpha: clip.alpha - 0.4}, 1000)
                .call(fadeTweenComplete);
    }
}

function fadeTweenComplete(tween) {
    var clip = tween._target;
    if (clip.alpha <= 0) {
        stage.removeChild(clip);
        var index = clips.indexOf(clip);
        clips.splice(index, 1);
    }
}

Update:

here is another approach based on the simple tick method

http://jsfiddle.net/t21v9bo4/