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;
position: absolute;
left: 150px;
display: none;
}
span {
color: var(--color, red);
}
JavaScript
const animation =
new Animation(new KeyframeEffect(
target,
[
{ opacity: 0, display: "none" },
{ opacity: 1, display: "block" },
], {
delay: 1000,
endDelay: 1000,
duration: 1000
}
));
animation.effect.updateTiming({
fill: 'both'
});
animation.onfinish = () => {
animation.commitStyles();
playing.innerText = 'false'
playing.style.cssText += '--color:red'
};
target.style.display = "block";
animation.reverse();
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) => {
playing.innerText = 'true'
playing.style.cssText += '--color: green'
reversed.innerText = isReverse.toString();
reversed.style.cssText += isReverse ?
'--color: green' :
'--color: red';
}