Search code examples
javascriptscrollmoveparallax

javascript how to move element on route on scroll


I have a route like a vertical snake. (like this http://www.my-favorite-coloring.net/Images/Large/Animals-Reptiles-Snake-31371.png )

How I can move element (circle 10x10) on route by X and Y position on scroll?

Horizonal is ok :

    var coin = $('#coin');

    $(window).scroll(function(){
        var coinTop = coin.css('top'),
            cointLeft = coin.css('left');

        if($(window).scrollTop() > 100 && $(window).scrollTop() < 600){
            $("#coin").css({ "left":  contLeft + 'px' });
        };
    });

But how I cat move it smoothly along the route?


Solution

  • I would suggest using a vector (SVG) library, namely raphael.js for the animation part.

    In raphael.js you can define a path and then animate any object along the length of that path.

    Please see the example and a corresponding stackoverflow thread for better understanding:

    Compared to the thread, you need to attach the animation on the onScroll event, as opposed to attaching it to a Interval.

    Edit:

    Adding the relevant code snippet from the link, as the commenter suggested:

    HTML:

    <div id="holder"></div>
    

    JS:

    var e;
    var myPath;
    var animation;  //make the variables global, so you can access them in the animation function
    window.onload = function() {
        var r = Raphael("holder", 620, 420),
            discattr = {
                fill: "#666",
                stroke: "none"
            };
        function curve(x, y, zx, zy, colour) {
            var ax = Math.floor(Math.random() * 200) + x;
            var ay = Math.floor(Math.random() * 200) + (y - 100);
            var bx = Math.floor(Math.random() * 200) + (zx - 200);
            var by = Math.floor(Math.random() * 200) + (zy - 100);
            e = r.image("http://openclipart.org/image/800px/svg_to_png/10310/Odysseus_boy.png", x, y, 10, 10);
            var path = [["M", x, y], ["C", ax, ay, bx, by, zx, zy]];
                myPath = r.path(path).attr({
                    stroke: colour,
                    "stroke-width": 2,
                    "stroke-linecap": "round",
                    "stroke-opacity": 0.2
                });
            controls = r.set(
                r.circle(x, y, 5).attr(discattr), r.circle(zx, zy, 5).attr(discattr));
        }
        curve(100,100,200,300,"red");
        animation = window.setInterval("animate()", 10);  //execute the animation function all 10ms (change the value for another speed)
    };
    var counter = 0;    // a counter that counts animation steps
    function animate(){
        if(myPath.getTotalLength() <= counter){   //break as soon as the total length is reached
            clearInterval(animation);
            return;
        }
        var pos = myPath.getPointAtLength(counter);   //get the position (see Raphael docs)
        e.attr({x: pos.x, y: pos.y});  //set the circle position
        counter++; // count the step counter one up
    };
    

    Update:

    I've recently used pathAnimator for the same task. Be careful about the performance though, a complicated animation might be quite intensive.