Guest User

Untitled

a guest
Jun 19th, 2020
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*!
  2.  * Stellar.js v0.6.2
  3.  * http://markdalgleish.com/projects/stellar.js
  4.  *
  5.  * Copyright 2013, Mark Dalgleish
  6.  * This content is released under the MIT license
  7.  * http://markdalgleish.mit-license.org
  8.  */
  9.  
  10. ;(function($, window, document, undefined) {
  11.  
  12.     var pluginName = 'stellar',
  13.         defaults = {
  14.             scrollProperty: 'scroll',
  15.             positionProperty: 'position',
  16.             horizontalScrolling: true,
  17.             verticalScrolling: true,
  18.             horizontalOffset: 0,
  19.             verticalOffset: 0,
  20.             responsive: false,
  21.             parallaxBackgrounds: true,
  22.             parallaxElements: true,
  23.             hideDistantElements: true,
  24.             hideElement: function($elem) { $elem.hide(); },
  25.             showElement: function($elem) { $elem.show(); }
  26.         },
  27.  
  28.         scrollProperty = {
  29.             scroll: {
  30.                 getLeft: function($elem) { return $elem.scrollLeft(); },
  31.                 setLeft: function($elem, val) { $elem.scrollLeft(val); },
  32.  
  33.                 getTop: function($elem) { return $elem.scrollTop(); },
  34.                 setTop: function($elem, val) { $elem.scrollTop(val); }
  35.             },
  36.             position: {
  37.                 getLeft: function($elem) { return parseInt($elem.css('left'), "10px") * -1; },
  38.                 getTop: function($elem) { return parseInt($elem.css('top'), "10px") * -1; }
  39.             },
  40.             margin: {
  41.                 getLeft: function($elem) { return parseInt($elem.css('margin-left'), "10px") * -1; },
  42.                 getTop: function($elem) { return parseInt($elem.css('margin-top'), "10px") * -1; }
  43.             },
  44.             transform: {
  45.                 getLeft: function($elem) {
  46.                     var computedTransform = getComputedStyle($elem[0])[prefixedTransform];
  47.                     return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[4], 10) * -1 : 0);
  48.                 },
  49.                 getTop: function($elem) {
  50.                     var computedTransform = getComputedStyle($elem[0])[prefixedTransform];
  51.                     return (computedTransform !== 'none' ? parseInt(computedTransform.match(/(-?[0-9]+)/g)[5], 10) * -1 : 0);
  52.                 }
  53.             }
  54.         },
  55.  
  56.         positionProperty = {
  57.             position: {
  58.                 setLeft: function($elem, left) { $elem.css('left', left); },
  59.                 setTop: function($elem, top) { $elem.css('top', top); }
  60.             },
  61.             transform: {
  62.                 setPosition: function($elem, left, startingLeft, top, startingTop) {
  63.                     $elem[0].style[prefixedTransform] = 'translate3d(' + (left - startingLeft) + 'px, ' + (top - startingTop) + 'px, 0)';
  64.                 }
  65.             }
  66.         },
  67.  
  68.         // Returns a function which adds a vendor prefix to any CSS property name
  69.         vendorPrefix = (function() {
  70.             var prefixes = /^(Moz|Webkit|Khtml|O|ms|Icab)(?=[A-Z])/,
  71.                 style = $('script')[0].style,
  72.                 prefix = '',
  73.                 prop;
  74.  
  75.             for (prop in style) {
  76.                 if (prefixes.test(prop)) {
  77.                     prefix = prop.match(prefixes)[0];
  78.                     break;
  79.                 }
  80.             }
  81.  
  82.             if ('WebkitOpacity' in style) { prefix = 'Webkit'; }
  83.             if ('KhtmlOpacity' in style) { prefix = 'Khtml'; }
  84.  
  85.             return function(property) {
  86.                 return prefix + (prefix.length > 0 ? property.charAt(0).toUpperCase() + property.slice(1) : property);
  87.             };
  88.         }()),
  89.  
  90.         prefixedTransform = vendorPrefix('transform'),
  91.  
  92.         supportsBackgroundPositionXY = $('<div />', { style: 'background:#fff' }).css('background-position-x') !== undefined,
  93.  
  94.         setBackgroundPosition = (supportsBackgroundPositionXY ?
  95.             function($elem, x, y) {
  96.                 $elem.css({
  97.                     'background-position-x': x,
  98.                     'background-position-y': y
  99.                 });
  100.             } :
  101.             function($elem, x, y) {
  102.                 $elem.css('background-position', x + ' ' + y);
  103.             }
  104.         ),
  105.  
  106.         getBackgroundPosition = (supportsBackgroundPositionXY ?
  107.             function($elem) {
  108.                 return [
  109.                     $elem.css('background-position-x'),
  110.                     $elem.css('background-position-y')
  111.                 ];
  112.             } :
  113.             function($elem) {
  114.                 return $elem.css('background-position').split(' ');
  115.             }
  116.         ),
  117.  
  118.         requestAnimFrame = (
  119.             window.requestAnimationFrame       ||
  120.             window.webkitRequestAnimationFrame ||
  121.             window.mozRequestAnimationFrame    ||
  122.             window.oRequestAnimationFrame      ||
  123.             window.msRequestAnimationFrame     ||
  124.             function(callback) {
  125.                 setTimeout(callback, 1000 / 60);
  126.             }
  127.         );
  128.  
  129.     function Plugin(element, options) {
  130.         this.element = element;
  131.         this.options = $.extend({}, defaults, options);
  132.  
  133.         this._defaults = defaults;
  134.         this._name = pluginName;
  135.  
  136.         this.init();
  137.     }
  138.  
  139.     Plugin.prototype = {
  140.         init: function() {
  141.             this.options.name = pluginName + '_' + Math.floor(Math.random() * 1e9);
  142.  
  143.             this._defineElements();
  144.             this._defineGetters();
  145.             this._defineSetters();
  146.             this._handleWindowLoadAndResize();
  147.             this._detectViewport();
  148.  
  149.             this.refresh({ firstLoad: true });
  150.  
  151.             if (this.options.scrollProperty === 'scroll') {
  152.                 this._handleScrollEvent();
  153.             } else {
  154.                 this._startAnimationLoop();
  155.             }
  156.         },
  157.         _defineElements: function() {
  158.             if (this.element === document.body) this.element = window;
  159.             this.$scrollElement = $(this.element);
  160.             this.$element = (this.element === window ? $('body') : this.$scrollElement);
  161.             this.$viewportElement = (this.options.viewportElement !== undefined ? $(this.options.viewportElement) : (this.$scrollElement[0] === window || this.options.scrollProperty === 'scroll' ? this.$scrollElement : this.$scrollElement.parent()) );
  162.         },
  163.         _defineGetters: function() {
  164.             var self = this,
  165.                 scrollPropertyAdapter = scrollProperty[self.options.scrollProperty];
  166.  
  167.             this._getScrollLeft = function() {
  168.                 return scrollPropertyAdapter.getLeft(self.$scrollElement);
  169.             };
  170.  
  171.             this._getScrollTop = function() {
  172.                 return scrollPropertyAdapter.getTop(self.$scrollElement);
  173.             };
  174.         },
  175.         _defineSetters: function() {
  176.             var self = this,
  177.                 scrollPropertyAdapter = scrollProperty[self.options.scrollProperty],
  178.                 positionPropertyAdapter = positionProperty[self.options.positionProperty],
  179.                 setScrollLeft = scrollPropertyAdapter.setLeft,
  180.                 setScrollTop = scrollPropertyAdapter.setTop;
  181.  
  182.             this._setScrollLeft = (typeof setScrollLeft === 'function' ? function(val) {
  183.                 setScrollLeft(self.$scrollElement, val);
  184.             } : $.noop);
  185.  
  186.             this._setScrollTop = (typeof setScrollTop === 'function' ? function(val) {
  187.                 setScrollTop(self.$scrollElement, val);
  188.             } : $.noop);
  189.  
  190.             this._setPosition = positionPropertyAdapter.setPosition ||
  191.                 function($elem, left, startingLeft, top, startingTop) {
  192.                     if (self.options.horizontalScrolling) {
  193.                         positionPropertyAdapter.setLeft($elem, left, startingLeft);
  194.                     }
  195.  
  196.                     if (self.options.verticalScrolling) {
  197.                         positionPropertyAdapter.setTop($elem, top, startingTop);
  198.                     }
  199.                 };
  200.         },
  201.         _handleWindowLoadAndResize: function() {
  202.             var self = this,
  203.                 $window = $(window);
  204.  
  205.             if (self.options.responsive) {
  206.                 $window.on("load." + this.name, function() {
  207.                     self.refresh();
  208.                 });
  209.             }
  210.  
  211.             $window.on('resize.' + this.name, function() {
  212.                 self._detectViewport();
  213.  
  214.                 if (self.options.responsive) {
  215.                     self.refresh();
  216.                 }
  217.             });
  218.         },
  219.         refresh: function(options) {
  220.             var self = this,
  221.                 oldLeft = self._getScrollLeft(),
  222.                 oldTop = self._getScrollTop();
  223.  
  224.             if (!options || !options.firstLoad) {
  225.                 this._reset();
  226.             }
  227.  
  228.             this._setScrollLeft(0);
  229.             this._setScrollTop(0);
  230.  
  231.             this._setOffsets();
  232.             this._findParticles();
  233.             this._findBackgrounds();
  234.  
  235.             // Fix for WebKit background rendering bug
  236.             if (options && options.firstLoad && /WebKit/.test(navigator.userAgent)) {
  237.                 $(window).on("load", function() {
  238.                     var oldLeft = self._getScrollLeft(),
  239.                         oldTop = self._getScrollTop();
  240.  
  241.                     self._setScrollLeft(oldLeft + 1);
  242.                     self._setScrollTop(oldTop + 1);
  243.  
  244.                     self._setScrollLeft(oldLeft);
  245.                     self._setScrollTop(oldTop);
  246.                 });
  247.             }
  248.  
  249.             this._setScrollLeft(oldLeft);
  250.             this._setScrollTop(oldTop);
  251.         },
  252.         _detectViewport: function() {
  253.             var viewportOffsets = this.$viewportElement.offset(),
  254.                 hasOffsets = viewportOffsets !== null && viewportOffsets !== undefined;
  255.  
  256.  
  257.             this.viewportWidth = this.$viewportElement.width();
  258.             this.viewportHeight = this.$viewportElement.height();
  259.  
  260.             this.viewportOffsetTop = (hasOffsets ? viewportOffsets.top : 0);
  261.             this.viewportOffsetLeft = (hasOffsets ? viewportOffsets.left : 0);
  262.         },
  263.         _findParticles: function() {
  264.             var self = this,
  265.                 scrollLeft = this._getScrollLeft(),
  266.                 scrollTop = this._getScrollTop();
  267.  
  268.             if (this.particles !== undefined) {
  269.                 for (var i = this.particles.length - 1; i >= 0; i--) {
  270.                     this.particles[i].$element.data('stellar-elementIsActive', undefined);
  271.                 }
  272.             }
  273.  
  274.             this.particles = [];
  275.  
  276.             if (!this.options.parallaxElements) return;
  277.  
  278.             this.$element.find('[data-stellar-ratio]').each(function(i) {
  279.                 var $this = $(this),
  280.                     horizontalOffset,
  281.                     verticalOffset,
  282.                     positionLeft,
  283.                     positionTop,
  284.                     marginLeft,
  285.                     marginTop,
  286.                     $offsetParent,
  287.                     offsetLeft,
  288.                     offsetTop,
  289.                     parentOffsetLeft = 0,
  290.                     parentOffsetTop = 0,
  291.                     tempParentOffsetLeft = 0,
  292.                     tempParentOffsetTop = 0;
  293.  
  294.                 // Ensure this element isn't already part of another scrolling element
  295.                 if (!$this.data('stellar-elementIsActive')) {
  296.                     $this.data('stellar-elementIsActive', this);
  297.                 } else if ($this.data('stellar-elementIsActive') !== this) {
  298.                     return;
  299.                 }
  300.  
  301.                 self.options.showElement($this);
  302.  
  303.                 // Save/restore the original top and left CSS values in case we refresh the particles or destroy the instance
  304.                 if (!$this.data('stellar-startingLeft')) {
  305.                     $this.data('stellar-startingLeft', $this.css('left'));
  306.                     $this.data('stellar-startingTop', $this.css('top'));
  307.                 } else {
  308.                     $this.css('left', $this.data('stellar-startingLeft'));
  309.                     $this.css('top', $this.data('stellar-startingTop'));
  310.                 }
  311.  
  312.                 positionLeft = $this.position().left;
  313.                 positionTop = $this.position().top;
  314.  
  315.                 // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8)
  316.                 marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), "10px");
  317.                 marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), "10px");
  318.  
  319.                 offsetLeft = $this.offset().left - marginLeft;
  320.                 offsetTop = $this.offset().top - marginTop;
  321.  
  322.                 // Calculate the offset parent
  323.                 $this.parents().each(function() {
  324.                     var $this = $(this);
  325.  
  326.                     if ($this.data('stellar-offset-parent') === true) {
  327.                         parentOffsetLeft = tempParentOffsetLeft;
  328.                         parentOffsetTop = tempParentOffsetTop;
  329.                         $offsetParent = $this;
  330.  
  331.                         return false;
  332.                     } else {
  333.                         tempParentOffsetLeft += $this.position().left;
  334.                         tempParentOffsetTop += $this.position().top;
  335.                     }
  336.                 });
  337.  
  338.                 // Detect the offsets
  339.                 horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset));
  340.                 verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset));
  341.  
  342.                 // Add our object to the particles collection
  343.                 self.particles.push({
  344.                     $element: $this,
  345.                     $offsetParent: $offsetParent,
  346.                     isFixed: $this.css('position') === 'fixed',
  347.                     horizontalOffset: horizontalOffset,
  348.                     verticalOffset: verticalOffset,
  349.                     startingPositionLeft: positionLeft,
  350.                     startingPositionTop: positionTop,
  351.                     startingOffsetLeft: offsetLeft,
  352.                     startingOffsetTop: offsetTop,
  353.                     parentOffsetLeft: parentOffsetLeft,
  354.                     parentOffsetTop: parentOffsetTop,
  355.                     stellarRatio: ($this.data('stellar-ratio') !== undefined ? $this.data('stellar-ratio') : 1),
  356.                     width: $this.outerWidth(true),
  357.                     height: $this.outerHeight(true),
  358.                     isHidden: false
  359.                 });
  360.             });
  361.         },
  362.         _findBackgrounds: function() {
  363.             var self = this,
  364.                 scrollLeft = this._getScrollLeft(),
  365.                 scrollTop = this._getScrollTop(),
  366.                 $backgroundElements;
  367.  
  368.             this.backgrounds = [];
  369.  
  370.             if (!this.options.parallaxBackgrounds) return;
  371.  
  372.             $backgroundElements = this.$element.find('[data-stellar-background-ratio]');
  373.  
  374.             if (this.$element.data('stellar-background-ratio')) {
  375.                 $backgroundElements = $backgroundElements.add(this.$element);
  376.             }
  377.  
  378.             $backgroundElements.each(function() {
  379.                 var $this = $(this),
  380.                     backgroundPosition = getBackgroundPosition($this),
  381.                     horizontalOffset,
  382.                     verticalOffset,
  383.                     positionLeft,
  384.                     positionTop,
  385.                     marginLeft,
  386.                     marginTop,
  387.                     offsetLeft,
  388.                     offsetTop,
  389.                     $offsetParent,
  390.                     parentOffsetLeft = 0,
  391.                     parentOffsetTop = 0,
  392.                     tempParentOffsetLeft = 0,
  393.                     tempParentOffsetTop = 0;
  394.  
  395.                 // Ensure this element isn't already part of another scrolling element
  396.                 if (!$this.data('stellar-backgroundIsActive')) {
  397.                     $this.data('stellar-backgroundIsActive', this);
  398.                 } else if ($this.data('stellar-backgroundIsActive') !== this) {
  399.                     return;
  400.                 }
  401.  
  402.                 // Save/restore the original top and left CSS values in case we destroy the instance
  403.                 if (!$this.data('stellar-backgroundStartingLeft')) {
  404.                     $this.data('stellar-backgroundStartingLeft', backgroundPosition[0]);
  405.                     $this.data('stellar-backgroundStartingTop', backgroundPosition[1]);
  406.                 } else {
  407.                     setBackgroundPosition($this, $this.data('stellar-backgroundStartingLeft'), $this.data('stellar-backgroundStartingTop'));
  408.                 }
  409.  
  410.                 // Catch-all for margin top/left properties (these evaluate to 'auto' in IE7 and IE8)
  411.                 marginLeft = ($this.css('margin-left') === 'auto') ? 0 : parseInt($this.css('margin-left'), "10px");
  412.                 marginTop = ($this.css('margin-top') === 'auto') ? 0 : parseInt($this.css('margin-top'), "10px");
  413.  
  414.                 offsetLeft = $this.offset().left - marginLeft - scrollLeft;
  415.                 offsetTop = $this.offset().top - marginTop - scrollTop;
  416.                
  417.                 // Calculate the offset parent
  418.                 $this.parents().each(function() {
  419.                     var $this = $(this);
  420.  
  421.                     if ($this.data('stellar-offset-parent') === true) {
  422.                         parentOffsetLeft = tempParentOffsetLeft;
  423.                         parentOffsetTop = tempParentOffsetTop;
  424.                         $offsetParent = $this;
  425.  
  426.                         return false;
  427.                     } else {
  428.                         tempParentOffsetLeft += $this.position().left;
  429.                         tempParentOffsetTop += $this.position().top;
  430.                     }
  431.                 });
  432.  
  433.                 // Detect the offsets
  434.                 horizontalOffset = ($this.data('stellar-horizontal-offset') !== undefined ? $this.data('stellar-horizontal-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-horizontal-offset') !== undefined ? $offsetParent.data('stellar-horizontal-offset') : self.horizontalOffset));
  435.                 verticalOffset = ($this.data('stellar-vertical-offset') !== undefined ? $this.data('stellar-vertical-offset') : ($offsetParent !== undefined && $offsetParent.data('stellar-vertical-offset') !== undefined ? $offsetParent.data('stellar-vertical-offset') : self.verticalOffset));
  436.  
  437.                 self.backgrounds.push({
  438.                     $element: $this,
  439.                     $offsetParent: $offsetParent,
  440.                     isFixed: $this.css('background-attachment') === 'fixed',
  441.                     horizontalOffset: horizontalOffset,
  442.                     verticalOffset: verticalOffset,
  443.                     startingValueLeft: backgroundPosition[0],
  444.                     startingValueTop: backgroundPosition[1],
  445.                     startingBackgroundPositionLeft: (isNaN(parseInt(backgroundPosition[0], 10)) ? 0 : parseInt(backgroundPosition[0], 10)),
  446.                     startingBackgroundPositionTop: (isNaN(parseInt(backgroundPosition[1], 10)) ? 0 : parseInt(backgroundPosition[1], 10)),
  447.                     startingPositionLeft: $this.position().left,
  448.                     startingPositionTop: $this.position().top,
  449.                     startingOffsetLeft: offsetLeft,
  450.                     startingOffsetTop: offsetTop,
  451.                     parentOffsetLeft: parentOffsetLeft,
  452.                     parentOffsetTop: parentOffsetTop,
  453.                     stellarRatio: ($this.data('stellar-background-ratio') === undefined ? 1 : $this.data('stellar-background-ratio'))
  454.                 });
  455.             });
  456.         },
  457.         _reset: function() {
  458.             var particle,
  459.                 startingPositionLeft,
  460.                 startingPositionTop,
  461.                 background,
  462.                 i;
  463.  
  464.             for (i = this.particles.length - 1; i >= 0; i--) {
  465.                 particle = this.particles[i];
  466.                 startingPositionLeft = particle.$element.data('stellar-startingLeft');
  467.                 startingPositionTop = particle.$element.data('stellar-startingTop');
  468.  
  469.                 this._setPosition(particle.$element, startingPositionLeft, startingPositionLeft, startingPositionTop, startingPositionTop);
  470.  
  471.                 this.options.showElement(particle.$element);
  472.  
  473.                 particle.$element.data('stellar-startingLeft', null).data('stellar-elementIsActive', null).data('stellar-backgroundIsActive', null);
  474.             }
  475.  
  476.             for (i = this.backgrounds.length - 1; i >= 0; i--) {
  477.                 background = this.backgrounds[i];
  478.  
  479.                 background.$element.data('stellar-backgroundStartingLeft', null).data('stellar-backgroundStartingTop', null);
  480.  
  481.                 setBackgroundPosition(background.$element, background.startingValueLeft, background.startingValueTop);
  482.             }
  483.         },
  484.         destroy: function() {
  485.             this._reset();
  486.  
  487.             this.$scrollElement.off('resize.' + this.name).off('scroll.' + this.name);
  488.             this._animationLoop = $.noop;
  489.  
  490.             $(window).off("load." + this.name).off('resize.' + this.name);
  491.         },
  492.         _setOffsets: function() {
  493.             var self = this,
  494.                 $window = $(window);
  495.  
  496.             $window.off('resize.horizontal-' + this.name).off('resize.vertical-' + this.name);
  497.  
  498.             if (typeof this.options.horizontalOffset === 'function') {
  499.                 this.horizontalOffset = this.options.horizontalOffset();
  500.                 $window.on('resize.horizontal-' + this.name, function() {
  501.                     self.horizontalOffset = self.options.horizontalOffset();
  502.                 });
  503.             } else {
  504.                 this.horizontalOffset = this.options.horizontalOffset;
  505.             }
  506.  
  507.             if (typeof this.options.verticalOffset === 'function') {
  508.                 this.verticalOffset = this.options.verticalOffset();
  509.                 $window.on('resize.vertical-' + this.name, function() {
  510.                     self.verticalOffset = self.options.verticalOffset();
  511.                 });
  512.             } else {
  513.                 this.verticalOffset = this.options.verticalOffset;
  514.             }
  515.         },
  516.         _repositionElements: function() {
  517.             var scrollLeft = this._getScrollLeft(),
  518.                 scrollTop = this._getScrollTop(),
  519.                 horizontalOffset,
  520.                 verticalOffset,
  521.                 particle,
  522.                 fixedRatioOffset,
  523.                 background,
  524.                 bgLeft,
  525.                 bgTop,
  526.                 isVisibleVertical = true,
  527.                 isVisibleHorizontal = true,
  528.                 newPositionLeft,
  529.                 newPositionTop,
  530.                 newOffsetLeft,
  531.                 newOffsetTop,
  532.                 i;
  533.  
  534.             // First check that the scroll position or container size has changed
  535.             if (this.currentScrollLeft === scrollLeft && this.currentScrollTop === scrollTop && this.currentWidth === this.viewportWidth && this.currentHeight === this.viewportHeight) {
  536.                 return;
  537.             } else {
  538.                 this.currentScrollLeft = scrollLeft;
  539.                 this.currentScrollTop = scrollTop;
  540.                 this.currentWidth = this.viewportWidth;
  541.                 this.currentHeight = this.viewportHeight;
  542.             }
  543.  
  544.             // Reposition elements
  545.             for (i = this.particles.length - 1; i >= 0; i--) {
  546.                 particle = this.particles[i];
  547.  
  548.                 fixedRatioOffset = (particle.isFixed ? 1 : 0);
  549.  
  550.                 // Calculate position, then calculate what the particle's new offset will be (for visibility check)
  551.                 if (this.options.horizontalScrolling) {
  552.                     newPositionLeft = (scrollLeft + particle.horizontalOffset + this.viewportOffsetLeft + particle.startingPositionLeft - particle.startingOffsetLeft + particle.parentOffsetLeft) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionLeft;
  553.                     newOffsetLeft = newPositionLeft - particle.startingPositionLeft + particle.startingOffsetLeft;
  554.                 } else {
  555.                     newPositionLeft = particle.startingPositionLeft;
  556.                     newOffsetLeft = particle.startingOffsetLeft;
  557.                 }
  558.  
  559.                 if (this.options.verticalScrolling) {
  560.                     newPositionTop = (scrollTop + particle.verticalOffset + this.viewportOffsetTop + particle.startingPositionTop - particle.startingOffsetTop + particle.parentOffsetTop) * -(particle.stellarRatio + fixedRatioOffset - 1) + particle.startingPositionTop;
  561.                     newOffsetTop = newPositionTop - particle.startingPositionTop + particle.startingOffsetTop;
  562.                 } else {
  563.                     newPositionTop = particle.startingPositionTop;
  564.                     newOffsetTop = particle.startingOffsetTop;
  565.                 }
  566.  
  567.                 // Check visibility
  568.                 if (this.options.hideDistantElements) {
  569.                     isVisibleHorizontal = !this.options.horizontalScrolling || newOffsetLeft + particle.width > (particle.isFixed ? 0 : scrollLeft) && newOffsetLeft < (particle.isFixed ? 0 : scrollLeft) + this.viewportWidth + this.viewportOffsetLeft;
  570.                     isVisibleVertical = !this.options.verticalScrolling || newOffsetTop + particle.height > (particle.isFixed ? 0 : scrollTop) && newOffsetTop < (particle.isFixed ? 0 : scrollTop) + this.viewportHeight + this.viewportOffsetTop;
  571.                 }
  572.  
  573.                 if (isVisibleHorizontal && isVisibleVertical) {
  574.                     if (particle.isHidden) {
  575.                         this.options.showElement(particle.$element);
  576.                         particle.isHidden = false;
  577.                     }
  578.  
  579.                     this._setPosition(particle.$element, newPositionLeft, particle.startingPositionLeft, newPositionTop, particle.startingPositionTop);
  580.                 } else {
  581.                     if (!particle.isHidden) {
  582.                         this.options.hideElement(particle.$element);
  583.                         particle.isHidden = true;
  584.                     }
  585.                 }
  586.             }
  587.  
  588.             // Reposition backgrounds
  589.             for (i = this.backgrounds.length - 1; i >= 0; i--) {
  590.                 background = this.backgrounds[i];
  591.  
  592.                 fixedRatioOffset = (background.isFixed ? 0 : 1);
  593.                 bgLeft = (this.options.horizontalScrolling ? (scrollLeft + background.horizontalOffset - this.viewportOffsetLeft - background.startingOffsetLeft + background.parentOffsetLeft - background.startingBackgroundPositionLeft) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueLeft);
  594.                 bgTop = (this.options.verticalScrolling ? (scrollTop + background.verticalOffset - this.viewportOffsetTop - background.startingOffsetTop + background.parentOffsetTop - background.startingBackgroundPositionTop) * (fixedRatioOffset - background.stellarRatio) + 'px' : background.startingValueTop);
  595.  
  596.                 setBackgroundPosition(background.$element, bgLeft, bgTop);
  597.             }
  598.         },
  599.         _handleScrollEvent: function() {
  600.             var self = this,
  601.                 ticking = false;
  602.  
  603.             var update = function() {
  604.                 self._repositionElements();
  605.                 ticking = false;
  606.             };
  607.  
  608.             var requestTick = function() {
  609.                 if (!ticking) {
  610.                     requestAnimFrame(update);
  611.                     ticking = true;
  612.                 }
  613.             };
  614.            
  615.             this.$scrollElement.on('scroll.' + this.name, requestTick);
  616.             requestTick();
  617.         },
  618.         _startAnimationLoop: function() {
  619.             var self = this;
  620.  
  621.             this._animationLoop = function() {
  622.                 requestAnimFrame(self._animationLoop);
  623.                 self._repositionElements();
  624.             };
  625.             this._animationLoop();
  626.         }
  627.     };
  628.  
  629.     $.fn[pluginName] = function (options) {
  630.         var args = arguments;
  631.         if (options === undefined || typeof options === 'object') {
  632.             return this.each(function () {
  633.                 if (!$.data(this, 'plugin_' + pluginName)) {
  634.                     $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
  635.                 }
  636.             });
  637.         } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {
  638.             return this.each(function () {
  639.                 var instance = $.data(this, 'plugin_' + pluginName);
  640.                 if (instance instanceof Plugin && typeof instance[options] === 'function') {
  641.                     instance[options].apply(instance, Array.prototype.slice.call(args, 1));
  642.                 }
  643.                 if (options === 'destroy') {
  644.                     $.data(this, 'plugin_' + pluginName, null);
  645.                 }
  646.             });
  647.         }
  648.     };
  649.  
  650.     $[pluginName] = function(options) {
  651.         var $window = $(window);
  652.         return $window.stellar.apply($window, Array.prototype.slice.call(arguments, 0));
  653.     };
  654.  
  655.     // Expose the scroll and position property function hashes so they can be extended
  656.     $[pluginName].scrollProperty = scrollProperty;
  657.     $[pluginName].positionProperty = positionProperty;
  658.  
  659.     // Expose the plugin class so it can be modified
  660.     window.Stellar = Plugin;
  661. }(jQuery, this, document));
Add Comment
Please, Sign In to add comment