Search code examples
javascriptcanvasgsappixi.js

Draw a line with PIXI and move it with TweenMax


I watched an example of using this both framework (PIXIjs and GSAP). So I wanted to use it

I'm a little bit stuck on a case. So what I want to do is to draw 3 line that match the border of my window. That's fine, but In a second step, I'd like that this lines move without leaving the border.

Here is my little code for this part

// This is how I create the line
    var lineArray = [];

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

        var line = new PIXI.Graphics();
        line.lineStyle(1, 0xf3a33f);

        if(i == 0) {
            line.moveTo(getRandomInt(0, window.innerWidth), window.innerHeight);
            line.lineTo(getRandomInt(0, window.innerWidth), 0);
        } else if(i == 1) {
            line.moveTo(0, getRandomInt(0, window.innerHeight));
            line.lineTo(window.innerWidth, getRandomInt(0, window.innerHeight));
        } else {
            line.moveTo(getRandomInt(0, window.innerWidth), window.innerHeight);
            line.lineTo(window.innerWidth, getRandomInt(0, window.innerHeight));
        }

        line.endFill();
        line.alpha = 0;

        stage.addChild(line);
        lineArray.push(line);

    }

// And this is how I want to animate it

var timeline = new TimelineMax({ paused: true });
for (var i = lineArray.length - 1; i >= 0; i--) {
    lineArray[i].beginFill(0xf3a33f, 1);
    timeline.add(TweenMax.to( lineArray[i], .05, {alpha: 1}), 1.25);
}
timeline.play();

Is there a way to move the lineTo(x, y) and moveTo(x, y) of the graphics shape ? I thought that I can redraw each time that I move the line, and destroy the old one, but I hope that there is a easier way to do that.

Cheers, H4mm3R


Solution

  • If you wish to be able to animate / tween the moveTo and lineTo values then the graphics object of each line will need updating i.e. clear(); and then redraw with the usual moveTo and lineTo calls with new values. All happening inside a render function which updates your canvas timely.

    The other thing is you will need a way to keep a track of your start and end values. I have resorted to arrays by the names currPoints and destPoints in my example below, code of which is as follows:

    JavaScript:

    var lineWidth = 2,
        lineColor = 0xf3a33f,
        length = 4,
        currPoints = [],
        destPoints = [],
        lineArray = [],
        duration = 1.4,
        ease = Power4.easeInOut,
        staggerFactor = .06;
    
    function init() {
        initScene();
        initLines();
        animateLines();
        TweenLite.ticker.addEventListener('tick', render);
    }
    
    function animateLines() {
        for (var i = 0; i < length; i += 1) {
            TweenMax.fromTo(lineArray[i], duration, {
                alpha: 0
            }, {
                delay: i * staggerFactor,
                alpha: 1,
                repeat: -1,
                yoyo: true,
                repeatDelay: duration * .5,
                ease: ease
            });
            TweenMax.to(currPoints[i].moveTo, duration, {
                delay: i * staggerFactor,
                x: destPoints[i].moveTo.x,
                y: destPoints[i].moveTo.y,
                repeat: -1,
                yoyo: true,
                repeatDelay: duration * .5,
                ease: ease
            });
            TweenMax.to(currPoints[i].lineTo, duration, {
                delay: i * staggerFactor,
                x: destPoints[i].lineTo.x,
                y: destPoints[i].lineTo.y,
                repeat: -1,
                yoyo: true,
                repeatDelay: duration * .5,
                ease: ease
            });
        }
    }
    
    function initLines() {
        var line;
        for (var i = 0; i < length; i += 1) {
            line = new PIXI.Graphics().lineStyle(1, 0xf3a33f);
            if (i == 0) {
                currPoints[i] = getPoint(getRandomInt(0, window.innerWidth), window.innerHeight, getRandomInt(0, window.innerWidth), 0);
                destPoints[i] = getPoint(getRandomInt(0, window.innerWidth), window.innerHeight, getRandomInt(0, window.innerWidth), 0);
            } else if (i == 1) {
                currPoints[i] = getPoint(0, getRandomInt(0, window.innerHeight), window.innerWidth, getRandomInt(0, window.innerHeight));
                destPoints[i] = getPoint(0, getRandomInt(0, window.innerHeight), window.innerWidth, getRandomInt(0, window.innerHeight));
            } else {
                currPoints[i] = getPoint(getRandomInt(0, window.innerWidth), window.innerHeight, window.innerWidth, getRandomInt(0, window.innerHeight));
                destPoints[i] = getPoint(getRandomInt(0, window.innerWidth), window.innerHeight, window.innerWidth, getRandomInt(0, window.innerHeight));
            }
            line.moveTo(currPoints[i].moveTo.x, currPoints[i].moveTo.y);
            line.lineTo(currPoints[i].lineTo.x, currPoints[i].lineTo.y);
            main.addChild(line);
            lineArray.push(line);
        }
    }
    
    function initScene() {
        renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight, {
            view: document.querySelector('canvas'),
            antialias: true
        });
        main = new PIXI.Container();
    }
    
    function render() {
        renderer.render(main);
        for (var i = 0; i < length; i += 1) {
            lineArray[i].clear();
            lineArray[i].lineStyle(lineWidth, lineColor);
            lineArray[i].moveTo(currPoints[i].moveTo.x, currPoints[i].moveTo.y);
            lineArray[i].lineTo(currPoints[i].lineTo.x, currPoints[i].lineTo.y);
        }
    }
    
    function getPoint(xMoveTo, yMoveTo, xLineTo, yLineTo) {
        return {
            moveTo: {
                x: xMoveTo,
                y: yMoveTo
            },
            lineTo: {
                x: xLineTo,
                y: yLineTo
            }
        };
    }
    
    function getRandomInt(min, max) {
        return Math.floor(Math.random() * (1 + max - min) + min);
    };
    
    //
    init();
    

    Play with the jsFiddle and let me know if this is what you were looking for.

    T