PageSourceSearch

https://reservas.hotelamaike.com/portal/themes/traveller/js/gridrotator.js?v=34

js hotelamaike.com collected 2026-10-05 07:13:27 UTC 26,144 bytes, 805 lines download raw bytes

1/**
2 * jquery.gridrotator.js v1.1.0
3 * http://www.codrops.com
4 *
5 * Licensed under the MIT license.
6 * http://www.opensource.org/licenses/mit-license.php
7 *
8 * Copyright 2012, Codrops
9 * http://www.codrops.com
10 */
11;
12(function($, window, undefined) {
13
14    'use strict';
15
16    /*
17     * debouncedresize: special jQuery event that happens once after a window resize
18     *
19     * latest version and complete README available on Github:
20     * https://github.com/louisremi/jquery-smartresize/blob/master/jquery.debouncedresize.js
21     *
22     * Copyright 2011 @louis_remi
23     * Licensed under the MIT license.
24     */
25    var $event = $.event,
26        $special,
27        resizeTimeout;
28
29    $special = $event.special.debouncedresize = {
30        setup: function() {
31            $(this).on("resize", $special.handler);
32        },
33        teardown: function() {
34            $(this).off("resize", $special.handler);
35        },
36        handler: function(event, execAsap) {
37            // Save the context
38            var context = this,
39                args = arguments,
40                dispatch = function() {
41                    // set correct event type
42                    event.type = "debouncedresize";
43                    $event.dispatch.apply(context, args);
44                };
45
46            if (resizeTimeout) {
47                clearTimeout(resizeTimeout);
48            }
49
50            execAsap ?
51                dispatch() :
52                resizeTimeout = setTimeout(dispatch, $special.threshold);
53        },
54        threshold: 100
55    };
56
57    // http://www.hardcode.nl/subcategory_1/article_317-array-shuffle-function
58    Array.prototype.shuffle = function() {
59        var i = this.length,
60            p, t;
61        while (i--) {
62            p = Math.floor(Math.random() * i);
63            t = this[i];
64            this[i] = this[p];
65            this[p] = t;
66        }
67        return this;
68    };
69
70    // HTML5 PageVisibility API
71    // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
72    // by Joe Marini (@joemarini)
73    function getHiddenProp() {
74        var prefixes = ['webkit', 'moz', 'ms', 'o'];
75
76        // if 'hidden' is natively supported just return it
77        if ('hidden' in document) return 'hidden';
78
79        // otherwise loop over all the known prefixes until we find one
80        for (var i = 0; i < prefixes.length; i++) {
81            if ((prefixes[i] + 'Hidden') in document)
82                return prefixes[i] + 'Hidden';
83        }
84
85        // otherwise it's not supported
86        return null;
87    }
88
89    function isHidden() {
90        var prop = getHiddenProp();
91        if (!prop) return false;
92
93        return document[prop];
94    }
95
96    function isEmpty(obj) {
97        return Object.keys(obj).length === 0;
98    }
99
100    // global
101    var $window = $(window),
102        Modernizr = window.Modernizr;
103
104    $.GridRotator = function(options, element) {
105
106        this.$el = $(element);
107        if (Modernizr.backgroundsize) {
108
109            var self = this;
110            this.$el.addClass('ri-grid-loading');
111            this._init(options);
112
113        }
114
115    };
116
117    // the options
118    $.GridRotator.defaults = {
119        // number of rows
120        rows: 4,
121        // number of columns 
122        columns: 10,
123        w992: {
124            rows: 3,
125            columns: 8
126        },
127        w768: {
128            rows: 3,
129            columns: 7
130        },
131        w480: {
132            rows: 3,
133            columns: 5
134        },
135        w320: {
136            rows: 2,
137            columns: 4
138        },
139        w240: {
140            rows: 2,
141            columns: 3
142        },
143        // step: number of items that are replaced at the same time
144        // random || [some number]
145        // note: for performance issues, the number "can't" be > options.maxStep
146        step: 'random',
147        // change it as you wish..
148        maxStep: 3,
149        // prevent user to click the items
150        preventClick: true,
151        // animation type
152        // showHide || fadeInOut || 
153        // slideLeft || slideRight || slideTop || slideBottom || 
154        // rotateBottom || rotateLeft || rotateRight || rotateTop || 
155        // scale ||
156        // rotate3d ||
157        // rotateLeftScale || rotateRightScale || rotateTopScale || rotateBottomScale || 
158        // random
159        animType: 'random',
160        // animation speed
161        animSpeed: 800,
162        // animation easings
163        animEasingOut: 'linear',
164        animEasingIn: 'linear',
165        // the item(s) will be replaced every 3 seconds
166        // note: for performance issues, the time "can't" be < 300 ms
167        interval: 3000,
168        // if false the animations will not start
169        // use false if onhover is true for example
170        slideshow: true,
171        // if true the items will switch when hovered
172        onhover: false,
173        // ids of elements that shouldn't change
174        nochange: []
175    };
176
177    $.GridRotator.prototype = {
178
179        _init: function(options) {
180
181            // options
182            this.options = $.extend(true, {}, $.GridRotator.defaults, options);
183            // cache some elements + variables
184            this._config();
185
186        },
187        _config: function() {
188
189            var self = this,
190                transEndEventNames = {
191                    'WebkitTransition': 'webkitTransitionEnd',
192                    'MozTransition': 'transitionend',
193                    'OTransition': 'oTransitionEnd',
194                    'msTransition': 'MSTransitionEnd',
195                    'transition': 'transitionend'
196                };
197
198            // support CSS transitions and 3d transforms
199            this.supportTransitions = Modernizr.csstransitions;
200            this.supportTransforms3D = Modernizr.csstransforms3d;
201
202            this.transEndEventName = transEndEventNames[Modernizr.prefixed('transition')] + '.gridrotator';
203
204            // all animation types for the random option
205            this.animTypes = this.supportTransforms3D ? [
206                'fadeInOut',
207                'slideLeft',
208                'slideRight',
209                'slideTop',
210                'slideBottom',
211                'rotateLeft',
212                'rotateRight',
213                'rotateTop',
214                'rotateBottom',
215                // 'scale', 
216                'rotate3d',
217                // 'rotateLeftScale', 
218                // 'rotateRightScale', 
219                // 'rotateTopScale', 
220                // 'rotateBottomScale' 
221            ] :
222                ['fadeInOut', 'slideLeft', 'slideRight', 'slideTop', 'slideBottom'];
223
224            this.animType = this.options.animType;
225
226            if (this.animType !== 'random' && !this.supportTransforms3D && $.inArray(this.animType, this.animTypes) === -1 && this.animType !== 'showHide') {
227
228                // fallback to 'fadeInOut' if user sets a type which is not supported
229                this.animType = 'fadeInOut';
230
231            }
232
233            this.animTypesTotal = this.animTypes.length;
234
235            // the <ul> where the items are placed
236            this.$list = this.$el.children('ul');
237            // remove images and add background-image to anchors
238            // preload the images before
239            var loaded = 0,
240                $imgs = this.$list.find('img'),
241                count = $imgs.length;
242
243            $imgs.each(function() {
244
245                var $img = $(this),
246                    src = $img.attr('src');
247
248                $('<img/>').load(function() {
249
250                    ++loaded;
251                    $img.parent().css('background-image', 'url(' + src + ')');
252
253                    if (loaded === count) {
254
255                        $imgs.remove();
256                        self.$el.removeClass('ri-grid-loading');
257                        // the items
258                        self.$items = self.$list.children('li');
259                        // make a copy of the items
260                        self.$itemsCache = self.$items.clone();
261                        // total number of items
262                        self.itemsTotal = self.$items.length;
263                        // the items that will be out of the grid
264                        // actually the item's child (anchor element)
265                        self.outItems = [];
266                        self._layout(function() {
267                            self._initEvents();
268                        });
269                        // replace [options.step] items after [options.interval] time
270                        // the items that go out are randomly chosen, while the ones that get in
271                        // follow a "First In First Out" logic
272                        self._start();
273
274                    }
275
276                }).attr('src', src)
277
278            });
279
280        },
281        _layout: function(callback) {
282
283            var self = this;
284
285            // sets the grid dimentions based on the container's width
286            this._setGridDim();
287
288            // reset
289            this.$list.empty();
290            this.$items = this.$itemsCache.clone().appendTo(this.$list);
291
292            var $outItems = this.$items.filter(':gt(' + (this.showTotal - 1) + ')'),
293                $outAItems = $outItems.children('a');
294
295            this.outItems.length = 0;
296
297            $outAItems.each(function(i) {
298                self.outItems.push($(this));
299            });
300
301            $outItems.remove();
302
303            // container's width
304            var containerWidth = (document.defaultView) ? parseInt(document.defaultView.getComputedStyle(this.$el.get(0), null).width) : this.$el.width(),
305                // item's width
306                itemWidth = Math.floor(containerWidth / this.columns),
307                // calculate gap
308                gapWidth = containerWidth - (this.columns * Math.floor(itemWidth));
309
310            for (var i = 0; i < this.rows; ++i) {
311
312                for (var j = 0; j < this.columns; ++j) {
313
314                    var idx = this.columns * i + j,
315                        $item = this.$items.eq(idx);
316
317                    $item.css({
318                        width: j < Math.floor(gapWidth) ? itemWidth + 1 : itemWidth,
319                        height: itemWidth
320                    });
321
322                    if ($.inArray(idx, this.options.nochange) !== -1) {
323                        $item.addClass('ri-nochange').data('nochange', true);
324                    }
325
326                }
327
328            }
329
330            if (this.options.preventClick) {
331
332                this.$items.children().css('cursor', 'default').on('click.gridrotator', false);
333
334            }
335
336            if (callback) {
337                callback.call();
338            }
339
340        },
341        // set the grid rows and columns
342        _setGridDim: function() {
343
344            // container's width
345            var c_w = this.$el.width();
346
347            // we will choose the number of rows/columns according to the container's width and the values set in the plugin options 
348            switch (true) {
349                case (c_w < 240):
350                    this.rows = this.options.w240.rows;
351                    this.columns = this.options.w240.columns;
352                    break;
353                case (c_w < 320):
354                    this.rows = this.options.w320.rows;
355                    this.columns = this.options.w320.columns;
356                    break;
357                case (c_w < 480):
358                    this.rows = this.options.w480.rows;
359                    this.columns = this.options.w480.columns;
360                    break;
361                case (c_w < 768):
362                    this.rows = this.options.w768.rows;
363                    this.columns = this.options.w768.columns;
364                    break;
365                case (c_w < 992):
366                    this.rows = this.options.w992.rows;
367                    this.columns = this.options.w992.columns;
368                    break;
369                default:
370                    this.rows = this.options.rows;
371                    this.columns = this.options.columns;
372                    break;
373            }
374
375            this.showTotal = this.rows * this.columns;
376
377        },
378        // init window resize event
379        _initEvents: function() {
380
381            var self = this;
382
383            $window.on('debouncedresize.gridrotator', function() {
384                self._layout();
385            });
386
387            // use the property name to generate the prefixed event name
388            var visProp = getHiddenProp();
389
390            // HTML5 PageVisibility API
391            // http://www.html5rocks.com/en/tutorials/pagevisibility/intro/
392            // by Joe Marini (@joemarini)
393            if (visProp) {
394
395                var evtname = visProp.replace(/[H|h]idden/, '') + 'visibilitychange';
396                document.addEventListener(evtname, function() {
397                    self._visChange();
398                });
399
400            }
401
402            if (!Modernizr.touch && this.options.onhover) {
403
404                self.$items.on('mouseenter.gridrotator', function() {
405
406                    var $item = $(this);
407                    if (!$item.data('active') && !$item.data('hovered') && !$item.data('nochange')) {
408                        $item.data('hovered', true);
409                        self._replace($item);
410                    }
411
412                }).on('mouseleave.gridrotator', function() {
413
414                    $(this).data('hovered', false);
415
416                });
417
418            }
419
420        },
421        _visChange: function() {
422
423            isHidden() ? clearTimeout(this.playtimeout) : this._start();
424
425        },
426        // start rotating elements
427        _start: function() {
428
429            if (this.showTotal < this.itemsTotal && this.options.slideshow) {
430                this._showNext();
431            }
432
433        },
434        // get which type of animation
435        _getAnimType: function() {
436
437            return this.animType === 'random' ? this.animTypes[Math.floor(Math.random() * this.animTypesTotal)] : this.animType;
438
439        },
440        // get css properties for the transition effect
441        _getAnimProperties: function($out) {
442
443            var startInProp = {},
444                startOutProp = {},
445                endInProp = {},
446                endOutProp = {},
447                animType = this._getAnimType(),
448                speed, delay = 0;
449
450            switch (animType) {
451
452                case 'showHide':
453
454                    speed = 0;
455                    endOutProp.opacity = 0;
456                    break;
457
458                case 'fadeInOut':
459
460                    endOutProp.opacity = 0;
461                    break;
462
463                case 'slideLeft':
464
465                    startInProp.left = $out.width();
466                    endInProp.left = 0;
467                    endOutProp.left = -$out.width();
468                    break;
469
470                case 'slideRight':
471
472                    startInProp.left = -$out.width();
473                    endInProp.left = 0;
474                    endOutProp.left = $out.width();
475                    break;
476
477                case 'slideTop':
478
479                    startInProp.top = $out.height();
480                    endInProp.top = 0;
481                    endOutProp.top = -$out.height();
482                    break;
483
484                case 'slideBottom':
485
486                    startInProp.top = -$out.height();
487                    endInProp.top = 0;
488                    endOutProp.top = $out.height();
489                    break;
490
491                case 'rotateLeft':
492
493                    speed = this.options.animSpeed / 2;
494                    startInProp.transform = 'rotateY(90deg)';
495                    endInProp.transform = 'rotateY(0deg)';
496                    delay = speed;
497                    endOutProp.transform = 'rotateY(-90deg)';
498                    break;
499
500                case 'rotateRight':
501
502                    speed = this.options.animSpeed / 2;
503                    startInProp.transform = 'rotateY(-90deg)';
504                    endInProp.transform = 'rotateY(0deg)';
505                    delay = speed;
506                    endOutProp.transform = 'rotateY(90deg)';
507                    break;
508
509                case 'rotateTop':
510
511                    speed = this.options.animSpeed / 2;
512                    startInProp.transform = 'rotateX(90deg)';
513                    endInProp.transform = 'rotateX(0deg)';
514                    delay = speed;
515                    endOutProp.transform = 'rotateX(-90deg)';
516                    break;
517
518                case 'rotateBottom':
519
520                    speed = this.options.animSpeed / 2;
521                    startInProp.transform = 'rotateX(-90deg)';
522                    endInProp.transform = 'rotateX(0deg)';
523                    delay = speed;
524                    endOutProp.transform = 'rotateX(90deg)';
525                    break;
526
527                case 'scale':
528
529                    speed = this.options.animSpeed / 2;
530                    startInProp.transform = 'scale(0)';
531                    startOutProp.transform = 'scale(1)';
532                    endInProp.transform = 'scale(1)';
533                    delay = speed;
534                    endOutProp.transform = 'scale(0)';
535                    break;
536
537                case 'rotateLeftScale':
538
539                    startOutProp.transform = 'scale(1)';
540                    speed = this.options.animSpeed / 2;
541                    startInProp.transform = 'scale(0.3) rotateY(90deg)';
542                    endInProp.transform = 'scale(1) rotateY(0deg)';
543                    delay = speed;
544                    endOutProp.transform = 'scale(0.3) rotateY(-90deg)';
545                    break;
546
547                case 'rotateRightScale':
548
549                    startOutProp.transform = 'scale(1)';
550                    speed = this.options.animSpeed / 2;
551                    startInProp.transform = 'scale(0.3) rotateY(-90deg)';
552                    endInProp.transform = 'scale(1) rotateY(0deg)';
553                    delay = speed;
554                    endOutProp.transform = 'scale(0.3) rotateY(90deg)';
555                    break;
556
557                case 'rotateTopScale':
558
559                    startOutProp.transform = 'scale(1)';
560                    speed = this.options.animSpeed / 2;
561                    startInProp.transform = 'scale(0.3) rotateX(90deg)';
562                    endInProp.transform = 'scale(1) rotateX(0deg)';
563                    delay = speed;
564                    endOutProp.transform = 'scale(0.3) rotateX(-90deg)';
565                    break;
566
567                case 'rotateBottomScale':
568
569                    startOutProp.transform = 'scale(1)';
570                    speed = this.options.animSpeed / 2;
571                    startInProp.transform = 'scale(0.3) rotateX(-90deg)';
572                    endInProp.transform = 'scale(1) rotateX(0deg)';
573                    delay = speed;
574                    endOutProp.transform = 'scale(0.3) rotateX(90deg)';
575                    break;
576
577                case 'rotate3d':
578
579                    speed = this.options.animSpeed / 2;
580                    startInProp.transform = 'rotate3d( 1, 1, 0, 90deg )';
581                    endInProp.transform = 'rotate3d( 1, 1, 0, 0deg )';
582                    delay = speed;
583                    endOutProp.transform = 'rotate3d( 1, 1, 0, -90deg )';
584                    break;
585
586            }
587
588            return {
589                startInProp: startInProp,
590                startOutProp: startOutProp,
591                endInProp: endInProp,
592                endOutProp: endOutProp,
593                delay: delay,
594                animSpeed: speed != undefined ? speed : this.options.animSpeed
595            };
596
597        },
598        // show next [option.step] elements
599        _showNext: function(time) {
600
601            var self = this;
602
603            clearTimeout(this.playtimeout);
604
605            this.playtimeout = setTimeout(function() {
606
607                var step = self.options.step,
608                    max = self.options.maxStep,
609                    min = 1;
610
611                if (max > self.showTotal) {
612                    max = self.showTotal;
613                }
614
615                // number of items to swith at this point of time
616                var nmbOut = step === 'random' ? Math.floor(Math.random() * max + min) : Math.min(Math.abs(step), max),
617                    // array with random indexes. These will be the indexes of the items we will replace
618                    randArr = self._getRandom(nmbOut, self.showTotal);
619
620                for (var i = 0; i < nmbOut; ++i) {
621
622                    // element to go out
623                    var $out = self.$items.eq(randArr[i]);
624
625                    // if element is active, which means it is currently animating,
626                    // then we need to get different positions.. 
627                    if ($out.data('active') || $out.data('nochange')) {
628
629                        // one of the items is active, call again..
630                        self._showNext(1);
631                        return false;
632
633                    }
634
635                    self._replace($out);
636
637                }
638
639                // again and again..
640                self._showNext();
641
642            }, time || Math.max(Math.abs(this.options.interval), 300));
643
644        },
645        _replace: function($out) {
646
647            $out.data('active', true);
648
649            var self = this,
650                $outA = $out.children('a:last'),
651                newElProp = {
652                    width: $outA.width(),
653                    height: $outA.height()
654                };
655
656            // element stays active
657            $out.data('active', true);
658
659            // get the element (anchor) that will go in (first one inserted in this.outItems)
660            var $inA = this.outItems.shift();
661
662            // save element that went out
663            this.outItems.push($outA.clone().css('transition', 'none'));
664
665            // prepend in element
666            $inA.css(newElProp).prependTo($out);
667
668            var animProp = this._getAnimProperties($outA);
669
670            $inA.css(animProp.startInProp);
671            $outA.css(animProp.startOutProp);
672
673            this._setTransition($inA, 'all', animProp.animSpeed, animProp.delay, this.options.animEasingIn);
674            this._setTransition($outA, 'all', animProp.animSpeed, 0, this.options.animEasingOut);
675
676            this._applyTransition($inA, animProp.endInProp, animProp.animSpeed, function() {
677
678                var $el = $(this),
679                    t = animProp.animSpeed === self.options.animSpeed && isEmpty(animProp.endInProp) ? animProp.animSpeed : 0;
680
681                setTimeout(function() {
682
683                    if (self.supportTransitions) {
684                        $el.off(self.transEndEventName);
685                    }
686
687                    $el.next().remove();
688                    $el.parent().data('active', false);
689
690                }, t);
691
692            }, animProp.animSpeed === 0 || isEmpty(animProp.endInProp));
693            this._applyTransition($outA, animProp.endOutProp, animProp.animSpeed);
694
695        },
696        _getRandom: function(cnt, limit) {
697
698            var randArray = [];
699
700            for (var i = 0; i < limit; ++i) {
701                randArray.push(i)
702            }
703
704            return randArray.shuffle().slice(0, cnt);
705
706        },
707        _setTransition: function(el, prop, speed, delay, easing) {
708
709            setTimeout(function() {
710                el.css('transition', prop + ' ' + speed + 'ms ' + delay + 'ms ' + easing);
711            }, 25);
712
713        },
714        _applyTransition: function(el, styleCSS, speed, fncomplete, force) {
715
716            var self = this;
717            setTimeout(function() {
718                $.fn.applyStyle = self.supportTransitions ? $.fn.css : $.fn.animate;
719
720                if (fncomplete && self.supportTransitions) {
721
722                    el.on(self.transEndEventName, fncomplete);
723
724                    if (force) {
725                        fncomplete.call(el);
726                    }
727
728                }
729
730                fncomplete = fncomplete || function() {
731                    return false;
732                };
733
734                el.stop().applyStyle(styleCSS, $.extend(true, [], {
735                    duration: speed + 'ms',
736                    complete: fncomplete
737                }));
738            }, 25);
739
740        }
741
742    };
743
744    var logError = function(message) {
745
746        if (window.console) {
747
748            window.console.error(message);
749
750        }
751
752    };
753
754    $.fn.gridrotator = function(options) {
755
756        var instance = $.data(this, 'gridrotator');
757
758        if (typeof options === 'string') {
759
760            var args = Array.prototype.slice.call(arguments, 1);
761
762            this.each(function() {
763
764                if (!instance) {
765
766                    logError("cannot call methods on gridrotator prior to initialization; " +
767                        "attempted to call method '" + options + "'");
768                    return;
769
770                }
771
772                if (!$.isFunction(instance[options]) || options.charAt(0) === "_") {
773
774                    logError("no such method '" + options + "' for gridrotator instance");
775                    return;
776
777                }
778
779                instance[options].apply(instance, args);
780
781            });
782
783        } else {
784
785            this.each(function() {
786
787                if (instance) {
788
789                    instance._init();
790
791                } else {
792
793                    instance = $.data(this, 'gridrotator', new $.GridRotator(options, this));
794
795                }
796
797            });
798
799        }
800
801        return instance;
802
803    };
804
805})(jQuery, window);

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.