support for fading in unmatched auto-animate elements

master
Hakim El Hattab 2020-02-12 14:05:23 +01:00
parent 3cf08624dd
commit 15e6994569
4 changed files with 94 additions and 10 deletions

View File

@ -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
*********************************************/

View File

@ -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
*********************************************/

View File

@ -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.

View File

@ -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;">