(function(root, factory) { if (typeof define === 'function' && define.amd) { define(factory); } else if (typeof exports === 'object') { module.exports = factory(require, exports, module); } else { root.ScrollReveal = factory(); } }(this, function(require, exports, module) { /* _____ ________ __ / ___/______________ / / / __ \___ _ _____ ____ _/ / \__ \/ ___/ ___/ __ \/ / / /_/ / _ \ | / / _ \/ __ `/ / ___/ / /__/ / / /_/ / / / _, _/ __/ |/ / __/ /_/ / / /____/\___/_/ \____/_/_/_/ |_|\___/|___/\___/\__,_/_/ v3.0.3 ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾ Copyright 2014–2016 Julian Lloyd (@jlmakes) Open source under MIT license ———————————————————————————————————————————————————————————————————————————————— https://scrollrevealjs.org — https://github.com/jlmakes/scrollreveal.js ______________________________________________________________________________*/ (function() { var Tools, sr, _requestAnimationFrame; this.ScrollReveal = (function() { ScrollReveal.prototype.defaults = { // Animation origin : 'bottom', distance : '20px', duration : 500, delay : 0, rotate : { x: 0, y: 0, z: 0 }, opacity : 0, scale : 0.9, easing : 'cubic-bezier( 0.6, 0.2, 0.1, 1 )', // Options container : null, mobile : true, reset : false, useDelay : 'always', viewFactor : 0.2, viewOffset : { top: 0, right: 0, bottom: 0, left: 0 }, afterReveal : function( domEl ) {}, afterReset : function( domEl ) {} }; function ScrollReveal( config ) { if ( window == this ) { return new ScrollReveal( config ); } sr = this; sr.tools = new Tools(); sr.tools.extend( sr.defaults, config || {} ); if ( sr.tools.isMobile() && !sr.defaults.mobile ) { return false; } else if ( !sr.tools.browserSupports('transform') ) { return console.warn('Your browser does not support CSS transform.'); } sr.store = { elements : {}, containers : [] }; sr.history = []; sr.counter = 0; sr.blocked = false; sr.initialized = false; return sr; } ScrollReveal.prototype.reveal = function( selector, config, sync ){ var elements, container, elem, elemId; if ( config && config.container ) { container = config.container; } else { container = window.document.documentElement; } elements = Array.prototype.slice.call( container.querySelectorAll( selector ) ); if ( !elements.length ) { console.warn( 'reveal(\'' + selector + '\') failed: no elements found.' ); return sr; } for ( var i = 0; i < elements.length; i++ ) { elem = {} elemId = elements[ i ].getAttribute('data-sr-id'); if ( elemId ) { elem = sr.store.elements[ elemId ]; } else { elem = { id : ++sr.counter, domEl : elements[ i ], seen : false, revealed : false }; elem.domEl.setAttribute( 'data-sr-id', elem.id ); } sr.configure( elem, config || {} ); sr.style( elem ); sr.updateStore( elem ); if ( !elem.revealed ) { elem.domEl.setAttribute( 'style', elem.styles.inline + elem.styles.transform.initial ); } } if ( !sync ) { sr.record( selector, config ); } sr.init(); return sr; }; ScrollReveal.prototype.configure = function( elem, config ) { if ( !elem.config ) { elem.config = sr.tools.extendClone( sr.defaults, config ); } else { elem.config = sr.tools.extendClone( elem.config, config ); } if ( elem.config.origin === 'top' || elem.config.origin === 'bottom' ) { elem.config.axis = 'Y'; } else { elem.config.axis = 'X'; } if ( elem.config.origin === 'top' || elem.config.origin === 'left' ) { elem.config.distance = '-' + elem.config.distance; } }; ScrollReveal.prototype.style = function( elem ) { var config = elem.config; var computed = window.getComputedStyle( elem.domEl ); if ( !elem.styles ) { elem.styles = { transition : {}, transform : {}, computed : {} }; elem.styles.inline = elem.domEl.getAttribute('style') || ''; elem.styles.inline += '; visibility: visible; '; elem.styles.computed.opacity = computed.opacity; if ( !computed.transition || computed.transition == 'all 0s ease 0s' ) { elem.styles.computed.transition = ''; } else { elem.styles.computed.transition = computed.transition + ', '; } } elem.styles.transition.instant = '-webkit-transition: ' + elem.styles.computed.transition + '-webkit-transform ' + config.duration / 1000 + 's ' + config.easing + ' 0s, opacity ' + config.duration / 1000 + 's ' + config.easing + ' 0s; ' + 'transition: ' + elem.styles.computed.transition + 'transform ' + config.duration / 1000 + 's ' + config.easing + ' 0s, opacity ' + config.duration / 1000 + 's ' + config.easing + ' 0s; '; elem.styles.transition.delayed = '-webkit-transition: ' + elem.styles.computed.transition + '-webkit-transform ' + config.duration / 1000 + 's ' + config.easing + ' ' + config.delay / 1000 + 's, opacity ' + config.duration / 1000 + 's ' + config.easing + ' ' + config.delay / 1000 + 's; ' + 'transition: ' + elem.styles.computed.transition + 'transform ' + config.duration / 1000 + 's ' + config.easing + ' ' + config.delay / 1000 + 's, opacity ' + config.duration / 1000 + 's ' + config.easing + ' ' + config.delay / 1000 + 's; '; elem.styles.transform.initial += ' -webkit-transform:'; elem.styles.transform.target += ' -webkit-transform:'; generateTransform( elem.styles.transform ); elem.styles.transform.initial = 'transform:'; elem.styles.transform.target = 'transform:'; generateTransform( elem.styles.transform ); function generateTransform( transform ) { if ( parseInt( config.distance ) ) { transform.initial += ' translate' + config.axis + '(' + config.distance + ')'; transform.target += ' translate' + config.axis + '(0)'; } if ( config.scale ) { transform.initial += ' scale(' + config.scale + ')'; transform.target += ' scale(1)'; } if ( config.rotate.x ) { transform.initial += ' rotateX(' + config.rotate.x + 'deg)'; transform.target += ' rotateX(0)'; } if ( config.rotate.y ) { transform.initial += ' rotateY(' + config.rotate.y + 'deg)'; transform.target += ' rotateY(0)'; } if ( config.rotate.z ) { transform.initial += ' rotateZ(' + config.rotate.z + 'deg)'; transform.target += ' rotateZ(0)'; } transform.initial += '; opacity: ' + config.opacity + ';'; transform.target += '; opacity: ' + elem.styles.computed.opacity + ';'; } }; ScrollReveal.prototype.updateStore = function( elem ) { var container = elem.config.container; if ( container && sr.store.containers.indexOf( container ) == -1 ) { sr.store.containers.push( elem.config.container ); } sr.store.elements[ elem.id ] = elem; }; ScrollReveal.prototype.record = function( selector, config ) { var record = { selector : selector, config : config }; sr.history.push( record ); }; ScrollReveal.prototype.init = function() { sr.animate(); for ( var i = sr.store.containers.length - 1; i >= 0; i-- ) { sr.store.containers[ i ].addEventListener( 'scroll', sr.handler ); sr.store.containers[ i ].addEventListener( 'resize', sr.handler ); } if ( !sr.initialized ){ window.addEventListener( 'scroll', sr.handler ); window.addEventListener( 'resize', sr.handler ); sr.initialized = true; } return sr; }; ScrollReveal.prototype.handler = function() { if ( !sr.blocked ) { sr.blocked = true; _requestAnimationFrame( sr.animate ); } }; ScrollReveal.prototype.animate = function() { var elem, visible; sr.tools.forOwn( sr.store.elements, function( elemId ) { elem = sr.store.elements[ elemId ]; visible = sr.isElemVisible( elem ); if ( visible && !elem.revealed ) { if ( elem.config.useDelay === 'always' || ( elem.config.useDelay === 'onload' && !sr.initialized ) || ( elem.config.useDelay === 'once' && !elem.seen ) ) { elem.domEl.setAttribute( 'style', elem.styles.inline + elem.styles.transform.target + elem.styles.transition.delayed ); } else { elem.domEl.setAttribute( 'style', elem.styles.inline + elem.styles.transform.target + elem.styles.transition.instant ); } elem.seen = true; queueCallback( 'reveal', elem ); } else if ( !visible && elem.config.reset && elem.revealed ){ elem.domEl.setAttribute( 'style', elem.styles.inline + elem.styles.transform.initial + elem.styles.transition.instant ); queueCallback( 'reset', elem ); } }); sr.blocked = false; function queueCallback( type, elem ) { var elapsed = 0; var duration = 0; var callback = 'after'; switch ( type ) { case 'reveal': duration = elem.config.duration + elem.config.delay; callback += 'Reveal'; break; case 'reset': duration = elem.config.duration; callback += 'Reset'; break; } if ( elem.timer ) { elapsed = Math.abs( elem.timer.started - new Date() ); window.clearTimeout( elem.timer.clock ); } elem.timer = { started: new Date() }; elem.timer.clock = window.setTimeout(function() { elem.config[ callback ]( elem.domEl ); elem.timer = null; }, duration - elapsed ); return type === 'reveal' ? elem.revealed = true : elem.revealed = false; } }; ScrollReveal.prototype.getContainerSize = function( container ){ if ( !container ) { container = window.document.documentElement; } var w = container['clientWidth'] || 0; var h = container['clientHeight'] || 0; return { width: w, height: h }; }; ScrollReveal.prototype.getScrolled = function( container ){ if ( !container ) { return { x: window.pageXOffset, y: window.pageYOffset }; } else { var offset = sr.getOffset( container ); return { x: container.scrollLeft + offset.left, y: container.scrollTop + offset.top }; } }; ScrollReveal.prototype.getOffset = function( domEl ) { var offsetTop = 0; var offsetLeft = 0; do { if ( !isNaN( domEl.offsetTop ) ) { offsetTop += domEl.offsetTop; } if ( !isNaN( domEl.offsetLeft ) ) { offsetLeft += domEl.offsetLeft; } } while ( domEl = domEl.offsetParent ); return { top: offsetTop, left: offsetLeft }; }; ScrollReveal.prototype.isElemVisible = function( elem ){ var offset = sr.getOffset( elem.domEl ); var container = sr.getContainerSize( elem.config.container ); var scrolled = sr.getScrolled( elem.config.container ); var vF = elem.config.viewFactor; var elemHeight = elem.domEl.offsetHeight; var elemWidth = elem.domEl.offsetWidth; var elemTop = offset.top; var elemBottom = elemTop + elemHeight; var elemLeft = offset.left; var elemRight = elemLeft + elemWidth; return ( confirmBounds() || isPositionFixed() ); function confirmBounds(){ var top = elemTop + elemHeight * vF; var bottom = elemBottom - elemHeight * vF; var left = elemLeft + elemWidth * vF; var right = elemRight - elemWidth * vF; var viewTop = scrolled.y + elem.config.viewOffset.top; var viewBottom = scrolled.y - elem.config.viewOffset.bottom + container.height; var viewLeft = scrolled.x + elem.config.viewOffset.left; var viewRight = scrolled.x - elem.config.viewOffset.right + container.width; return ( top < viewBottom ) && ( bottom > viewTop ) && ( left > viewLeft ) && ( right < viewRight ); } function isPositionFixed(){ return ( window.getComputedStyle( elem.domEl ).position === 'fixed' ); } }; ScrollReveal.prototype.sync = function() { if ( sr.history.length ) { for ( var i = 0; i < sr.history.length; i++ ) { var record = sr.history[ i ]; sr.reveal( record.selector, record.config, true ); }; } else { console.warn('sync() failed: no reveals found.'); } return sr; }; return ScrollReveal; })(); var Tools = (function() { Tools.prototype.isObject = function( object ) { return object !== null && typeof object === 'object' && object.constructor == Object; }; Tools.prototype.forOwn = function( object, callback ) { if ( !this.isObject( object ) ){ throw new TypeError( 'Expected \'object\', but received \'' + typeof object + '\'.' ); } else { for ( var property in object ) { if ( object.hasOwnProperty( property ) ) { callback( property ); } } } }; Tools.prototype.extend = function( target, source ) { this.forOwn( source, function( property ) { if ( this.isObject( source[ property ] ) ) { if ( !target[ property ] || !this.isObject( target[ property ] ) ) { target[ property ] = {}; } this.extend( target[ property ], source[ property ] ); } else { target[ property ] = source[ property ]; } }.bind( this )); return target; }; Tools.prototype.extendClone = function( target, source ) { return this.extend( this.extend( {}, target ), source ); }; Tools.prototype.isMobile = function() { return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ); }; Tools.prototype.browserSupports = function( feature ) { var sensor = document.createElement('sensor'); var cssPrefix = 'Webkit,Moz,O,'.split(','); var tests = ( feature + cssPrefix.join( feature + ',' ) ).split(','); for ( var i = 0; i < tests.length; i++ ){ if ( !sensor.style[ tests[ i ] ] === '' ) { return false; } } return true; }; function Tools(){}; return Tools; })(); var _requestAnimationFrame = this.requestAnimationFrame || this.webkitRequestAnimationFrame || this.mozRequestAnimationFrame; }).call( this ); return ScrollReveal; }));