Skip to content

Instantly share code, notes, and snippets.

@thenikso
Created April 16, 2015 08:52
Show Gist options
  • Save thenikso/592c95bf597c218000ac to your computer and use it in GitHub Desktop.
Save thenikso/592c95bf597c218000ac to your computer and use it in GitHub Desktop.
AngularJS parallax effect component
'use strict';
(function() {
var $window, parallaxItems, addParallaxItem, removeParallaxItem, updateParallax;
angular.module('app.Components.ParallaxBox', [])
.directive('parallaxBox', function() {
return {
restrict: 'A',
controller: ['$element', function($element) {
this.element = $element;
return this;
}],
link: function (scope, element, attrs) {
element.css({
overflow: 'hidden'
});
}
};
})
.directive('parallaxMultiplier', function() {
return {
restrict: 'A',
require: '^parallaxBox',
priority: 0,
link: function(scope, element, attrs, controller) {
var parallaxItem;
if (typeof Modernizr !== "undefined" && Modernizr !== null ? Modernizr.touch : void 0) {
return;
}
parallaxItem = {
parent: controller.element,
element: element,
multiplier: parseFloat(attrs.parallaxMultiplier)
};
addParallaxItem(parallaxItem);
scope.$on('$destroy', function() {
return removeParallaxItem(parallaxItem);
});
setTimeout(function () {
var backgroundImageUrl = element.css('background-image').replace('url(','').replace(')','');
if (backgroundImageUrl) {
var backgroundImage = new Image();
backgroundImage.onload = function () {
setTimeout(updateParallax, 200);
backgroundImage = null;
};
backgroundImage.src = backgroundImageUrl;
}
else {
scope.$applyAsync(updateParallax);
}
});
}
};
});
parallaxItems = [];
addParallaxItem = function (parallaxItem) {
if (parallaxItems.length == 0) {
$window.bind('scroll', updateParallax);
}
parallaxItems.push(parallaxItem);
};
removeParallaxItem = function(parallaxItem) {
parallaxItems = parallaxItems.filter(function(i) {
return i !== parallaxItem;
});
if (parallaxItems.length == 0) {
$window.unbind('scroll', updateParallax);
}
};
$window = angular.element(window);
$window.scrollTop = function () {
var doc = document.documentElement;
// var left = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
var top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
return top;
};
if (!has3d()) {
updateParallax = function() {
var item, translateY, _i, _len, _results;
_results = [];
for (_i = 0, _len = parallaxItems.length; _i < _len; _i++) {
item = parallaxItems[_i];
translateY = Math.floor(($window.scrollTop() - item.parent[0].offsetTop) * item.multiplier);
_results.push(item.element.css('margin-top', "" + translateY + "px"));
}
return _results;
};
} else {
updateParallax = function() {
var item, translateY, _i, _len;
for (_i = 0, _len = parallaxItems.length; _i < _len; _i++) {
item = parallaxItems[_i];
translateY = Math.floor(($window.scrollTop() - item.parent[0].offsetTop) * item.multiplier);
item.element.css({
'-webkit-transform': "translate3d(0px, " + translateY + "px, 0px)",
'-mox-transform': "translate3d(0px, " + translateY + "px, 0px)",
'-o-transform': "translate3d(0px, " + translateY + "px, 0px)",
'-ms-transform': "translateY(" + translateY + "px)",
'transform': "translate3d(0px, " + translateY + "px, 0px)"
});
}
};
}
function has3d(){
var el = document.createElement('p'),
has3d,
transforms = {
'webkitTransform':'-webkit-transform',
'OTransform':'-o-transform',
'msTransform':'-ms-transform',
'MozTransform':'-moz-transform',
'transform':'transform'
};
// Add it to the body to get the computed style
document.body.insertBefore(el, null);
for(var t in transforms){
if( el.style[t] !== undefined ){
el.style[t] = 'translate3d(1px,1px,1px)';
has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
}
}
document.body.removeChild(el);
return (has3d !== undefined && has3d.length > 0 && has3d !== "none");
}
})();
@thenikso
Copy link
Author

Example usage:

<div parallax-box>
    <div class="my-bg-with-background-image" parallax-multiplier="0.5"></div>
</div>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment