auto-animate; carry forward fragment visibility, unmatched elements adhere to duration/delay attributes
							parent
							
								
									376b8230bb
								
							
						
					
					
						commit
						4d1cb43faf
					
				|  | @ -45,6 +45,10 @@ body { | ||||||
| 		opacity: 1; | 		opacity: 1; | ||||||
| 		visibility: inherit; | 		visibility: inherit; | ||||||
| 	} | 	} | ||||||
|  | 
 | ||||||
|  | 	&.disabled { | ||||||
|  | 		transition: none; | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .reveal .slides section .fragment.grow { | .reveal .slides section .fragment.grow { | ||||||
|  |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -38,9 +38,13 @@ export default class AutoAnimate { | ||||||
| 			fromSlide.dataset.autoAnimate = 'pending'; | 			fromSlide.dataset.autoAnimate = 'pending'; | ||||||
| 			toSlide.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
 | 			// Inject our auto-animate styles for this transition
 | ||||||
| 			let css = this.getAutoAnimatableElements( fromSlide, toSlide ).map( elements => { | 			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
 | 			// Animate unmatched elements, if enabled
 | ||||||
|  | @ -124,8 +128,9 @@ export default class AutoAnimate { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Auto-animates the properties of an element from their original | 	 * Creates a FLIP animation where the `to` element starts out | ||||||
| 	 * values to their new state. | 	 * in the `from` element position and animates to its original | ||||||
|  | 	 * state. | ||||||
| 	 * | 	 * | ||||||
| 	 * @param {HTMLElement} from | 	 * @param {HTMLElement} from | ||||||
| 	 * @param {HTMLElement} to | 	 * @param {HTMLElement} to | ||||||
|  | @ -134,7 +139,7 @@ export default class AutoAnimate { | ||||||
| 	 * @param {String} id Unique ID that we can use to identify this | 	 * @param {String} id Unique ID that we can use to identify this | ||||||
| 	 * auto-animate element in the DOM | 	 * 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,
 | 		// '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
 | 		// '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 ), | 		let fromProps = this.getAutoAnimatableProperties( 'from', from, elementOptions ), | ||||||
| 			toProps = this.getAutoAnimatableProperties( 'to', to, 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
 | 		// If translation and/or scaling are enabled, css transform
 | ||||||
| 		// the 'to' element so that it matches the position and size
 | 		// the 'to' element so that it matches the position and size
 | ||||||
| 		// of the 'from' element
 | 		// of the 'from' element
 | ||||||
|  |  | ||||||
|  | @ -63,8 +63,8 @@ export default class Fragments { | ||||||
| 
 | 
 | ||||||
| 		let currentSlide = this.Reveal.getCurrentSlide(); | 		let currentSlide = this.Reveal.getCurrentSlide(); | ||||||
| 		if( currentSlide && this.Reveal.getConfig().fragments ) { | 		if( currentSlide && this.Reveal.getConfig().fragments ) { | ||||||
| 			let fragments = currentSlide.querySelectorAll( '.fragment' ); | 			let fragments = currentSlide.querySelectorAll( '.fragment:not(.disabled)' ); | ||||||
| 			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.visible)' ); | 			let hiddenFragments = currentSlide.querySelectorAll( '.fragment:not(.disabled):not(.visible)' ); | ||||||
| 
 | 
 | ||||||
| 			return { | 			return { | ||||||
| 				prev: fragments.length - hiddenFragments.length > 0, | 				prev: fragments.length - hiddenFragments.length > 0, | ||||||
|  | @ -291,12 +291,12 @@ export default class Fragments { | ||||||
| 		let currentSlide = this.Reveal.getCurrentSlide(); | 		let currentSlide = this.Reveal.getCurrentSlide(); | ||||||
| 		if( currentSlide && this.Reveal.getConfig().fragments ) { | 		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( fragments.length ) { | ||||||
| 
 | 
 | ||||||
| 				// If no index is specified, find the current
 | 				// If no index is specified, find the current
 | ||||||
| 				if( typeof index !== 'number' ) { | 				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 ) { | 					if( lastVisibleFragment ) { | ||||||
| 						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); | 						index = parseInt( lastVisibleFragment.getAttribute( 'data-fragment-index' ) || 0, 10 ); | ||||||
|  |  | ||||||
|  | @ -42,6 +42,22 @@ | ||||||
| 					<h1>Non-auto-animate slide</h1> | 					<h1>Non-auto-animate slide</h1> | ||||||
| 				</section> | 				</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> | ||||||
| 
 | 
 | ||||||
| 		</div> | 		</div> | ||||||
|  | @ -119,6 +135,21 @@ | ||||||
| 					Reveal.configure({ autoAnimate: true }); | 					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> | 		</script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Hakim El Hattab
						Hakim El Hattab