芝麻web文件管理V1.00
编辑当前文件:/home/freeclou/optimyar/wp-content/plugins/elementor-extras/assets/lib/switcher/switcher.js
// -- Switcher Plugin // @license Switcher v1.0.0 | MIT | Namogo 2018 | https://www.namogo.com // -------------------------------- ;( function( $, window, document, undefined ) { $.eeSwitcher = function(element, options) { var defaults = { scope : $(window), mediaEffect : 'swipeLeft', contentEffect : 'slideLeft', contentEffectZoom : false, contentStagger : true, speed : 1, duration : 3, autoplay : false, loop : false, changeBackground : false, background : null, entranceAnimation : true, cancelOnInteraction : true, loaderRetractSpeed : 0.2, defaultIndex : 0, titleSelector : '.ee-switcher__title', mediaWrapperSelector: '.ee-switcher__media', mediaSelector : '.ee-switcher__media__items', mediaItemSelector : '.ee-switcher__media__item', imageItemSelector : '.ee-switcher__media__item img', navSelector : '.ee-switcher__nav', navItemSelector : '.ee-switcher__nav__item', navLoaderSelector : '.ee-loader__progress', contentSelector : '.ee-switcher__titles', contentItemSelector : '.ee-switcher__titles__title', descSelector : '.ee-switcher__descriptions', descItemSelector : '.ee-switcher__descriptions__description', arrowsSelector : '.ee-switcher__arrows', arrowNextSelector : '.ee-arrow--next', arrowPrevSelector : '.ee-arrow--prev', }; var plugin = this; plugin.opts = {}; var $window = null, $body = null, $viewport = $(window), $element = $(element), dragging = false, scrolling = false, resizing = false, latestKnownScrollY = -1, latestKnownWindowHeight = -1, latestKnownContentHeight = -1, latestKnownDescHeight = -1, currentScrollY = 0, currentWindowHeight = 0, currentContentHeight = 0, currentDescHeight = 0, ticking = false, updateAF = null, rafTimer = null, _rafStartTime = null, animation = null, st = [], $nav = null, $navItems = null, $media = null, $mediaWrapper = null, $mediaItems = null, $content = null, $contentItems = null, $desc = null, $descItems = null, $imageItems = null, $titleItems = null, $arrows = null, $arrowNext = null, $arrowPrev = null, $arrowCircle = null, $arrowTimer = null, $thisNavItem = null, $thisNavLoader = null, $thisMediaItem = null, $thisImageItem = null, $thisContentItem = null, $thisDescItem = null, $lastNavItem = null, $lastMediaItem = null, $lastImageItem = null, $lastNavLoader = null, $lastContentItem = null, $lastDescItem = null, $background = null, _current = 0, _prev = null, _next = null, _last = 0, _total = null, _direction = null, _circleLength = 0, _startTime = null, _duration = 0, // Total pause duration between transitionss _timerCancelled = false, // Timer has been cancelled by user interaction _timerRunning = false, // Timer is running between transitions _appeared = false, // Element has appearead at least once in the viewport _defaultBgColor = 'rgba(255,255,255,0)', _isAnimating = false, // Transition between slides is occuring _isPlaying = false, // Autoplay is active and is switching slides between timers _effects = null, _easing = CustomEase.create("custom", "M0,0 C0.446,0 0.034,1 1,1"); plugin.init = function() { plugin.opts = $.extend({}, defaults, options); plugin._construct(); }; plugin._construct = function() { $window = plugin.opts.scope; $body = $window.find( 'body' ); currentScrollY = $window.scrollTop(); currentWindowHeight = $(window).height(); plugin.setup(); plugin.requestTick(); plugin.events(); }; plugin.requestTick = function() { if ( ! ticking ) { updateAF = requestAnimationFrame( plugin.refresh ); } ticking = true; }; plugin.setEffects = function( _dir ) { _effects = { media: { 'coverLeft' : { prepareImages : {}, prepareItems : { x: '100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '100%' : '-100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '-10%' : '10%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'coverRight' : { prepareImages : {}, prepareItems : { x: '-100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '-100%' : '100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '10%' : '-10%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'coverTop' : { prepareImages : {}, prepareItems : { y: '100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '100%' : '-100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '-10%' : '10%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'coverBottom' : { prepareImages : {}, prepareItems : { y: '-100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '-100%' : '100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '10%' : '-10%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'uncoverLeft' : { prepareImages : {}, prepareItems : { x: '100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '-10%' : '10%', autoAlpha: 1 }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'uncoverRight' : { prepareImages : {}, prepareItems : { x: '-100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '10%' : '-10%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'uncoverBottom' : { prepareImages : {}, prepareItems : { y: '100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '-10%' : '10%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'uncoverTop' : { prepareImages : {}, prepareItems : { y: '-100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '10%' : '-10%', autoAlpha: 1 }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'fade' : { prepareImages : {}, prepareItems : { autoAlpha: 0, scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, prepareFirst : { autoAlpha: ( plugin.opts.entranceAnimation ) ? 0 : 1, scale: 1 }, prepareFirstImage : {}, prepareNext : {}, prepareNextImage : {}, animateOut : { autoAlpha: 0, scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateIn : { autoAlpha: 1, scale: 1, ease: _easing }, animateImageOut : {}, animateImageIn : {}, }, 'flipHorizontal' : { // wait : true, prepareImages : { transformStyle : "preserve-3d", rotationY : 180, scale: 0.2 }, prepareItems : { perspective : 1300 }, prepareFirst : {}, prepareFirstImage : { rotationY: ( plugin.opts.entranceAnimation ) ? 180 : 0, scale: ( plugin.opts.entranceAnimation ) ? 0.2 : 1 }, prepareNext : {}, prepareNextImage : { rotationY : 180, scale: 0.2 }, animateOut : {}, animateIn : {}, animateImageOut : { rotationY : -180, scale: 0.2, ease: _easing }, animateImageIn : { rotationY : 0, scale: 1, ease: _easing }, }, 'flipVertical' : { // wait : true, prepareImages : { transformStyle : "preserve-3d", rotationX : 180, scale: 0.2 }, prepareItems : { perspective : 1300 }, prepareFirst : {}, prepareFirstImage : { rotationX: ( plugin.opts.entranceAnimation ) ? 180 : 0, scale: ( plugin.opts.entranceAnimation ) ? 0.2 : 1 }, prepareNext : {}, prepareNextImage : { rotationX : 180, scale: 0.2 }, animateOut : {}, animateIn : {}, animateImageOut : { rotationX : -180, scale: 0.2, ease: _easing }, animateImageIn : { rotationX : 0, scale: 1, ease: _easing }, }, 'slideLeft' : { prepareImages : {}, prepareItems : { x: '100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '100%' : '-100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'slideRight' : { prepareImages : {}, prepareItems : { x: '-100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { x: _dir === 'next' ? '-100%' : '100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { x: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'slideTop' : { prepareImages : {}, prepareItems : { y: '100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '100%' : '-100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'slideBottom' : { prepareImages : {}, prepareItems : { y: '-100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { scale: 1 }, prepareNext : { y: _dir === 'next' ? '-100%' : '100%' }, prepareNextImage : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1 }, animateOut : { y: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateImageIn : { scale: 1, ease: _easing }, }, 'swipeLeft' : { prepareItems : {}, prepareImages : { x: _dir === 'next' ? '100%' : '-100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { x: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%', scale: 1 }, prepareNext : { x: _dir === 'next' ? '100%' : '-100%', ease: _easing }, prepareNextImage : { x: _dir === 'next' ? '-100%' : '100%', scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateOut : {}, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageIn : { x: '0%', scale: 1, ease: _easing }, }, 'swipeRight' : { prepareItems : {}, prepareImages : { x: _dir === 'next' ? '-100%' : '100%' }, prepareFirst : { x: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { x: ( plugin.opts.entranceAnimation ) ? '100%' : '0%', scale: 1 }, prepareNext : { x: _dir === 'next' ? '-100%' : '100%', ease: _easing }, prepareNextImage : { x: _dir === 'next' ? '100%' : '-100%', scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateOut : {}, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateIn : { x: '0%', ease: _easing }, animateImageIn : { x: '0%', scale: 1, ease: _easing }, }, 'swipeTop' : { prepareItems : {}, prepareImages : { y: _dir === 'next' ? '100%' : '-100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '100%' : '0%' }, prepareFirstImage : { y: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%', scale: 1 }, prepareNext : { y: _dir === 'next' ? '100%' : '-100%', ease: _easing }, prepareNextImage : { y: _dir === 'next' ? '-100%' : '100%', scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateOut : {}, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageIn : { y: '0%', scale: 1, ease: _easing }, }, 'swipeBottom' : { prepareItems : {}, prepareImages : { y: _dir === 'next' ? '-100%' : '100%' }, prepareFirst : { y: ( plugin.opts.entranceAnimation ) ? '-100%' : '0%' }, prepareFirstImage : { y: ( plugin.opts.entranceAnimation ) ? '100%' : '0%', scale: 1 }, prepareNext : { y: _dir === 'next' ? '-100%' : '100%', ease: _easing }, prepareNextImage : { y: _dir === 'next' ? '100%' : '-100%', scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateOut : {}, animateImageOut : { scale: plugin.opts.contentEffectZoom ? 1.1 : 1, ease: _easing }, animateIn : { y: '0%', ease: _easing }, animateImageIn : { y: '0%', scale: 1, ease: _easing }, }, }, content: { 'slideLeft' : { wait : true, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { x: '0%', ease: _easing }, animateLastTo : { x: _dir === 'next' ? '-150%' : '150%', ease: _easing }, animateNextFrom : { x: _dir === 'next' ? '150%' : '-150%', ease: _easing }, animateNextTo : { x: '0%', ease: _easing }, }, 'slideRight' : { wait : true, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { x: '0%', ease: _easing }, animateLastTo : { x: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateNextFrom : { x: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateNextTo : { x: '0%', ease: _easing }, }, 'slideTop' : { wait : false, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { y: '0%', ease: _easing }, animateLastTo : { y: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateNextFrom : { y: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateNextTo : { y: '0%', ease: _easing }, }, 'slideBottom' : { wait : false, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { y: '0%', ease: _easing }, animateLastTo : { y: _dir === 'next' ? '100%' : '-100%', ease: _easing }, animateNextFrom : { y: _dir === 'next' ? '-100%' : '100%', ease: _easing }, animateNextTo : { y: '0%', ease: _easing }, }, 'fade' : { wait : true, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { autoAlpha: 1, ease: _easing }, animateLastTo : { autoAlpha: 0, ease: _easing }, animateNextFrom : { autoAlpha: 0, ease: _easing }, animateNextTo : { autoAlpha: 1, ease: _easing }, }, 'scale' : { wait : true, prepareItems : { autoAlpha: 0 }, prepareFirst : { autoAlpha: 1 }, prepareNext : { autoAlpha: 1 }, animateLastFrom : { scale: 1, ease: _easing }, animateLastTo : { scale: 0, ease: _easing }, animateNextFrom : { scale: 0, ease: _easing }, animateNextTo : { scale: 1, ease: _easing }, } }, }; }; plugin.setup = function() { $nav = $element.find( plugin.opts.navSelector ); $navItems = $nav.find( plugin.opts.navItemSelector ); $navLoaders = $nav.find( plugin.opts.navLoaderSelector ); $media = $element.find( plugin.opts.mediaSelector ); $mediaWrapper = $element.find( plugin.opts.mediaWrapperSelector ); $imageItems = $element.find( plugin.opts.imageItemSelector ); $titleItems = $element.find( plugin.opts.titleSelector ); $mediaItems = $media.find( plugin.opts.mediaItemSelector ); $content = $element.find( plugin.opts.contentSelector ); $contentItems = $content.find( plugin.opts.contentItemSelector ); $desc = $element.find( plugin.opts.descSelector ); $descItems = $desc.find( plugin.opts.descItemSelector ); $arrows = $element.find( plugin.opts.arrowsSelector ); $arrowNext = $arrows.find( plugin.opts.arrowNextSelector ); $arrowPrev = $arrows.find( plugin.opts.arrowPrevSelector ); $arrowCircle = $arrowNext.find( '.ee-arrow__svg' ); $arrowTimer = $arrowCircle.find( '.ee-arrow__circle--loader' ); $background = plugin.opts.background; _current = plugin.opts.defaultIndex; _total = $mediaItems.length - 1; _last = _current; _prev = _current < 1 ? _total : _current - 1; _next = _current >= _total ? 0 : _current + 1; _defaultBgColor = $background.css( 'backgroundColor' ); $thisNavItem = $navItems.eq( _current ); $thisNavLoader = $thisNavItem.find( plugin.opts.navLoaderSelector ); $thisMediaItem = $mediaItems.eq( _current ); $thisImageItem = $imageItems.eq( _current ); $thisContentItem = $contentItems.eq( _current ); $thisDescItem = $descItems.eq( _current ); $thisNavItem.addClass('is--active'); $thisMediaItem.addClass('is--active is--current').data('active', true); $thisContentItem.addClass('is--active'); $thisDescItem.addClass('is--active'); plugin.setEffects( _direction ); plugin.setArrowsClasses(); // Prepare items TweenMax.set( $mediaItems, _effects.media[ plugin.opts.mediaEffect ].prepareItems ); TweenMax.set( $imageItems, _effects.media[ plugin.opts.mediaEffect ].prepareImages ); TweenMax.set( $contentItems, _effects.content[ plugin.opts.contentEffect ].prepareItems ); TweenMax.set( $descItems, { autoAlpha: 0 } ); // Prepare background if ( ! plugin.opts.entranceAnimation ) { plugin.prepareBackground(); } // Prepare next items if ( ! plugin.opts.entranceAnimation ) { TweenMax.set( $thisMediaItem, _effects.media[ plugin.opts.mediaEffect ].prepareFirst ); TweenMax.set( $thisImageItem, _effects.media[ plugin.opts.mediaEffect ].prepareFirstImage ); TweenMax.set( $thisContentItem, _effects.content[ plugin.opts.contentEffect ].prepareFirst ); TweenMax.set( $thisDescItem, { autoAlpha: 1 } ); } else { TweenMax.set( [ $nav, $arrows ], { autoAlpha: 0 } ); } $element.find('.ee-switcher').addClass( 'is--loaded' ); $contentItems.each( function( index ) { st[index] = new SplitText( $(this).find( plugin.opts.titleSelector ), { type : ['chars', 'words'], }); $( st[index].chars ).addClass('ee-switcher__title__char').wrapInner('
'); }); currentContentHeight = $thisContentItem.outerHeight(); currentDescHeight = $thisDescItem.outerHeight(); }; plugin.events = function() { $window.on( 'ee/toggle-element/toggle', plugin.onResize ); $window.on( 'ee/toggle-element/toggle', plugin.onAppear ); $element.on('switcher:goto', function( e, i ) { var dir = i > _current ? 'next' : 'prev'; plugin.goTo( i, dir ); }); $window.on('scroll', plugin.onScroll ); $(window).on('resize', plugin.onResize ); $titleItems._resize( plugin.onResize ); $descItems._resize( plugin.onResize ); $navItems.each( function( i, e ) { var $this = $(this); $this.on( 'click', function( e ) { var dir = i > _current ? 'next' : 'prev'; plugin.onAfterInteraction(); plugin.goTo( i, dir ); }); }); $arrowNext.on( 'click', function( e ) { e.preventDefault(); plugin.onArrowClick( 'next' ); }); $arrowPrev.on( 'click', function( e ) { e.preventDefault(); plugin.onArrowClick( 'prev' ); }); $._appear( element, { force_process: true }); $element.on( '_appear', plugin.onAppear ); }; plugin.onAppear = function() { if ( ! _appeared ) { if ( plugin.opts.entranceAnimation ) { plugin.animate( 0, 'next' ); } else { if ( plugin.opts.autoplay && ! _timerCancelled && ! _isPlaying ) plugin.play(); } _appeared = true; } }; plugin.onArrowClick = function( direction ) { var _limit = direction === 'next' ? _total : 0, _direction = direction === 'next' ? _next : _prev; if ( ! plugin.opts.loop && ! _isAnimating && _current === _limit ) { return; } plugin.onAfterInteraction(); plugin.goTo( _direction, direction ); }; plugin.onAfterInteraction = function() { if ( plugin.opts.cancelOnInteraction ) { _timerCancelled = true; } } plugin.onScroll = function() { currentScrollY = $window.scrollTop(); plugin.requestTick(); }; plugin.onResize = function() { currentScrollY = $window.scrollTop(); currentContentHeight = $thisContentItem.outerHeight(); currentDescHeight = $thisDescItem.outerHeight(); currentWindowHeight = $window.height(); plugin.requestTick(); }; plugin.prepareBackground = function() { if ( plugin.opts.changeBackground ) { // Set the old default color as a data attribute $background.attr( 'data-switcher-old-background', _defaultBgColor ); if ( ! plugin.opts.entranceAnimation ) { // Entrance animation will take care of this // Set the background color directly TweenMax.set( $background, { backgroundColor: plugin.getCurrentBackgroundColor() } ); // Set the current item background } } }; plugin.changeBackground = function( animation ) { animation.to( $background, plugin.opts.speed, { backgroundColor: plugin.getCurrentBackgroundColor() }, 'animateAll' ); }; plugin.revertBackground = function() { // Remove any exising data on the background elements $background // .css( 'background-color', $background.data( 'switcher-old-background' ) ) .removeAttr( 'data-switcher-old-background' ) .get(0).style.removeProperty('background-color'); }; plugin.getCurrentBackgroundColor = function() { var backgroundColor = $thisNavItem.data('switcher-background'); if ( '' === backgroundColor || undefined === typeof backgroundColor ) { backgroundColor = _defaultBgColor; } return backgroundColor; }; plugin.setupClasses = function() { $content.addClass('is--animating'); $navItems.removeClass('is--active'); $mediaItems.removeClass('is--active is--current').data('active', false); $contentItems.removeClass('is--active'); $descItems.removeClass('is--active'); $lastMediaItem.addClass('is--last'); $thisNavItem.addClass('is--active'); $thisMediaItem.addClass('is--animating is--current').data('active', true); $thisContentItem.addClass('is--animating'); $thisDescItem.addClass('is--animating'); plugin.setArrowsClasses(); }; plugin.setArrowsClasses = function() { $arrowNext.removeClass( 'ee-arrow--disabled' ); $arrowPrev.removeClass( 'ee-arrow--disabled' ); if ( ! plugin.opts.loop ) { if ( _current === _total ) $arrowNext.addClass( 'ee-arrow--disabled' ); if ( _current === 0 ) $arrowPrev.addClass( 'ee-arrow--disabled' ); } }; plugin.play = function() { _startTime = window.performance.now(); _duration = Math.floor( plugin.opts.duration * 10 ); _isPlaying = true; _timerRunning = true; plugin.timer(); }; plugin.stop = function() { _timerRunning = false; plugin.resetNavLoaders(); }; plugin.timer = function() { if ( ! _timerRunning ) return; var time = window.performance.now(), diff = Math.round( time - _startTime ), percent = Math.round( diff / _duration ); percent = percent > 100 ? 100 : percent; if ( percent < 100 && ! _isAnimating ) { plugin.setCircleLength(); plugin.updateCircleLoader( percent ); plugin.updateMenuLoader( percent ); setTimeout( plugin.timer, _duration ); } else { plugin.stop(); plugin.goTo( _next, 'next' ); } } // TODO: Revert to requestAnimationFrame method // plugin.play = function() { // _startTime = window.performance.now() || Date.now(), // _duration = plugin.opts.duration * 1000; // rafTimer = window.requestAnimationFrame( plugin.timer ); // _timerRunning = true; // }; // plugin.stop = function() { // window.cancelAnimationFrame( rafTimer ); // _timerRunning = false; // plugin.resetNavLoaders(); // }; // plugin.timer = function( time ) { // if ( ! _rafStartTime ) { // _rafStartTime = time; // } // var diff = Math.round( time - _startTime ), // percent = Math.round( diff / _duration * 100 ); // percent = percent > 100 ? 100 : percent; // plugin.setCircleLength(); // plugin.updateCircleLoader( percent ); // plugin.updateMenuLoader( percent ); // if ( diff < _duration && ! _isAnimating ) { // rafTimer = window.requestAnimationFrame( plugin.timer ); // } else { // _rafStartTime = null; // plugin.resetNavLoaders(); // plugin.goTo( _next, 'next' ); // } // }; plugin.updateMenuLoader = function( percent ) { TweenMax.to( $thisNavLoader, 0.1, { width: percent + '%' }); }; plugin.updateCircleLoader = function( percent ) { var stroke = parseInt( $arrowTimer.css( 'stroke-width' ), 10 ), dashOffset = 0; dashOffset = _circleLength - _circleLength * ( percent / 100 ); $arrowTimer.addClass( 'is--animating' ); TweenMax.to( $arrowTimer, 0.05, { strokeDasharray : _circleLength, strokeDashoffset : dashOffset } ); }; plugin.resetNavLoaders = function( pause ) { var pause = pause || false; TweenMax.to( $arrowTimer, plugin.opts.loaderRetractSpeed, { strokeDashoffset : _circleLength, ease: _easing, onComplete: function() { if ( pause ) $arrowTimer.removeClass( 'is--animating' ); } } ); if ( ! $lastNavLoader ) return; TweenMax.set( $lastNavLoader, { float: 'right' } ); TweenMax.to( $lastNavLoader, plugin.opts.loaderRetractSpeed, { width: '0%', ease: _easing, clearProps: "float,width" } ); }; plugin.setCircleLength = function() { if ( ! $arrowCircle.length ) return; var circleWidth = parseInt( $arrowCircle.outerWidth() ); _circleLength = Math.round( 2 * Math.PI * ( circleWidth / 2 ) ) + 2; }; plugin.goTo = function( index, direction ) { var _is_current_active = $mediaItems.eq( index ).data('active'); if ( ! _is_current_active && ! _isAnimating ) { plugin.animate( index, direction ); } }; plugin.animate = function( index, direction ) { plugin.onBeforeTransition( index, direction ); var _currentIsLast = _last === _current, _mediaEffect = _effects.media[ plugin.opts.mediaEffect ], _contentEffect = _effects.content[ plugin.opts.contentEffect ], _staggerAmount = plugin.opts.contentStagger ? 0.05 : 0, _lastChars = $( st[_last].chars ).find( '> *' ), _thisChars = $( st[index].chars ).find( '> *' ); if ( _currentIsLast ) { TweenMax.set( $thisMediaItem, _mediaEffect.prepareFirst ); TweenMax.set( $thisImageItem, _mediaEffect.prepareFirstImage ); TweenMax.set( $thisContentItem, _contentEffect.prepareFirst ); } else { TweenMax.set( $thisMediaItem, _mediaEffect.prepareNext ); TweenMax.set( $thisImageItem, _mediaEffect.prepareNextImage ); TweenMax.set( $thisContentItem, _contentEffect.prepareNext ); } // Animate items animation = new TimelineMax({ onComplete: plugin.onAfterTransition }); var waitMedia = _mediaEffect.wait ? plugin.opts.speed / 2 : 0, mediaSpeed = _mediaEffect.wait ? plugin.opts.speed / 2 : plugin.opts.speed; // Animate items animation.to( $lastMediaItem, plugin.opts.speed, _mediaEffect.animateOut, 'animateAll' ); animation.to( $lastImageItem, plugin.opts.speed, _mediaEffect.animateImageOut, 'animateAll' ); animation.to( $lastDescItem, plugin.opts.speed, { autoAlpha: 0 }, 'animateAll' ); animation.to( $thisMediaItem, plugin.opts.speed, _mediaEffect.animateIn, 'animateAll+=' + waitMedia ); animation.to( $thisImageItem, plugin.opts.speed, _mediaEffect.animateImageIn, 'animateAll+=' + waitMedia ); animation.to( $thisDescItem, plugin.opts.speed, { autoAlpha: 1 }, 'animateAll+=' + waitMedia ); // Animate page background if ( plugin.opts.changeBackground ) { plugin.changeBackground( animation ); } var outDuration = plugin.opts.speed, inDuration = plugin.opts.speed, waitDuration = _contentEffect.wait ? plugin.opts.speed / 2 : 0; // Animate chars if ( ! _currentIsLast ) { animation.staggerFromTo( _lastChars, outDuration, _contentEffect.animateLastFrom, _contentEffect.animateLastTo, _staggerAmount, "animateAll" ); } else { waitDuration = 0; } animation.staggerFromTo( _thisChars, inDuration, _contentEffect.animateNextFrom, _contentEffect.animateNextTo, _staggerAmount, "animateAll+=" + waitDuration ); }; plugin.onBeforeTransition = function( index, direction ) { _last = _current; _current = index; _isAnimating = true; _prev = _current < 1 ? _total : _current - 1; _next = _current >= _total ? 0 : _current + 1; _direction = direction; plugin.setEffects( _direction ); $thisNavItem = $navItems.eq( _current ); $thisNavLoader = $thisNavItem.find( plugin.opts.navLoaderSelector ); $thisMediaItem = $mediaItems.eq( _current ); $thisImageItem = $imageItems.eq( _current ); $thisContentItem = $contentItems.eq( _current ); $thisDescItem = $descItems.eq( _current ); $lastNavItem = $navItems.eq( _last ); $lastNavLoader = $lastNavItem.find( plugin.opts.navLoaderSelector ); $lastMediaItem = $mediaItems.eq( _last ); $lastImageItem = $imageItems.eq( _last ); $lastContentItem = $contentItems.eq( _last ); $lastDescItem = $descItems.eq( _last ); plugin.stop(); plugin.setupClasses(); }; plugin.onAfterTransition = function() { $content.removeClass('is--animating'); $navItems.removeClass('is--last'); $mediaItems.removeClass('is--last'); $contentItems.removeClass('is--last'); $descItems.removeClass('is--last'); $thisMediaItem.removeClass('is--animating'); $thisContentItem.removeClass('is--animating'); $thisDescItem.removeClass('is--animating'); $thisMediaItem.addClass('is--active'); $thisContentItem.addClass('is--active'); $thisDescItem.addClass('is--active'); if ( _last !== _current ) { TweenMax.set( $lastContentItem, { autoAlpha: 0 } ); TweenMax.set( $lastDescItem, { autoAlpha: 0 } ); } else if ( plugin.opts.entranceAnimation ) { TweenMax.to( [ $nav, $arrows ], 0.3, { autoAlpha: 1, ease: _easing } ); } _isAnimating = false; if ( plugin.opts.autoplay && ! _timerCancelled ) { if ( ! plugin.opts.loop ) { if ( _current === _total ) { _isPlaying = false; return; } plugin.play(); } else { plugin.play(); } } }; plugin.getTallestElement = function( $items ) { var tallest = 0; $items.each( function(){ var itemHeight = $(this).outerHeight(); if ( itemHeight > tallest ) { tallest = itemHeight; } }); return tallest; }; plugin.setContentHeight = function( _height, $parent, $items ) { var newHeight = plugin.getTallestElement( $items ); if ( ! _height ) { _height = newHeight; } else { newHeight = _height; } $parent.css({ height: _height }); return newHeight; }; plugin.refresh = function() { ticking = false; if ( latestKnownContentHeight !== currentContentHeight ) { latestKnownContentHeight = plugin.setContentHeight( false, $content, $contentItems ); } if ( latestKnownDescHeight !== currentDescHeight ) { latestKnownContentHeight = plugin.setContentHeight( false, $desc, $descItems ); } if ( ( latestKnownScrollY !== currentScrollY ) || ( latestKnownWindowHeight !== currentWindowHeight ) ) { latestKnownScrollY = currentScrollY; latestKnownWindowHeight = currentWindowHeight; if ( plugin.opts.autoplay && _appeared ) { if ( ! $element.visible( true, false, 'vertical' ) || ! $element.is(':visible') ) { if ( _timerRunning ) { plugin.stop(); } } else if ( ! _timerCancelled && ! _timerRunning && _isPlaying ) { plugin.play(); } } } }; plugin.destroy = function() { // Make sure autoplay is stopped plugin.stop() // Kill the current animation if it's defined if ( animation ) animation.kill(); // Cancel animation frames // window.cancelAnimationFrame( updateAF ); // window.cancelAnimationFrame( rafTimer ); // Unbind events $navItems.unbind(); $arrowNext.unbind(); $arrowPrev.unbind(); $window.off( 'scroll', plugin.onScroll ); $window.off( 'mousemove', plugin.parallax ); $viewport.off( 'resize', plugin.onResize ); plugin.revertBackground(); // Remove plugin from data $element.removeData( 'eeSwitcher' ); }; plugin.init(); }; $.fn.inlineStyle = function ( prop ) { return this.prop("style")[ $.camelCase( prop ) ]; }; $.fn.eeSwitcher = function(options) { return this.each(function() { if (undefined === $(this).data('eeSwitcher')) { var plugin = new $.eeSwitcher( this, options ); $(this).data( 'eeSwitcher', plugin ); } }); }; } )( jQuery, window, document );