ソースを参照

auto-animate; carry forward fragment visibility, unmatched elements adhere to duration/delay attributes

Hakim El Hattab 5 年 前
コミット
4d1cb43faf

+ 4 - 0
css/reveal.scss

@@ -45,6 +45,10 @@ body {
 		opacity: 1;
 		visibility: inherit;
 	}
+
+	&.disabled {
+		transition: none;
+	}
 }
 
 .reveal .slides section .fragment.grow {

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/reveal.css


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/reveal.min.js


+ 24 - 4
js/controllers/autoanimate.js

@@ -38,9 +38,13 @@ export default class AutoAnimate {
 			fromSlide.dataset.autoAnimate = 'pending';
 			toSlide.dataset.autoAnimate = 'pending';
 
+			// Flag the navigation direction, needed for fragment buildup
+			let allSlides = this.Reveal.getSlides();
+			animationOptions.slideDirection = allSlides.indexOf( toSlide ) > allSlides.indexOf( fromSlide ) ? 'forward' : 'backward';
+
 			// Inject our auto-animate styles for this transition
 			let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => {
-				return this.getAutoAnimateCSS( elements.from, elements.to, elements.options || {}, animationOptions, this.autoAnimateCounter++ );
+				return this.autoAnimateElements( elements.from, elements.to, elements.options || {}, animationOptions, this.autoAnimateCounter++ );
 			} );
 
 			// Animate unmatched elements, if enabled
@@ -124,8 +128,9 @@ export default class AutoAnimate {
 	}
 
 	/**
-	 * Auto-animates the properties of an element from their original
-	 * values to their new state.
+	 * Creates a FLIP animation where the `to` element starts out
+	 * in the `from` element position and animates to its original
+	 * state.
 	 *
 	 * @param {HTMLElement} from
 	 * @param {HTMLElement} to
@@ -134,7 +139,7 @@ export default class AutoAnimate {
 	 * @param {String} id Unique ID that we can use to identify this
 	 * auto-animate element in the DOM
 	 */
-	getAutoAnimateCSS( from, to, elementOptions, animationOptions, id ) {
+	autoAnimateElements( from, to, elementOptions, animationOptions, id ) {
 
 		// 'from' elements are given a data-auto-animate-target with no value,
 		// 'to' elements are are given a data-auto-animate-target with an ID
@@ -154,6 +159,21 @@ export default class AutoAnimate {
 		let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ),
 			toProps = this.getAutoAnimatableProperties( 'to', to, elementOptions );
 
+		// Maintain fragment visibility for matching elements when
+		// we're navigating forwards, this way the viewer won't need
+		// to step through the same fragments twice
+		if( to.classList.contains( 'fragment' ) ) {
+
+			// Don't auto-animate the opacity of fragments to avoid
+			// conflicts with fragment animations
+			delete toProps.styles['opacity'];
+
+			if( from.classList.contains( 'fragment' ) && animationOptions.slideDirection === 'forward' ) {
+				to.classList.add( 'visible', 'disabled' );
+			}
+
+		}
+
 		// If translation and/or scaling are enabled, css transform
 		// the 'to' element so that it matches the position and size
 		// of the 'from' element

+ 4 - 4
js/controllers/fragments.js

@@ -63,8 +63,8 @@ export default class Fragments {
 
 		let currentSlide = this.Reveal.getCurrentSlide();
 		if( currentSlide && this.Reveal.getConfig().fragments ) {
-			let fragments = currentSlide.querySelectorAll( '.fragment' );
-			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' );
+			let fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' );
+			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' );
 
 			return {
 				prev: fragments.length - hiddenFragments.length > 0,
@@ -291,12 +291,12 @@ export default class Fragments {
 		let currentSlide = this.Reveal.getCurrentSlide();
 		if( currentSlide && this.Reveal.getConfig().fragments ) {
 
-			let fragments = this.sort( currentSlide.querySelectorAll( '.fragment' ) );
+			let fragments = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled)' ) );
 			if( fragments.length ) {
 
 				// If no index is specified, find the current
 				if( typeof index !== 'number' ) {
-					let lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment.visible' ) ).pop();
+					let lastVisibleFragment = this.sort( currentSlide.querySelectorAll( '.fragment:not(.disabled).visible' ) ).pop();
 
 					if( lastVisibleFragment ) {
 						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 );

+ 31 - 0
test/test-auto-animate.html

@@ -42,6 +42,22 @@
 					<h1>Non-auto-animate slide</h1>
 				</section>
 
+				<section data-auto-animate>
+					<h1 class="fragment">h1</h1>
+					<h2 class="fragment">h2</h2>
+					<h3>h3</h3>
+				</section>
+
+				<section data-auto-animate>
+					<h1 class="fragment">h1</h1>
+					<h2 class="fragment">h2</h2>
+					<h3 class="fragment">h3</h3>
+				</section>
+
+				<section>
+					<h1>Non-auto-animate slide</h1>
+				</section>
+
 			</div>
 
 		</div>
@@ -119,6 +135,21 @@
 					Reveal.configure({ autoAnimate: true });
 				});
 
+				QUnit.test( 'Carries forward matching fragment visibility', assert => {
+					Reveal.slide(4);
+					assert.ok( !slides[5].h1.classList.contains( 'visible' ) )
+					Reveal.next();
+					Reveal.next();
+					Reveal.next();
+					assert.ok( slides[5].h1.classList.contains( 'visible' ) )
+					assert.ok( slides[5].h2.classList.contains( 'visible' ) )
+					assert.ok( !slides[5].h3.classList.contains( 'visible' ) )
+					Reveal.next();
+					assert.ok( slides[5].h3.classList.contains( 'visible' ) )
+					Reveal.next();
+					assert.ok( slides[6].slide === Reveal.getCurrentSlide() )
+				});
+
 			} );
 		</script>
 

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません