TheCarver
TheCarver

Reputation: 19713

Continuous, looping, scrollable content in all directions

I've seen a very nice effect I'd like to try and reproduce for my own project but I'm struggling to see the best way to achieve it both in terms of performance and to operate absolutely seamlessly.

The effect is continous/looping content that can be scrolled and panned in any direction endlessly and appears to be completely seamless. It can be seen on Android's award-winning Leap:Second website here: http://leapsecond2015.com/.

I can think of a couple of ways to achieve this; one is by cloning the content body and repeat it once in all directions on page load and, when scrolled/panned, add more cloned content in the direction the user is moving in.

enter image description here

The thing I don't understand with this method is the performance, as I've yet to use .clone() in any of my projects. Let's say the user scrolled down continuously for 5-minutes, just for fun, and cloned 10,000 times - what are the cons of cloning so much content?

Another method I saw was to reset the scrollbar back to the beginning when the user reached the end of the content. A little bit like this demo:

var bgHeight = 1600; // pixel height of background image

$(document).ready(function() {   
    $('body').height( bgHeight + $(window).height() );
    $(window).scroll(function() {
        if ( $(window).scrollTop() >= ($('body').height() - $(window).height()) ) {
            $(window).scrollTop(1);
        }
        else if ( $(window).scrollTop() == 0 ) {
            $(window).scrollTop($('body').height() - $(window).height() -1);
        }    
    });
});
$(window).r
body {
    height: 1600px;
    background-image: url("");
    background-p
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Again, I struggle to see how this would work seamlessly when I added horizontal scrolling functionality to it as well but looks great vertically.

I'd like to know which one of these methods would perform better or, if none of them are suitable, please advice on how Android have achieved it on their Leap:Second website or suggest a new method.

I've had a decent Google on the subject but get flooded with 'inifinte scrolling' articles instead and have a hit a brick wall. I had a look at element inspection on Firefox and I think I came to the conclusion that they weren't cloning and appending but maybe I was wrong.

Upvotes: 5

Views: 3167

Answers (3)

TheCarver
TheCarver

Reputation: 19713

It took a while but I think I have finally discovered most of Android's methods used for this cool effect.

As @Kootsj kindly pointed out, the Leap:Second website uses PIXI-js - a webGL/canvas, 2-D rendering library, primarily used for gaming. After looking at alternative libraries, any of the gaming/rendering engines could be used to achieve the same result.

They use the rendering library to draw the individual images to their canvas in a smart, grid-like layout. They then use PIXI to animate/transform the canvas on scroll, mouse, touch and drag events - for the ultimate smoothness I guess.

Looking into PIXI more, 'canvas caching' and 'scene buffering' is possible. Knowing this, I'd imagine they're caching/cloning the image board and somehow pasting it in the directions the user is scolling/panning in but becasue it's 'cached' or 'buffered', it performs extremely well. I'm still not 100% how they achieve the inifity-panning feature but seems like this could be close.

Their script consists of 20,500+ lines of Javscript and pretty much resembles the architecture of a game. It's going to take some serious effort to achieve a similar effect with matching performance but will try.

If I learn anything more about this feature or come up with a working example, I will update this answer with my findings.

Upvotes: 0

Rounin
Rounin

Reputation: 29463

To start with, you can achieve an infinitely scrolling background with very little processor cost by using a CSS repeated background and a very small amount of javascript:

window.scroll(1800,1800);

function resetWindow() {

    if (window.pageXOffset < 900) {
    window.scrollBy(900,0);
    }

    if (window.pageXOffset > 2700) {
    window.scrollBy(-900,0);
    }

    if (window.pageYOffset < 900) {
    window.scrollBy(0,900);
    }

    if (window.pageYOffset > 2700) {
    window.scrollBy(0,-900);
    }
}

window.addEventListener('scroll',resetWindow,false);
body {
width: 3600px;
height: 3600px;
background-image: url('http://1-background.com/images/stars-1/star-space-tile.jpg');
background-size: 300px 300px;
background-repeat: repeat;
}

As you can see, the window does not scroll infinitely at all. Instead the window (only 3600px x 3600px) keeps correcting its own position, so it only looks as if it is being infinitely scrolled.

Adding content is a little more complex, but as long as the pattern of elements repeats (predictably) in 2 dimensions, the same principle can be employed: using scrollBy() to take the scrollbars back to an earlier viewport-position that looks identical to the one which the user is just about to enter.

For more complex scenarios involving a more random distribution of elements, rather than cloning elements, I would be tempted to replace already existing elements using insertBefore(); such that an element which is (say) 300px below the viewport and 900px to the right of the viewport is moved, so that is now 600px above the viewport and 300px to the left of the viewport.

This will enable a seemingly-infinite movement in all four directions (and a random distribution of elements across that seemingly-infinite field), without increasing the number of elements in the document.

Upvotes: 2

Kootsj
Kootsj

Reputation: 431

It looks like http://leapsecond2015.com/ uses http://www.pixijs.com/ which handles the performance of loading an "infinite" amount of images/items

Upvotes: 2

Related Questions