Skip to content

Instantly share code, notes, and snippets.

@Hikari9
Last active February 29, 2016 13:43
Show Gist options
  • Select an option

  • Save Hikari9/bb0579bc831934c67500 to your computer and use it in GitHub Desktop.

Select an option

Save Hikari9/bb0579bc831934c67500 to your computer and use it in GitHub Desktop.
Parallax effect for jQuery.
<div parallax='margin'>
This will scroll 0.15 times faster by default, using margin-top and margin-bottom offsets.
</div>
<div parallax='padding'>
You may also parallax using the padding instead of margin.
</div>
<div parallax='margin' speed='0.5'>
You can edit how fast the scrolling will be for this element by using the speed attribute.
speed=0 is like doing position: fixed
speed=1 is the normal scrolling speed
speed=0.15 is the default if you didn't put anything
</div>
<div parallax='margin' breakpoint='0.5'>
You can also edit when the parallax activates by using the breakpoint attribute.
This only works for margin/padding.
The breakpoint is the percentage of the window height where the bottom of the element should touch in order to start the parallax.
breakpoint=1 is the default
</div>
<div parallax='background' speed='0.2' style='background-image: url(...)'>
This will scroll the background-image 5 times slower (0.2 times faster).
Note that breakpoint will not have any effect on background.
</div>
$(function() {
// parallax effect background position on scroll
// 0 = fixed, 1 = normal scroll
var wind = $(window);
var parallax = $('[parallax]');
function outsideWindow(e) { // check if outside window
e = $(e);
var a = e.offset().top;
var b = a + e.height();
var A = wind.scrollTop();
var B = A + wind.height();
return (a > B || b < A);
}
parallax.each(function() {
var item = $(this);
var info = item.attr('parallax').split(' ');
// window percentage breakpoint for when to activate parallax
var breakpoint = item.is('[breakpoint]') ? parseFloat(item.attr('breakpoint')) : 1;
function getFloat(css, def) {
var x = item.css(css);
return x == 'none' ? (def ? def : 0) : parseFloat(x);
}
function getSpeed() {
return item.is('[speed]') ? parseFloat(item.attr('speed')) : 0.15;
}
for (var i in info) {
switch (info[i]) {
case 'background':
// move background position
item.on('adjust', function() {
if (outsideWindow(item)) return;
// var pbot = item.offset().top + item.height();
// var wbot = wind.scrollTop() + Math.min(pbot, wind.height() * breakpoint);
// var scroll = Math.max(0, wbot - pbot);
var scroll = wind.scrollTop() - item.offset().top;
item.css('background-position', 'center ' + (getSpeed() * -scroll) + 'px');
}); break;
case 'margin': case 'padding':
// translate by using margin-top/padding-top
var top = info[i] + '-top';
var bot = info[i] + '-bottom';
var mtop = getFloat(top); // initial margin-top
var mbot = getFloat(bot); // initial margin-bottom
item.on('adjust', function() {
var ptop = item.offset().top - getFloat(top) + mtop;
var pbot = ptop + item.height();
var wbot = wind.scrollTop() + Math.min(pbot, wind.height() * breakpoint);
var delta = Math.max(0, wbot - pbot);
var margin = delta * (1 - getSpeed());
item.css(top, margin + mtop + 'px');
item.css(bot, -margin + mbot + 'px');
});
break;
case 'transform':
// translate by using CSS3 transform
var trans = item.css('transform');
var initY = 0;
if (trans == 'none')
trans = item.css('transform', 'translateY(0px)').css('transform');
else
initY = getFloat(trans.slice(trans.lastIndexOf(',') + 1));
item.on('adjust', function() {
var ptop = item.offset().top;
var pbot = ptop + item.height();
var wbot = wind.scrollTop() + Math.min(pbot, wind.height() * breakpoint);
var delta = Math.max(0, wbot - pbot);
var margin = delta * (1 - getSpeed());
var matrix = item.css('transform');
var comma = matrix.lastIndexOf(',') + 1;
var paren = matrix.lastIndexOf(')');
matrix = matrix.slice(0, comma) + margin + matrix.slice(paren);
item.css({
'-webkit-transform': matrix,
'-ms-transform': matrix,
'transform': matrix
});
});
break;
case 'opacity':
// EXPERIMENTAL
// fade opacity when window top intersects element
var inop = getFloat('opacity', 1); // initial opacity
item.on('adjust', function() {
var top = item.offset().top;
var bot = top + item.height();
var wtop = wind.scrollTop();
if (wtop > bot) {
item.css('opacity', '0');
} else if (wtop < top) {
item.css('opacity', inop);
} else {
item.css('opacity', (bot - wtop) / (bot - top) * inop);
}
});
}
}
});
// speed up performance by blocking simultaneous adjusts
var adjusting = false;
function adjust() {
if (!adjusting) {
adjusting = true;
parallax.trigger('adjust');
adjusting = false;
}
}
wind.scroll(adjust).resize(adjust); adjust();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment