Explorar el Código

support for fading in unmatched auto-animate elements

Hakim El Hattab hace 5 años
padre
commit
15e6994569
Se han modificado 4 ficheros con 94 adiciones y 10 borrados
  1. 9 0
      css/reveal.css
  2. 12 0
      css/reveal.scss
  3. 72 9
      js/reveal.js
  4. 1 1
      test/examples/auto-animate.html

+ 9 - 0
css/reveal.css

@@ -1226,6 +1226,15 @@ body {
 .reveal[data-transition-speed="slow"] > .backgrounds .slide-background {
   transition-duration: 1200ms; }
 
+/*********************************************
+ * AUTO ANIMATE
+ *********************************************/
+.reveal section[data-auto-animate] [data-auto-animate-unmatched="fade-in"] {
+  opacity: 0; }
+
+.reveal section[data-auto-animate="running"] [data-auto-animate-unmatched="fade-in"] {
+  opacity: 1; }
+
 /*********************************************
  * OVERVIEW
  *********************************************/

+ 12 - 0
css/reveal.scss

@@ -1310,6 +1310,18 @@ $controlsArrowAngleActive: 36deg;
 }
 
 
+/*********************************************
+ * AUTO ANIMATE
+ *********************************************/
+
+.reveal section[data-auto-animate] [data-auto-animate-unmatched="fade-in"] {
+	opacity: 0;
+}
+.reveal section[data-auto-animate="running"] [data-auto-animate-unmatched="fade-in"] {
+	opacity: 1;
+}
+
+
 /*********************************************
  * OVERVIEW
  *********************************************/

+ 72 - 9
js/reveal.js

@@ -1431,9 +1431,8 @@
 		toArray( dom.slides.querySelectorAll( '[data-auto-animate]:not([data-auto-animate=""])' ) ).forEach( function( element ) {
 			element.dataset.autoAnimate = '';
 		} );
-		toArray( dom.wrapper.querySelectorAll( '[data-auto-animate-target]' ) ).forEach( function( element ) {
-			delete element.dataset.autoAnimateTarget;
-		} );
+
+		removeEphemeralAutoAnimateAttributes();
 
 		if( autoAnimateStyleSheet && autoAnimateStyleSheet.parentNode ) {
 			autoAnimateStyleSheet.parentNode.removeChild( autoAnimateStyleSheet );
@@ -3849,10 +3848,8 @@
 			autoAnimateStyleSheet.innerHTML = '';
 		}
 
-		// Clean up from previous animations
-		toArray( document.querySelectorAll( '[data-auto-animate-target]' ) ).forEach( function( element ) {
-			delete element.dataset.autoAnimateTarget;
-		} );
+		// Clean up after prior animations
+		removeEphemeralAutoAnimateAttributes();
 
 		var slideOptions = getAutoAnimateOptions( toSlide, {
 
@@ -3868,9 +3865,21 @@
 		toSlide.dataset.autoAnimate = 'pending';
 
 		// Inject our auto-animate styles for this transition
-		autoAnimateStyleSheet.innerHTML = getAutoAnimatableElements( fromSlide, toSlide ).map( function( elements ) {
+		var css = getAutoAnimatableElements( fromSlide, toSlide ).map( function( elements ) {
 			return getAutoAnimateCSS( elements.from, elements.to, elements.options || {}, slideOptions, autoAnimateCounter++ );
-		} ).join( '' );
+		} );
+
+		// If the slide is configured to animate unmatched elements we
+		// need to flag them
+		if( toSlide.dataset.autoAnimateUnmatched ) {
+			getUnmatchedAutoAnimateElements( toSlide ).forEach( function( unmatchedElement ) {
+				unmatchedElement.dataset.autoAnimateUnmatched = 'fade-in';
+			} );
+
+			css.push( '.reveal [data-auto-animate="running"] [data-auto-animate-unmatched] { transition: all '+ (slideOptions.duration*0.8) +'s ease '+ (slideOptions.duration*0.2) +'s; }' );
+		}
+
+		autoAnimateStyleSheet.innerHTML = css.join( '' );
 
 		// Start the animation next cycle
 		requestAnimationFrame( function() {
@@ -3879,6 +3888,22 @@
 
 	}
 
+	/**
+	 * Removes all attributes that we temporarily add to slide
+	 * elements in order to carry out auto-animation.
+	 */
+	function removeEphemeralAutoAnimateAttributes() {
+
+		toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack) [data-auto-animate-target]' ) ).forEach( function( element ) {
+			delete element.dataset.autoAnimateTarget;
+		} );
+
+		toArray( dom.wrapper.querySelectorAll( SLIDES_SELECTOR + ':not(.stack) [data-auto-animate-unmatched]' ) ).forEach( function( element ) {
+			delete element.dataset.autoAnimateUnmatched;
+		} );
+
+	}
+
 	/**
 	 * Auto-animates the properties of an element from their original
 	 * values to their new state.
@@ -4139,6 +4164,44 @@
 
 	}
 
+	/**
+	 * Returns a all elements within the given scope that should
+	 * be considered unmatched in an auto-animate transition. If
+	 * fading of unmatched elements is turnded on, these elements
+	 * will fade when going between auto-aniamted slides.
+	 *
+	 * Note that parents of auto-animate targets are NOT considerd
+	 * unmatched since fading them would break the auto-animation.
+	 *
+	 * @param {HTMLElement} rootElement
+	 * @return {Array}
+	 */
+	function getUnmatchedAutoAnimateElements( rootElement ) {
+
+		return [].slice.call( rootElement.children ).reduce( function( result, element ) {
+
+			// If the element is auto-animated we can stop looking at this tree
+			if( !element.hasAttribute( 'data-auto-animate-target' ) ) {
+
+				// If this element contains an auto-animated element it's considered
+				// a match since we can't fade it without affecting the inner
+				// auto-animate target
+				if( !element.querySelector( '[data-auto-animate-target]' ) ) {
+					result.push( element );
+				}
+				else {
+					// Keep looking down this tree
+					result = result.concat( getUnmatchedAutoAnimateElements( element ) );
+				}
+
+			}
+
+			return result;
+
+		}, [] );
+
+	}
+
 	/**
 	 * Should the given element be preloaded?
 	 * Decides based on local element attributes and global config.

+ 1 - 1
test/examples/auto-animate.html

@@ -19,7 +19,7 @@
 
 			<div class="slides">
 
-				<section data-auto-animate>
+				<section data-auto-animate data-auto-animate-unmatched="fade">
 					<h3>Auto-Animate Example</h3>
 					<p>This will fade out</p>
 					<img src="assets/image1.png" style="height: 100px;">