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