Not sure about Tween.JS, but here's how to do it using vanilla JavaScript in order to toggle a class, and let CSS handle the rest.
The staggered characters animation effect is made possible by assigning a CSS var --anim-delay
to each character SPAN with a value of the respective SPAN index, later used in CSS as the transition-delay:
// DOM helper functions:
const el = (sel, par) => (par || document).querySelector(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);
// Staggered characters flip effect:
const elText = el("#text");
const words = ["Discover", "Swipe", "Culture"];
// Create SPANs for words and charactres
words.forEach(word => {
const elsChars = [...word].map((char, i) => {
const elChar = elNew("span", { className: "char", textContent: char });
elChar.style.setProperty("--anim-delay", i);
return elChar;
});
const elWord = elNew("span", { className: "word" });
elWord.append(...elsChars);
elText.append(elWord);
});
// Animate on pointer events:
el("body").addEventListener("pointerdown", () => {
elText.classList.add("is-pressed");
});
el("body").addEventListener("pointerup", () => {
elText.classList.remove("is-pressed");
});
#text {
display: flex;
justify-content: center;
gap: 2rem;
-webkit-font-smoothing: antialiased;
font-smoothing: antialiased;
perspective: 600px;
}
.word {
font-size: 9vw;
display: inline-flex;
pointer-events: none;
user-select: none;
}
.char {
transition:
transform 0.3s calc(var(--anim-delay) * 20ms) ease-in-out,
opacity 0.3s calc(var(--anim-delay) * 20ms) ease-in-out;
opacity: 1;
transform-origin: center center 0.4em;
}
.is-pressed .char {
transform: rotate3d(-1, -0.4, 0, 90deg);
opacity: 0;
}
(Click and hold)
<div id="text"></div>