Text orientation change animation
by ShaCP
HTML
<div id="one">
<span>Hello</span>
</div>
CSS
#one {
width: 100px;
height: 100px;
background-color: lightskyblue;
position: relative;
animation: 3s linear forwards;
margin-top: 100px;
writing-mode: vertical-lr;
text-orientation: upright;
letter-spacing: -1px;
}
body {
margin: 0;
}
#one.play {
animation-name: move;
}
#one.play span {
animation: move-text 3s forwards;
display: inline-block;
}
#one.off {
writing-mode: unset;
text-orientation: unset;
letter-spacing: unset;
background-color: red;
}
@keyframes move {
100% {
transform: translate(300px);
margin: 0;
}
}
@keyframes move-text {
50% {
transform: scale(0);
}
}
JavaScript
one.addEventListener("click", (e) => {
e.target.classList.toggle("play");
e.target.classList.remove("off");
})
/* one.addEventListener("animationend", (e) => e.target.classList.toggle("play")) */
one.addEventListener("animationstart", (e) => {
console.log("START")
if (e.animationName === "move-text") {
window.requestAnimationFrame(step);
}
})
/* one.addEventListener("animationend", () => e.target.classList.toggle("off")) */
let i = 0;
const duration = 2000;
const element = document.getElementById("one");
let start;
let reqId;
/* this is the reliable way to do something at some point
during an animation, setTimeout can have sync issues */
function step(timestamp) {
console.log("timestamp", timestamp);
if (start === undefined)
start = timestamp;
const elapsed = timestamp - start;
console.log("elapsed", elapsed, i++);
// `Math.min()` is used here to make sure that the element stops at exactly 200px.
console.log(0.1 * elapsed)
/* element.style.transform = 'translateX(' + Math.min(0.1 * elapsed, 200) + 'px)' */
;
if (elapsed > duration / 2) {
console.log('toggle')
one.classList.toggle("off");
start = undefined;
console.log('reqId', reqId);
} else {
reqId = window.requestAnimationFrame(step);
}
/* if (elapsed < duration) { // Stop the animation after 2 seconds
window.requestAnimationFrame(step);
} else {
console.log("end")
} */
}