PageSourceSearch

https://blog.annikids.com/wp-content/plugins/buzzy-core/shortcodes…/assets/js/plugins/curtain.js?ver=7.1.2

js annikids.com collected 2026-09-26 05:13:54 UTC 20,317 bytes, 540 lines download raw bytes

1/*
2* Curtain.js - Create an unique page transitioning system
3* ---
4* Version: 2
5* Copyright 2011, Victor Coulon (http://victorcoulon.fr)
6* Released under the MIT Licence
7*/
8
9(function ( $, window, document, undefined ) {
10
11    var pluginName = 'curtain',
12        defaults = {
13            scrollSpeed: 400,
14            bodyHeight: 0,
15            linksArray: [],
16            mobile: false,
17            scrollButtons: {},
18            controls: null,
19            curtainLinks: '.curtain-links',
20            enableKeys: true,
21            easing: 'swing',
22            disabled: false,
23            nextSlide: function() {},
24            prevSlide: function() {}
25        };
26
27    // The actual plugin constructor
28    function Plugin( element, options ) {
29        var self = this;
30
31        // Public attributes
32        this.element = element;
33        this.options = $.extend( {}, defaults, options) ;
34
35        this._defaults = defaults;
36        this._name = pluginName;
37        this._ignoreHashChange = false;
38
39        this.init();
40    }
41
42    Plugin.prototype = {
43        init: function () {
44            var self = this;
45
46            // Cache element
47            this.$element = $(this.element);
48            this.$li = $(this.element).find('>li');
49            this.$liLength = this.$li.length;
50            self.$windowHeight = $(window).height();
51            self.$elDatas = {};
52            self.$document = $(document);
53            self.$window = $(window);
54
55
56            self.webkit = (navigator.userAgent.indexOf('Chrome') > -1 || navigator.userAgent.indexOf("Safari") > -1);
57            $.msie = /msie/.test(navigator.userAgent.toLowerCase()); 
58            $.mozilla = /firefox/.test(navigator.userAgent.toLowerCase()); 
59            $.Android = (navigator.userAgent.match(/Android/i));
60            $.iPhone = ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)));
61            $.iPad = ((navigator.userAgent.match(/iPad/i)));
62            $.iOs4 = (/OS [1-4]_[0-9_]+ like Mac OS X/i.test(navigator.userAgent));
63
64            /*if($.iPhone || $.iPad || $.Android || self.options.disabled){
65                this.options.mobile = true;
66                this.$li.css({position:'relative'});
67                this.$element.find('.fixed').css({position:'absolute'});
68            }*/
69
70            if(this.options.mobile){
71               this.scrollEl =  this.$element;
72            } else if($.mozilla || $.msie) {
73                this.scrollEl = $('html');
74            } else {
75                this.scrollEl = $('body');
76            }
77
78            if(self.options.controls){
79                self.options.scrollButtons['up'] =  $(self.options.controls).find('[href="#up"]');
80                self.options.scrollButtons['down'] =  $(self.options.controls).find('[href="#down"]');
81
82                if(!$.iOs4 && ($.iPhone || $.iPad)){
83                    self.$element.css({
84                        position:'fixed',
85                        top:0,
86                        left:0,
87                        right:0,
88                        bottom:0,
89                        '-webkit-overflow-scrolling':'touch',
90                        overflow:'auto'
91                    });
92                    $(self.options.controls).css({position:'absolute'});
93                }
94            }
95
96            // When all image is loaded
97            var callbackImageLoaded = function(){
98                self.setDimensions();
99                self.$li.eq(0).addClass('current');
100
101                self.setCache();
102                
103                if(!self.options.mobile){
104                    if(self.$li.eq(1).length)
105                        self.$li.eq(1).nextAll().addClass('hidden');
106                }
107
108                self.setEvents();
109                self.setLinks();
110                self.isHashIsOnList(location.hash.substring(1));
111            };
112
113            if(self.$element.find('img').length)
114                self.imageLoaded(callbackImageLoaded);
115            else
116                callbackImageLoaded();
117
118        },
119        // Events
120        scrollToPosition: function (direction){
121            var position = null,
122                self = this;
123
124            if(self.scrollEl.is(':animated')){
125                return false;
126            }
127
128            if(direction === 'up' || direction === 'down'){
129                // Keyboard event
130                var $next = (direction === 'up') ? self.$current.prev() : self.$current.next();
131
132                // Step in the current panel ?
133                if(self.$step){
134
135                    if(!self.$current.find('.current-step').length){
136                        self.$step.eq(0).addClass('current-step');
137                    }
138                        
139                    var $nextStep = (direction === 'up') ? self.$current.find('.current-step').prev('.step') : self.$current.find('.current-step').next('.step');
140
141                    if($nextStep.length) {
142                        position = (self.options.mobile) ? $nextStep.position().top + self.$elDatas[self.$current.index()]['data-position'] : $nextStep.position().top + self.$elDatas[self.$current.index()]['data-position'];
143                    }
144                }
145
146                position = position || ((self.$elDatas[$next.index()] === undefined) ? null : self.$elDatas[$next.index()]['data-position']);
147
148                if(position !== null){
149                    self.scrollEl.animate({
150                        scrollTop: position
151                    }, self.options.scrollSpeed, self.options.easing);
152                }
153
154            } else if(direction === 'top'){
155                self.scrollEl.animate({
156                    scrollTop:0
157                }, self.options.scrollSpeed, self.options.easing);
158            } else if(direction === 'bottom'){
159                self.scrollEl.animate({
160                    scrollTop:self.options.bodyHeight
161                }, self.options.scrollSpeed, self.options.easing);
162            } else {
163                var index = $("#"+direction).index(),
164                    speed = Math.abs(self.currentIndex-index) * (this.options.scrollSpeed*4) / self.$liLength;
165
166                self.scrollEl.animate({
167                    scrollTop:self.$elDatas[index]['data-position'] || null
168                }, (speed <= self.options.scrollSpeed) ? self.options.scrollSpeed : speed, this.options.easing);
169            }
170            
171        },
172        scrollEvent: function() {
173            var self = this,
174                docTop = self.$document.scrollTop();
175
176            if(docTop < self.currentP && self.currentIndex > 0){
177                // Scroll to top
178                self._ignoreHashChange = true;
179
180                if(self.$current.prev().attr('id'))
181                    self.setHash(self.$current.prev().attr('id'));
182                
183                self.$current
184                    .removeClass('current')
185                    .css( (self.webkit) ? {'-webkit-transform': 'translateY(0px) translateZ(0)'} : {marginTop: 0} )
186                    .nextAll().addClass('hidden').end()
187                    .prev().addClass('current').removeClass('hidden');
188  
189                self.setCache();
190                self.options.prevSlide();
191
192            } else if(docTop < (self.currentP + self.currentHeight)){
193
194                // Animate the current pannel during the scroll
195                if(self.webkit)
196                    self.$current.css({'-webkit-transform': 'translateY('+(-(docTop-self.currentP))+'px) translateZ(0)' });
197                else
198                    self.$current.css({marginTop: -(docTop-self.currentP) });
199
200                // If there is a fixed element in the current panel
201                if(self.$fixedLength){
202                    var dataTop = parseInt(self.$fixed.attr('data-top'), 10);
203
204                    if(docTop + self.$windowHeight >= self.currentP + self.currentHeight){
205                        self.$fixed.css({
206                            position: 'fixed'
207                        });
208                    } else {
209                        self.$fixed.css({
210                            position: 'absolute',
211                            marginTop: Math.abs(docTop-self.currentP)
212                        });
213                    }
214                }
215                
216                // If there is a step element in the current panel
217                if(self.$stepLength){
218                    $.each(self.$step, function(i,el){
219                        if(($(el).position().top+self.currentP) <= docTop+5 && $(el).position().top + self.currentP + $(el).height() >= docTop+5){
220                            if(!$(el).hasClass('current-step')){
221                                self.$step.removeClass('current-step');
222                                $(el).addClass('current-step');
223                                return false;
224                            }
225                        }
226                    });
227                }
228
229
230                if(self.parallaxBg){
231                    var tr = docTop * -0.07;
232
233                    self.parallaxBg.css({
234                        '-webkit-transform' : 'translate3d(0,' + tr + 'px,0)',
235                        '-moz-transform'    : 'translate3d(0,' + tr + 'px,0)',
236                        'transform'         : 'translate3d(0,' + tr + 'px,0)'
237                    });
238                }
239
240                if(self.$fade.length){
241                    self.$fade.css({
242                        'z-index': self.z - 1,
243                        'opacity': Math.abs(1- ( (docTop-self.currentP) / self.$windowHeight))
244                    });
245                }
246
247                if(self.$slowScroll.length){
248                    self.$slowScroll.css({
249                        'margin-top' : (docTop / self.$slowScroll.attr('data-slow-scroll'))
250                    });
251                }
252
253            } else {
254                // Scroll bottom
255                self._ignoreHashChange = true;
256                if(self.$current.next().attr('id'))
257                    self.setHash(self.$current.next().attr('id'));
258
259                self.$current.removeClass('current')
260                    .addClass('hidden')
261                    .next('li').addClass('current').next('li').removeClass('hidden');
262
263                self.setCache();
264                self.options.nextSlide();
265            }
266
267        },
268        scrollMobileEvent: function() {
269            var self = this,
270                docTop = self.$element.scrollTop();
271
272            if(docTop+10 < self.currentP && self.currentIndex > 0){
273
274                // Scroll to top
275                self._ignoreHashChange = true;
276
277                if(self.$current.prev().attr('id'))
278                    self.setHash(self.$current.prev().attr('id'));
279
280                self.$current.removeClass('current').prev().addClass('current');
281                self.setCache();
282                self.options.prevSlide();
283            } else if(docTop+10 < (self.currentP + self.currentHeight)){
284
285                // If there is a step element in the current panel
286                if(self.$stepLength){
287                    $.each(self.$step, function(i,el){
288                        if(($(el).position().top+self.currentP) <= docTop && (($(el).position().top+self.currentP) + $(el).outerHeight()) >= docTop){
289                            if(!$(el).hasClass('current-step')){
290                                self.$step.removeClass('current-step');
291                                $(el).addClass('current-step');
292                            }
293                        }
294                    });
295                }
296
297            } else {
298
299                // Scroll bottom
300                self._ignoreHashChange = true;
301                if(self.$current.next().attr('id'))
302                    self.setHash(self.$current.next().attr('id'));
303
304                self.$current.removeClass('current').next().addClass('current');
305                self.setCache();
306                self.options.nextSlide();
307            }
308
309
310        },
311        // Setters
312        setDimensions: function(){
313            var self = this,
314                levelHeight = 0,
315                cover = false,
316                height = null;
317            
318            self.$windowHeight = self.$window.height();
319
320            this.$li.each(function(index) {
321                var $self = $(this);
322                cover = $self.hasClass('cover');
323
324                if(cover){
325                    $self.css({height: self.$windowHeight, zIndex: 20-index})
326                        .attr('data-height',self.$windowHeight)
327                        .attr('data-position',levelHeight);
328
329                    self.$elDatas[$self.index()] = {
330                        'data-height': parseInt(self.$windowHeight,10),
331                        'data-position': parseInt(levelHeight, 10)
332                    };
333
334                    levelHeight += self.$windowHeight;
335
336                } else{
337                    height = ($self.outerHeight() <= self.$windowHeight) ? self.$windowHeight : $self.outerHeight();
338                    $self.css({minHeight: height, zIndex: 20-index})
339                        .attr('data-height',height)
340                        .attr('data-position',levelHeight);
341                    
342                     self.$elDatas[$self.index()] = {
343                        'data-height': parseInt(height, 10),
344                        'data-position': parseInt(levelHeight, 10)
345                    };
346
347                    levelHeight += height;
348                }
349
350                if($self.find('.fixed').length){
351                    var top = $self.find('.fixed').css('top');
352                    $self.find('.fixed').attr('data-top', top);
353                }
354            });
355            if(!this.options.mobile)
356                this.setBodyHeight();
357        },
358        setEvents: function() {
359            var self = this;
360
361            $(window).on('resize', function(){
362                self.setDimensions();
363            });
364
365            if(self.options.mobile) {
366                self.$element.on('scroll', function(){
367                    self.scrollMobileEvent();
368                });
369            } else {
370                self.$window.on('scroll', function(){
371                    self.scrollEvent();
372                });
373            }
374            
375            if(self.options.enableKeys) {
376                self.$document.on('keydown', function(e){
377                    if(e.keyCode === 38 || e.keyCode === 37) {
378                        self.scrollToPosition('up');
379                        e.preventDefault();
380                        return false;
381                    }
382                    if(e.keyCode === 40 || e.keyCode === 39){
383                        self.scrollToPosition('down');
384                        e.preventDefault();
385                        return false;
386                    }
387                    // Home button
388                    if(e.keyCode === 36){
389                        self.scrollToPosition('top');
390                        e.preventDefault();
391                        return false;
392                    }
393                    // End button
394                    if(e.keyCode === 35){
395                        self.scrollToPosition('bottom');
396                        e.preventDefault();
397                        return false;
398                    }
399                });
400            }
401
402            if(self.options.scrollButtons){
403                if(self.options.scrollButtons.up){
404                    self.options.scrollButtons.up.on('click', function(e){
405                        e.preventDefault();
406                        self.scrollToPosition('up');
407                    });
408                }
409                if(self.options.scrollButtons.down){
410                    self.options.scrollButtons.down.on('click', function(e){
411                        e.preventDefault();
412                        self.scrollToPosition('down');
413                    });
414                }
415            }
416
417            if(self.options.curtainLinks){
418                $(self.options.curtainLinks).on('click', function(e){
419                    e.preventDefault();
420                    var href = $(this).attr('href');
421                    
422                    if(!self.isHashIsOnList(href.substring(1)) && position)
423                        return false;
424                    var position = self.$elDatas[$(href).index()]['data-position'] || null;
425
426                    if(position){
427                        self.scrollEl.animate({
428                            scrollTop:position
429                        }, self.options.scrollSpeed, self.options.easing);
430                    }
431                    return false;
432                });
433            }
434
435            self.$window.on("hashchange", function(event){
436                if(self._ignoreHashChange === false){
437                    self.isHashIsOnList(location.hash.substring(1));
438                }
439                self._ignoreHashChange = false;
440            });
441        },
442        setBodyHeight: function(){
443            var h = 0;
444
445            for (var key in this.$elDatas) {
446               var obj = this.$elDatas[key];
447               h += obj['data-height'];
448            }
449  
450            this.options.bodyHeight = h;
451            $('body').height(h);
452        },
453        setLinks: function(){
454            var self = this;
455            this.$li.each(function() {
456                var id = $(this).attr('id') || 0;
457                self.options.linksArray.push(id);
458            });
459        },
460        setHash: function(hash){
461            // "HARD FIX"
462            el = $('[href=#'+hash+']');
463            el.parent().siblings('li').removeClass('active');
464            el.parent().addClass('active');
465
466            if(history.pushState) {
467                history.pushState(null, null, '#'+hash);
468            }
469            else {
470                location.hash = hash;
471            }
472        },
473        setCache: function(){
474            var self = this;
475            var imageHolderClassName = self.$element.data('image-holder-name');
476            var fadeElementClassName = self.$element.data('fade-element-name');
477            self.$current = self.$element.find('.current');
478            self.$fixed = self.$current.find('.fixed');
479            self.$fixedLength = self.$fixed.length;
480            self.$step = self.$current.find('.step');
481            self.$stepLength = self.$step.length;
482            self.currentIndex = self.$current.index();
483            self.currentP = self.$elDatas[self.currentIndex]['data-position'];
484            self.currentHeight = self.$elDatas[self.currentIndex]['data-height'];
485            self.z = self.$element.find('.current').css('z-index');
486            self.parallaxBg = self.$current.find(imageHolderClassName);
487            self.$fade = $(fadeElementClassName);
488            self.$slowScroll = self.$current.find('[data-slow-scroll]');
489        },
490        // Utils
491        isHashIsOnList: function(hash){
492            var self = this;
493            $.each(self.options.linksArray, function(i,val){
494                if(val === hash){
495                    self.scrollToPosition(hash);
496                    return false;
497                }
498            });
499        },
500        readyElement: function(el,callback){
501          var interval = setInterval(function(){
502            if(el.length){
503              callback(el.length);
504              clearInterval(interval);
505            }
506          },60);
507        },
508        imageLoaded: function(callback){
509            var self = this,
510                elems = self.$element.find('img'),
511                len   = elems.length,
512                blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
513
514            elems.on('load.imgloaded',function(){
515                if (--len <= 0 && this.src !== blank || $(this).not(':visible')){
516                    elems.off('load.imgloaded');
517                    callback.call(elems,this);
518                }
519            }).each(function(){
520                if (this.complete || this.complete === undefined){
521                    var src = this.src;
522                    this.src = blank;
523                    this.src = src;
524                }
525            });
526        }
527    };
528
529
530
531    $.fn[pluginName] = function ( options ) {
532        return this.each(function () {
533            if (!$.data(this, 'plugin_' + pluginName)) {
534                $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
535            }
536        });
537    };
538
539
540})( 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.