JSFiddle - React, Tailwind, and code Playground
by Glenn Marks
HTML
<div id=target></div>
<button id=show type=button>Show</button>
<button id=hide type=button>Hide</button>
<p><strong>Reversed:</strong> <span id=reversed>false</span></p>
<p><strong>Playing:</strong> <span id=playing>false</span></p>
<pre><code>
<strong>As you can see, the opacity flickers</strong>
-----------------------------------------------------------------------
<strong>Note for Chrome:</strong> When animation is reversed,
an external event is required to update the finished state,
eg. pointer move or key down event.
There is a bug filed (<a href="https://bugs.chromium.org/p/chromium/issues/detail?id=1141935">star it</a>)
<!-- This is actually where i got most of this code from 😁 -->
</code></pre>
<p><b>Proposal</b></p>
<pre><code>
<span style=color:green>// Proposal usage example</span>
animation.onstart = () => {
var isReverse = animation.playbackrate === -1;
target.style.opacity =
isReverse
? "1"
: "0";
playing.innerText = 'true'
playing.style.cssText += '--color: green'
reversed.innerText = isReverse.toString();
reversed.style.cssText += isReverse
? '--color: green'
: '--color: red';
};
</code></pre>
CSS
div {
width: 100px;
height: 100px;
background-color: black;
}
span {
color: var(--color, red);
}
JavaScript
const sustainOpacity = (direction) => {
target.style.opacity = direction === "forward" ?
"1" :
"0";
}
const animation =
target.animate({
opacity: [0, 1]
}, {
delay: 1000,
endDelay: 1000,
duration: 1000
});
animation.onfinish = () => {
sustainOpacity(target.dataset.direction);
playing.innerText = 'false'
playing.style.cssText += '--color:red'
};
animation.finish();
show.onclick = () => {
if (animation.playbackRate === 1) {
animation.play();
} else {
animation.reverse();
}
animationStart(false); // <= Drop this under new proposal
}
hide.onclick = () => {
if (animation.playbackRate === 1) {
animation.reverse();
} else {
animation.play();
}
animationStart(true); // <= Drop this under new proposal
}
// DROP THIS AS WELL
const animationStart = (isReverse) => {
target.dataset.direction = isReverse ?
"reverse" :
"forward";
target.style.opacity =
target.dataset.direction === "forward" ?
"0" :
"1";
playing.innerText = 'true'
playing.style.cssText += '--color: green'
reversed.innerText = isReverse.toString();
reversed.style.cssText += isReverse ?
'--color: green' :
'--color: red';
}