Smooth parallax scrolling

This post is about a site that I built recently (http://www.leicestercityofculture2017.co.uk) that uses the infamous parallax scrolling technique, and some of the issues I found trying to do it.

There’s millions of tutorials about how to implement parallax scrolling, so I won’t go into that here. When I was trying to do it, the main issue I faced was the smoothness of the scrolling. If the page height is absolutely gigantic, its not so much of a problem since the discrete scrolling steps of most browsers (the interpolation) will be quite small, so the scroll action won’t be jerky.

The Jerk

However, on the city of culture site, the home page was relatively short. It contains just four main sections. When I built it, it was in firefox, which by default has animated interpolation, so when using the mouse scroll wheel, things looked great. When I tested it in chrome, IE etc, it was all jerky and spoilt the effect completely. One example of this is the white house iraq timeline site (http://www.whitehouse.gov/iraq). Its not horrible, but if you view it in chrome or IE, there is a definite jerk when scrolling using the mouse wheel.

The solution I settled on was to use the ‘nicescroll‘ jquery plugin. Its simple to use and forces the browser to animate the interpolated scroll steps, so even when using the mouse wheel to scroll, it looks ok.

Parallax methods

When researching how to do this, a number of the tutorials I read used data attributes in the html markup to specify the speed that elements move, their offset values etc. I didn’t like that idea since it combined presentation and behaviour. The way I did it was by having a json config file that specified all the animated elements, their ids, speeds, positions and offsets. This keeps all the parallax behaviour in one place. Here’s a snippet of it…

{ 
    "panel" : [ 
        {
            "id" : "pnl1-intro",
            "isMainPanel" : true,
            "speed": {
                "x": 0,
                "y": 7
            },
            "position" : {
                "x": "50%",
                "y": 0
            },
            "offset": {
                "x": 0,
                "y": 0
            }
        },

So, from my actual parallax processing script, this just loads the config and loops through it. In this way, if the site is being viewed on mobile, the parallax stuff does not need to be loaded or processed at all. It also separates presentation from behaviour.

Only animate what you need to

One other thing that I’ve seen on quite a few other parallax scrolling sites is that when the window is scrolled, the script first checks that the actual element is on screen. If its not, there’s no point doing the calculation to move it. On a page with lots of elements, large pngs, videos etc, it makes sense to only do what you have to. Here’s some of my ‘updateElements’ function…

function updateElements() {
        //...
        $(scrollingElements).each(function () {
            if (isInView.apply(win, [this.dom.top, this.dom.bottom]))  
            {
                if(this.isMainPanel){
                    selectedPanel = this;
                }
                move.apply(this, [win]);
            }
        });
//...      

function isInView(top, bottom) {
        var inview  = (this.scrollTop() + this.height()) > top && bottom > this.scrollTop();
        return inview;
}

So, on each animation frame, the function loops through all elements in the ‘scrollingElements’ array. The dom element is passed to the ‘isInView’ function that looks at its top and bottom position and determines if its within the current window. If it is, its moved, if not, its ignored. The ‘move’ function just determines the next position for that object based on its config and then updates its background position.

Considerations

Since this was for a local authority, naturally the powers that be wanted it ‘all singing, all dancing’ (grr). However, it also had to work in IE7. This was the reason for not going with a canvas-based approach and sticking to the more traditional method of updating the background position of a fixed position element. If you look at the city of culture site in ie7, though, you’ll see the scrolling is just as nice as ff, chrome etc. Its even got simple responsive stuff built in so it shows a non-parallax view on smaller devices.

There’s my 2p’s worth anyway.

Leave a Reply