PageSourceSearch

https://www.rosenbaumcontemporary.com/lib/jquery/plugins/parallax/…=3a12eec&g=1a86e7b5d8da497779872c662581cf7c

js rosenbaumcontemporary.com collected 2026-10-02 12:59:42 UTC 17,997 bytes, 502 lines download raw bytes

1/*!
2 * Artlogic Parallax
3 * This file is heavily edited to work primarily with parallax on template and gallery sites
4 * This will only work with one parallax instance on each page, but is modified to accept slideshows and other elements in addition to just a single image within the parallax area
5 * To use the original functionality of parallax.js, please use parallax.original.js located in the same folder.
6 *
7 * parallax.js v1.3.1 (http://pixelcog.github.io/parallax.js/)
8 * @copyright 2015 PixelCog, Inc.
9 * @license MIT (https://github.com/pixelcog/parallax.js/blob/master/LICENSE)
10 */
11
12parallax_init_callback = function() {};
13parallax_resize_callback = function() {};
14
15(function ( $, window, document, undefined ) {
16
17  // Polyfill for requestAnimationFrame
18  // via: https://gist.github.com/paulirish/1579671
19
20    (function() {
21        var lastTime = 0;
22        var vendors = ['ms', 'moz', 'webkit', 'o'];
23        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
24        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
25        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
26                                 || window[vendors[x]+'CancelRequestAnimationFrame'];
27        }
28
29        if (!window.requestAnimationFrame)
30          window.requestAnimationFrame = function(callback) {
31            var currTime = new Date().getTime();
32            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
33            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
34              timeToCall);
35            lastTime = currTime + timeToCall;
36            return id;
37          };
38
39        if (!window.cancelAnimationFrame)
40          window.cancelAnimationFrame = function(id) {
41            clearTimeout(id);
42          };
43    }());
44
45  // Parallax Constructor
46
47    function Parallax(element, options) {
48        var self = this;
49
50        if (typeof options == 'object') {
51            delete options.refresh;
52            delete options.render;
53            $.extend(this, options);
54        }
55
56        this.$element = $(element);
57
58        this.id = '';
59        if (this.$element.attr('id')) {
60            this.id = 'parallax-' + this.$element.attr('id');
61        }
62        this.color = '#000000';
63        if (this.$element.attr('data-color')) {
64            this.color = this.$element.attr('data-color');
65        }
66        this.opacity = '1';
67        if (this.$element.attr('data-opacity')) {
68          this.opacity = this.$element.attr('data-opacity');
69        }
70
71        if (!this.imageSrc && this.$element.is('img')) {
72            this.imageSrc = this.$element.attr('src');
73        }
74
75        var positions = (this.position + '').toLowerCase().match(/\S+/g) || [];
76
77        if (positions.length < 1) {
78            positions.push('center');
79        }
80        if (positions.length == 1) {
81            positions.push(positions[0]);
82        }
83
84        if (positions[0] == 'top' || positions[0] == 'bottom' || positions[1] == 'left' || positions[1] == 'right') {
85            positions = [positions[1], positions[0]];
86        }
87
88        if (this.positionX != undefined) positions[0] = this.positionX.toLowerCase();
89        if (this.positionY != undefined) positions[1] = this.positionY.toLowerCase();
90
91        self.positionX = positions[0];
92        self.positionY = positions[1];
93
94        if (this.positionX != 'left' && this.positionX != 'right') {
95            if (isNaN(parseInt(this.positionX))) {
96                this.positionX = 'center';
97            } else {
98                this.positionX = parseInt(this.positionX);
99            }
100        }
101
102        if (this.positionY != 'top' && this.positionY != 'bottom') {
103            if (isNaN(parseInt(this.positionY))) {
104                this.positionY = 'center';
105            } else {
106                this.positionY = parseInt(this.positionY);
107            }
108        }
109
110        this.position =
111        this.positionX + (isNaN(this.positionX)? '' : 'px') + ' ' +
112        this.positionY + (isNaN(this.positionY)? '' : 'px');
113
114        if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
115            if (false && this.iosFix && !this.$element.is('img')) {
116                this.$element.css({
117                    backgroundImage: 'url(' + this.imageSrc + ')',
118                    backgroundSize: 'cover',
119                    backgroundPosition: this.position
120                });
121                return this;
122            }
123        }
124
125        if (navigator.userAgent.match(/(Android)/)) {
126            if (false && this.androidFix && !this.$element.is('img')) {
127                this.$element.css({
128                    backgroundImage: 'url(' + this.imageSrc + ')',
129                    backgroundSize: 'cover',
130                    backgroundPosition: this.position
131                });
132                return this;
133            }
134        }
135
136        this.$mirror = $('<div />').prependTo('body');
137        this.$slider = $('<img />').prependTo(this.$mirror);
138
139        this.$mirror.addClass('parallax-mirror').attr({id: this.id, role: "complementary"}).css({
140            visibility: 'hidden',
141            zIndex: this.zIndex,
142            position: 'fixed',
143            top: 0,
144            left: 0,
145            overflow: 'hidden',
146            background: this.color
147        });
148        
149        this.$slider.fadeTo(0, this.opacity).addClass('parallax-slider').attr('alt', 'Placeholder image').one('load', function() {
150            if (!self.naturalHeight || !self.naturalWidth) {
151                self.naturalHeight = this.naturalHeight || this.height || 1;
152                self.naturalWidth  = this.naturalWidth  || this.width  || 1;
153            }
154            self.aspectRatio = self.naturalWidth / self.naturalHeight;
155
156            Parallax.isSetup || Parallax.setup();
157            Parallax.sliders.push(self);
158            Parallax.isFresh = false;
159            Parallax.requestRender();
160        });
161
162        this.$slider[0].src = this.imageSrc;
163
164        if (this.naturalHeight && this.naturalWidth || this.$slider[0].complete) {
165        this.$slider.trigger('load');
166        }
167
168    };
169
170
171  // Parallax Instance Methods
172
173  $.extend(Parallax.prototype, {
174    speed:    0.2,
175    bleed:    0,
176    zIndex:   0,
177    iosFix:   true,
178    androidFix: true,
179    position: 'center',
180    overScrollFix: false,
181
182    refresh: function() {
183      if (this.$element.hasClass('parallax-loaded')) {
184          var element_display_status = this.$element.css('display');
185          this.$element.css('display', 'block');
186      }
187
188      this.cmsToolbarHeight = $('#cms-frontend-toolbar-container').height();
189      this.originalElementOffsetTop = this.$element.offset().top;
190      this.boxWidth        = this.$element.outerWidth();
191      this.boxHeight       = this.$element.outerHeight() + this.bleed * 2; // previously this.$element.outerHeight() + this.bleed * 2 + this.$element.offset().top - this.bleed
192      this.boxOffsetTop    = this.$element.offset().top - this.bleed; // previously 0
193      this.boxOffsetLeft   = this.$element.offset().left;
194      this.boxOffsetBottom = this.boxOffsetTop + this.boxHeight;
195
196      var winHeight = Parallax.winHeight;
197      var docHeight = Parallax.docHeight;
198      var maxOffset = Math.min(this.boxOffsetTop, docHeight - winHeight);
199      var minOffset = Math.max(this.boxOffsetTop + this.boxHeight - winHeight, 0);
200      var imageHeightMin = this.boxHeight + (maxOffset - minOffset) * (1 - this.speed) | 0;
201      var imageOffsetMin = (this.boxOffsetTop - maxOffset) * (1 - this.speed) | 0;
202
203      if (imageHeightMin * this.aspectRatio >= this.boxWidth) {
204        this.imageWidth    = imageHeightMin * this.aspectRatio | 0;
205        this.imageHeight   = imageHeightMin;
206        this.offsetBaseTop = imageOffsetMin;
207
208        var margin = this.imageWidth - this.boxWidth;
209
210        if (this.positionX == 'left') {
211          this.offsetLeft = 0;
212        } else if (this.positionX == 'right') {
213          this.offsetLeft = - margin;
214        } else if (!isNaN(this.positionX)) {
215          this.offsetLeft = Math.max(this.positionX, - margin);
216        } else {
217          this.offsetLeft = - margin / 2 | 0;
218        }
219      } else {
220        this.imageWidth    = this.boxWidth;
221        this.imageHeight   = this.boxWidth / this.aspectRatio | 0;
222        this.offsetLeft    = 0;
223
224        var margin = this.imageHeight - imageHeightMin;
225
226        if (this.positionY == 'top') {
227          this.offsetBaseTop = imageOffsetMin;
228        } else if (this.positionY == 'bottom') {
229          this.offsetBaseTop = imageOffsetMin - margin;
230        } else if (!isNaN(this.positionY)) {
231          this.offsetBaseTop = imageOffsetMin + Math.max(this.positionY, - margin);
232        } else {
233          this.offsetBaseTop = imageOffsetMin - margin / 2 | 0;
234        }
235      }
236
237      if (this.$element.hasClass('parallax-loaded')) {
238        this.$element.css('display', '');
239      }
240      
241      var scrollTop = Parallax.scrollTop;
242      var mirrorTop = this.boxOffsetTop;
243      this.originalOffsetTop = this.offsetBaseTop - mirrorTop * (1 - this.speed);
244    },
245
246    render: function() {
247      var scrollTop    = Parallax.scrollTop;
248      var scrollLeft   = Parallax.scrollLeft;
249      var overScroll   = this.overScrollFix ? Parallax.overScroll : 0;
250      var scrollBottom = scrollTop + Parallax.winHeight;
251
252      //console.log('2222#########################');
253      //console.log('boxOffsetBottom ' + this.boxOffsetBottom);
254      //console.log('scrollTop ' + this.scrollTop);
255      //console.log('boxOffsetTop ' + this.boxOffsetTop);
256      //console.log('scrollBottom ' + this.scrollBottom);
257      
258      //console.log(this.boxOffsetBottom > scrollTop && this.boxOffsetTop < scrollBottom);
259
260      if (this.boxOffsetBottom > scrollTop && this.boxOffsetTop < scrollBottom) {
261        //console.log('visible');
262        this.visibility = 'visible';
263          this.mirrorTop = this.boxOffsetTop  - scrollTop;
264          this.mirrorLeft = this.boxOffsetLeft - scrollLeft;
265          this.offsetTop = this.offsetBaseTop - this.mirrorTop * (1 - this.speed);
266
267          this.slideshowOffsetTop = 0 - this.mirrorTop * (1 - this.speed);
268          this.$mirror.css({
269            transform: 'translate3d(0px, 0px, 0px)',
270            visibility: this.visibility,
271            top: this.mirrorTop - overScroll,
272            left: this.mirrorLeft,
273            height: this.boxHeight,
274            width: this.boxWidth
275          });
276      } else {
277        //console.log('hidden');
278        this.visibility = 'hidden';
279        this.$mirror.css({
280            visibility: this.visibility
281        });
282      }
283
284      var parallax_before_load = this.visibility == 'visible' && !$(this.$element).hasClass('parallax-loaded');
285      
286      if (parallax_before_load) {
287          $(this.$element).addClass('parallax-loaded');
288          if ($(this.$element).find('.hero-parallax-element').length) {
289              var element_id = $(this.$element).find('.hero-parallax-element').parent().attr('id');
290              var original_element_class = (typeof $(this.$element).find('.hero-parallax-element').parent().attr('class') != 'undefined' ? $(this.$element).find('.hero-parallax-element').parent().attr('class') : '');
291              if (element_id == 'slideshow' || element_id == 'hero_parallax_content') {
292                  this.$slider.css({
293                    opacity: 0
294                  });
295                  this.$mirror.append('<div id="mirror-' + element_id + '" class="hero-parallax-element-mirror ' + original_element_class + '" style="opacity:' + this.opacity + ';">' + $(this.$element).find('.hero-parallax-element').parent().html() + '</div>');
296                  this.$mirror.find('.hero-parallax-element').removeClass('hero-parallax-element');
297                  this.$mirror.find('.fullscreen_slideshow_video').remove();
298                  if (element_id == 'slideshow') {
299                    window.galleries.slideshow.init();
300                  }
301              }
302          }
303      }
304
305      if (this.$mirror.find('.hero-parallax-element-mirror').length) {
306          var mirror_element_height = this.imageHeight;
307
308          var mirror_container_height = this.$mirror.height();
309          var mirror_element_height = mirror_container_height + this.$mirror.offset().top;
310          if (mirror_element_height > $(window).height()) {
311                var mirror_element_height = $(window).height()
312          }
313          
314          //if (this.boxHeight > this.imageHeight) {
315          //    var mirror_element_height = this.boxHeight;
316          //}
317          this.$mirror.find('.hero-parallax-element-mirror').css({
318            transform: 'translate3d(0px, 0px, 0px)',
319            top: this.slideshowOffsetTop,
320            height: mirror_element_height
321            //height: this.boxHeight - this.originalOffsetTop
322          });
323          this.$slider.css({
324            opacity: 0
325          });
326      } else {
327          this.$slider.css({
328            transform: 'translate3d(0px, 0px, 0px)',
329            position: 'absolute',
330            top: this.offsetTop,
331            left: this.offsetLeft,
332            height: this.imageHeight,
333            width: this.imageWidth,
334            maxWidth: 'none'
335          });
336      }
337
338      if (parallax_before_load) {
339          parallax_init_callback();
340      }
341
342    }
343  });
344
345
346  // Parallax Static Methods
347
348  $.extend(Parallax, {
349    scrollTop:    0,
350    scrollLeft:   0,
351    winHeight:    0,
352    winWidth:     0,
353    docHeight:    1 << 30,
354    docWidth:     1 << 30,
355    sliders:      [],
356    isReady:      false,
357    isFresh:      false,
358    isBusy:       false,
359
360    setup: function() {
361      if (this.isReady) return;
362
363      var $doc = $(document), $win = $(window);
364
365      $win.on('scroll.px.parallax load.px.parallax', function() {
366          var scrollTopMax  = Parallax.docHeight - Parallax.winHeight;
367          var scrollLeftMax = Parallax.docWidth  - Parallax.winWidth;
368          Parallax.scrollTop  = $win.scrollTop();
369          // Removed the 'maximum' rule for scrolltop, this would cause problems if the height increased on a very short page:
370          //    Parallax.scrollTop  = Math.max(0, Math.min(scrollTopMax,  $win.scrollTop()));
371          Parallax.scrollLeft = Math.max(0, Math.min(scrollLeftMax, $win.scrollLeft()));
372          Parallax.overScroll = Math.max($win.scrollTop() - scrollTopMax, Math.min($win.scrollTop(), 0));
373          Parallax.requestRender();
374        })
375        .on('resize.px.parallax load.px.parallax', function() {
376          Parallax.winHeight = $win.height();
377          Parallax.winWidth  = $win.width();
378          Parallax.docHeight = $doc.height();
379          Parallax.docWidth  = $doc.width();
380          Parallax.isFresh = false;
381          Parallax.requestRender();
382          parallax_resize_callback();
383        });
384
385      this.isReady = true;
386
387      $(window).trigger('resize.px.parallax');
388    },
389
390    configure: function(options) {
391      if (typeof options == 'object') {
392        delete options.refresh;
393        delete options.render;
394        $.extend(this.prototype, options);
395      }
396    },
397
398    refresh: function() {
399      $.each(this.sliders, function(){this.refresh()});
400      this.isFresh = true;
401    },
402
403    render: function() {
404        this.isFresh || this.refresh();
405      $.each(this.sliders, function(){this.render()});
406    },
407
408    requestRender: function() {
409      var self = this;
410
411      if (!this.isBusy) {
412        this.isBusy = true;
413        window.requestAnimationFrame(function() {
414
415          self.render();
416          self.isBusy = false;
417        });
418      }
419    },
420    
421    destroy: function(){
422        Parallax.sliders = []
423        this.isReady = false;
424        // delete Parallax
425        $('body').addClass('parallax-destroyed');
426        $('.parallax-mirror').each(function() {
427            $(this).remove();
428        });
429    }
430  });
431
432
433
434    function ParallaxDestroy(element, options) {}
435
436
437  // Parallax Plugin Definition
438  function Plugin(option) {
439    return this.each(function () {
440      var $this = $(this);
441      var options = typeof option == 'object' && option;
442
443      if (this == window || this == document || $this.is('body')) {
444        Parallax.configure(options);
445      }
446      else if (!$this.data('px.parallax')) {
447        options = $.extend({}, $this.data(), options);
448        $this.data('px.parallax', new Parallax(this, options));
449      }else if($('body').hasClass('parallax-destroyed')){
450        options = $.extend({}, $this.data(), options);
451        $this.data('px.parallax', new Parallax(this, options));
452        $('body').removeClass('parallax-destroyed')
453      }
454      if (typeof option == 'string') {
455        Parallax[option]();
456      }
457    })
458  };
459
460  var old = $.fn.parallax;
461
462  $.fn.parallax             = Plugin;
463  $.fn.parallax.Constructor = Parallax;
464  $.fn.parallax.destroy      = Parallax.destroy;
465  $.fn.parallax.setup      = Parallax.setup;
466  //$.fn.parallax_destroy     = ParallaxDestroy;
467
468
469  // Parallax No Conflict
470
471  $.fn.parallax.noConflict = function () {
472    $.fn.parallax = old;
473    return this;
474  };
475
476
477  // Parallax Data-API
478
479  $(document).on('ready.px.parallax.data-api', function () {
480      $('[data-parallax="scroll"]').parallax();
481  });
482  
483  window.onbeforeunload = function() {
484    if (!$('body').hasClass('cms-frontend-toolbar-fallback-mode')) {
485        // Stop mousewheel when navigating away from the page
486        // mousewheel on OSX allows users to scroll on Chrome even when jquery events do not fire
487        $('body').bind("mousewheel.parallax", function() {
488            return false;
489        });
490        // Remove mousewheel event after set amount of time
491        window.setTimeout(function() {
492            $('body').unbind("mousewheel.parallax");
493        }, 5000);
494    }
495    //$('.parallax-mirror').fadeOut(150);
496    //$('body').addClass('device-handheld');
497    //$('.parallax-loaded').removeClass('.parallax-loaded');
498    //$('.hero-parallax-element').removeClass('hero-parallax-element');
499    //$('body').css('overflow', 'hidden');
500  }
501
502}(jQuery, window, document));

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.