I'm having some issues with parallaxing backgrounds. I've made a little website for an event organized by some friends of mine, and on that site I have a bunch of background images alternating in between content sections. I've added some logic to offset these background images when scrolling, to create a parallaxing effect.
It's working well enough and I haven't noticed any performance issues, but when using the scrollwheel, the parallaxing seems to be lagging behind in WebKit browsers.
Here's a link to the website:
The effect I've tried to mimic, at least for the background images, is the one seen on the Spotify website:
From looking at their source code, I seem to be doing more or less the same thing: I have a parallaxing function that calculates the background transform based on the scrollTop
value of the document, and this function is throttled to 16 ms and bound to the window's scroll event. Still, the background transformation on the Spotify site is instant, while mine visually lags behind the content. It's not "broken" as in it works well in Firefox/IE and it works in WebKit browsers when sliding the scrollbar manually... but it's really annoying.
Does anyone have any tips on what is causing this jerkiness?
Here's the code for the parallaxing functionality (I'm using prototype so sorry about the this
spam):
parallaxBackground: function () {
var viewportTop = this.elements.$document.scrollTop();
var viewportBottom = viewportTop + this.elements.$window.height();
var scrollDelta = this.slideHeight + this.elements.$window.height();
$.each( this.backgroundSlides, function ( index, slide ) {
var slideTop = slide.$container.offset().top;
var slideBottom = slideTop + this.slideHeight;
if ( slideBottom < viewportTop || slideTop > viewportBottom )
return true;
var factor = 1 - ( slideBottom - viewportTop ) / scrollDelta;
this.transformBackground( slide.$image, this.slideLength * ( factor - 1 ) );
}.bind( this ) );
},
transformBackground: Modernizr.csstransforms ? function ( $backgroundElement, distance ) {
$backgroundElement.css( {
'-ms-transform': 'translate(0px, ' + distance + 'px)',
'-webkit-transform': 'translate(0px, ' + distance + 'px)',
'transform': 'translate(0px, ' + distance + 'px)'
} );
} : function ( $backgroundElement, distance ) {
$backgroundElement.css( 'top', distance );
}
And here's how it gets bound (using Underscore for throttling):
this.elements.$window.on( 'scroll',
_.throttle( this.parallaxBackground.bind( this ), 16 ) );