PageSourceSearch

https://www.untouch.de/shop/gm_javascript.js.php?cPath=1&products_…=ProductInfo&current_template=Honeygrid

js untouch.de collected 2026-09-24 14:02:19 UTC 11,185 bytes, 373 lines download raw bytes

1
2/**
3 * SmoothParallax 1.1.2
4 * 
5 * File smooth-parallax.js.
6 *
7 * Yet another parallax script. Smooth parallax is intended to make it a lot easier to
8 * make objects move vertically or horizontally when scroll, being it images,
9 * divs or what-have-you. Use this script to add background or foreground parallax
10 * effect to your website.
11 *
12 * Website: https://diegoversiani.me/smooth-parallax
13 * Github: https://github.com/diegoversiani/smooth-parallax
14 *
15 * Author: Diego Versiani
16 * Contact: https://diegoversiani.me/
17 * 
18 * Based on the work of:
19 * Rachel Smith: https://codepen.io/rachsmith/post/how-to-move-elements-on-scroll-in-a-way-that-doesn-t-suck-too-bad
20 */
21(function (root, factory) {
22  if ( typeof define === 'function' && define.amd ) {
23    define([], factory(root));
24  } else if ( typeof exports === 'object' ) {
25    module.exports = factory(root);
26  } else {
27    root.SmoothParallax = factory(root);
28  }
29})(typeof global !== 'undefined' ? global : this.window || this.global, function (root) {
30
31  'use strict';
32
33  //
34  // Variables
35  //
36
37  var window = root; // Map window to root to avoid confusion
38  var _container;
39  var _width, _height, _scrollHeight, _viewPortHeight;
40  var _scrollPercent = 0;
41  var _scrollOffset = 0;
42  var _movingElements = [];
43  var _positions = [];
44  var _basePercentageOnOptions = [ 'containerVisibility', 'pageScroll' ];
45  var _settings;
46  var publicMethods = {}; // Placeholder for public methods
47
48  // Default settings
49  var defaults = {
50    basePercentageOn: 'containerVisibility', // See `_basePercentageOnOptions` for more options
51    decimalPrecision: 2
52  };
53
54
55  //
56  // Methods
57  //
58
59  /**
60   * Merge two or more objects. Returns a new object.
61   * @private
62   * @param {Boolean}  deep     If true, do a deep (or recursive) merge [optional]
63   * @param {Object}   objects  The objects to merge together
64   * @returns {Object}          Merged values of defaults and options
65   */
66  var extend = function () {
67    // Variables
68    var extended = {};
69    var deep = false;
70    var i = 0;
71    var length = arguments.length;
72
73    // Check if a deep merge
74    if ( Object.prototype.toString.call( arguments[0] ) === '[object Boolean]' ) {
75      deep = arguments[0];
76      i++;
77    }
78
79    // Merge the object into the extended object
80    var merge = function (obj) {
81      for ( var prop in obj ) {
82        if ( Object.prototype.hasOwnProperty.call( obj, prop ) ) {
83          // If deep merge and property is an object, merge properties
84          if ( deep && Object.prototype.toString.call(obj[prop]) === '[object Object]' ) {
85            extended[prop] = extend( true, extended[prop], obj[prop] );
86          } else {
87            extended[prop] = obj[prop];
88          }
89        }
90      }
91    };
92
93    // Loop through each object and conduct a merge
94    for ( ; i < length; i++ ) {
95      var obj = arguments[i];
96      merge(obj);
97    }
98
99    return extended;
100  };
101
102
103
104  /**
105   * Get movable element container
106   * @private
107   */
108  var getElementContainer = function ( element ) {
109    var containerSelector = element.getAttribute( 'container' );
110    _container = element.parentNode;
111
112    if ( containerSelector != '' && document.querySelector( containerSelector ) ) {
113      _container = document.querySelector( containerSelector );
114    }
115
116    return _container;
117  };
118
119
120
121  /**
122   * Calculate page percent scrolled.
123   * @private
124   */
125  var calculatePageScrollPercent = function () {
126    var documentElement = document.documentElement || document.body;
127    _height = documentElement.scrollHeight;
128    _scrollOffset = window.pageYOffset || documentElement.scrollTop;
129    return _scrollOffset / ( _height - documentElement.clientHeight );
130  };
131
132
133
134  /**
135   * Calculate variables used to determine elements position
136   * @private
137   */
138  var calculatePercent = function ( positionData ) {
139    _viewPortHeight = window.innerHeight;
140
141    // Based on `containerVisibility`
142    if ( _settings.basePercentageOn == 'containerVisibility' ) {  
143      _height = positionData.container.scrollHeight;
144      _scrollOffset = _viewPortHeight - positionData.container.getBoundingClientRect().top;
145      _scrollPercent = _scrollOffset / _height;
146    }
147
148    // Based on `pageScroll`
149    if ( _settings.basePercentageOn == 'pageScroll' ) {
150      _scrollPercent = calculatePageScrollPercent();
151    }
152
153    // Normalize scrollPercentage from 0 to 1
154    if ( _scrollPercent < 0 ) {
155      _scrollPercent = 0;
156    }
157    else if ( _scrollPercent > 1 ) {
158      _scrollPercent = 1;
159    }
160  };
161
162
163
164  /**
165   * Get position data object for the element.
166   * @returns {Object} Position data object for element or false if not found.
167   */
168  var getPositionDataByElement = function ( el ) {
169    for (var i = 0; i < _positions.length; i++) {
170      if ( _positions[i].element == el ) {
171        return _positions[i];
172      }
173    }
174    
175    // Return false if not found
176    return false;
177  }
178
179
180
181  /**
182   * Initializes positions for each moving element.
183   * @private
184   */
185  var initializeMovingElementsPosition = function () {
186    var startPercent,
187        startX,
188        startY,
189        endPercent,
190        endX,
191        endY,
192        baseSizeOn,
193        baseSizeOnOptions = [ 'elementsize', 'containerSize' ];
194
195    _movingElements = document.querySelectorAll('[smooth-parallax]');
196
197    for (var i = 0; i < _movingElements.length; i++) {
198      startPercent = parseFloat(_movingElements[i].getAttribute( 'start-movement' )) || 0;
199      startX = parseFloat(_movingElements[i].getAttribute( 'start-position-x' )) || 0;
200      startY = parseFloat(_movingElements[i].getAttribute( 'start-position-y' )) || 0;
201      endPercent = parseFloat(_movingElements[i].getAttribute( 'end-movement' )) || 1;
202      endX = parseFloat(_movingElements[i].getAttribute( 'end-position-x' )) || 0;
203      endY = parseFloat(_movingElements[i].getAttribute( 'end-position-y' )) || 0;
204      baseSizeOn = _movingElements[i].getAttribute( 'base-size' );
205
206      if ( baseSizeOnOptions.indexOf( baseSizeOn ) == -1 ) {
207        baseSizeOn = 'elementSize'; // Default value
208      }
209
210      var elementPosition = {
211        element: _movingElements[i],
212        container: getElementContainer( _movingElements[i] ),
213        baseSizeOn: baseSizeOn,
214        start: {
215          percent: startPercent,
216          x: startX,
217          y: startY
218        },
219        end: {
220          percent: endPercent,
221          x: endX,
222          y: endY
223        },
224        diff: {
225          percent: endPercent - startPercent,
226          x: endX - startX,
227          y: endY - startY,
228        },
229        target: {},
230        current: {}
231      };
232
233      _positions.push( elementPosition );
234    }
235  };
236
237  /**
238   * Updates moving elements position.
239   * @private
240   */
241  var updateElementsPosition = function () {
242    for (var i = 0; i < _movingElements.length; i++) {
243      var p = _positions[i],
244          baseWidth,
245          baseHeight,
246          transformValue;
247
248      // Try get element's size with `scrollWidth` and `scrollHeight`
249      // otherwise use `getComputedStyle` which is more expensive
250      if ( p.baseSizeOn == 'elementSize' ) {
251        baseWidth = _movingElements[i].scrollWidth || parseFloat( window.getComputedStyle( _movingElements[i] ).width );
252        baseHeight = _movingElements[i].scrollHeight || parseFloat( window.getComputedStyle( _movingElements[i] ).height );
253      }
254      else if ( p.baseSizeOn == 'containerSize' ) {
255        baseWidth = p.container.scrollWidth - (_movingElements[i].scrollWidth || parseFloat( window.getComputedStyle( _movingElements[i] ).width ) );
256        baseHeight = p.container.scrollHeight - (_movingElements[i].scrollHeight  || parseFloat( window.getComputedStyle( _movingElements[i] ).height ) );
257      }
258
259      // Need to calculate percentage for each element
260      // when based on `containerVisibility`
261      calculatePercent( p );
262      
263      // calculate target position
264      if(_scrollPercent <= p.start.percent) {
265        p.target.x = p.start.x * baseWidth;
266        p.target.y = p.start.y * baseHeight;
267      }
268      else if(_scrollPercent >= p.end.percent) {
269        p.target.x = p.end.x * baseWidth;
270        p.target.y = p.end.y * baseHeight;
271      }
272      else {
273        p.target.x = p.start.x * baseWidth + ( p.diff.x * ( _scrollPercent - p.start.percent ) / p.diff.percent * baseWidth );
274        p.target.y = p.start.y * baseHeight + ( p.diff.y * ( _scrollPercent - p.start.percent ) / p.diff.percent * baseHeight );
275      }
276      
277      // easing with linear interpolation
278      if( !p.current.x || !p.current.y) {
279        p.current.x = p.target.x;
280        p.current.y = p.target.y;
281      } else {
282        p.current.x = p.current.x + (p.target.x - p.current.x) * 0.1;
283        p.current.y = p.current.y + (p.target.y - p.current.y) * 0.1;
284      }
285
286      // Round to decimal precision to prevent
287      // too many calculation trips
288      p.current.x = parseFloat( p.current.x.toFixed( _settings.decimalPrecision ) );
289      p.current.y = parseFloat( p.current.y.toFixed( _settings.decimalPrecision ) );
290
291      // update element style
292      _movingElements[i].style.transform = 'translate3d(' + p.current.x + 'px, ' + p.current.y + 'px, 0)';
293    }
294  };
295
296  /**
297   * Keep updating elements position infinitelly.
298   * @private
299   */
300  var loopUpdatePositions = function () {
301    updateElementsPosition();
302    requestAnimationFrame( loopUpdatePositions );
303  };
304
305  /**
306   * Keep updating elements position infinitelly.
307   * @private
308   */
309  var isSupported = function () {
310    var supported = true;
311
312    // Test basePercentageOn settings
313    if ( _basePercentageOnOptions.indexOf( _settings.basePercentageOn ) == -1 ) {
314      supported = false;
315      console.error( 'Value not supported for setting basePercentageOn: ' + _settings.basePercentageOn );
316    }
317
318    // TODO: ADD feature test for `querySelector`
319    // TODO: ADD feature test for css property `translate3d`
320
321    return supported;
322  };
323
324  /**
325   * Initializes plugin
326   */
327  publicMethods.init = function ( options ) {
328    // Merge user options with defaults
329    _settings = extend( defaults, options || {} );
330    _settings.decimalPrecision = parseInt( _settings.decimalPrecision ) || defaults.decimalPrecision;
331
332    // Bail early if not supported
333    if ( !isSupported() ) { return; }
334
335    // Initialize variables
336    initializeMovingElementsPosition();
337    loopUpdatePositions();
338  };
339
340  /**
341   * Get scroll percentage for the element or page.
342   * @param {string} el Target element css selector.
343   * @return {float} Scroll percentage for the element or the page.
344   */
345  publicMethods.getScrollPercent = function ( selector ) {
346    // Calculate page scroll if no selector was passed
347    if ( selector == undefined ) {
348      return calculatePageScrollPercent();
349    }
350
351    // Find element
352    // Return false if not found
353    var el = document.querySelector( selector );
354    if ( el == null ) return false;
355
356    // Calculate element scroll percent
357    var positionData = getPositionDataByElement( el );
358    if ( positionData ) {
359      calculatePercent( positionData );
360      return _scrollPercent;
361    }
362
363    // Return false otherwise
364    return false;
365  };
366
367
368  //
369  // Public APIs
370  //
371  return publicMethods;
372
373});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.