Issue
I have the below code to begin an animation for an acronym that makes the code transform to a vertical form. I'd like to have it where it will type the rest of the acronym out next to the letters on the button click. However doing so adds far to much space between all the type I want them to basically line up how they do before the button is pressed you can see what it currently does here:
var a = 0;
var b = 0;
var c = 0;
var d = 0;
var e = 0;
var f = 0;
var balance = 'alance';
var execution = 'xecution';
var teamwork = 'eamwork';
var training = 'raining';
var experience = 'xperience';
var results = 'esults';
var speed = 50;
function typeWriter() {
while (a < balance.length) {
document.getElementById("balance").innerHTML += balance.charAt(a);
a++;
setTimeout(typeWriter, speed);
}
while (b < execution.length) {
document.getElementById("execution").innerHTML += execution.charAt(b);
b++;
setTimeout(typeWriter, speed);
}
while (c < teamwork.length) {
document.getElementById("teamwork").innerHTML += teamwork.charAt(c);
c++;
setTimeout(typeWriter, speed);
}
while (d < training.length) {
document.getElementById("training").innerHTML += training.charAt(d);
d++;
setTimeout(typeWriter, speed);
}
while (e < experience.length) {
document.getElementById("experience").innerHTML += experience.charAt(e);
e++;
setTimeout(typeWriter, speed);
}
while (f < results.length) {
document.getElementById("results").innerHTML += results.charAt(f);
f++;
setTimeout(typeWriter, speed);
}
}
function scroller() {
var move = document.querySelectorAll(".move");
var fade = document.querySelectorAll(".fade");
for (var i = 0; i < move.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = move[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
move[i].classList.add("active");
} else {
move[i].classList.remove("active");
}
}
for (var i = 0; i < fade.length; i++) {
var windowHeight = window.innerHeight;
var elementTop = fade[i].getBoundingClientRect().top;
var elementVisible = 0;
if (elementTop < windowHeight - elementVisible) {
fade[i].classList.add("active");
} else {
fade[i].classList.remove("active");
}
}
}
window.addEventListener("scroll", scroller);
.move {
font-size: 105px;
position: relative;
}
.move.active {
font-size: 105px;
position: relative;
animation: mover 5s ease 0s normal forwards;
}
.fade {
font-size: 105px;
position: relative;
}
.fade.active {
font-size: 105px;
position: relative;
animation: fader 2s ease 0s normal forwards;
}
.move.active span {
margin: 0px;
position: relative;
display: inline-block;
animation: rotate 5s ease 0s normal forwards;
}
@keyframes mover {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(-20%, 300px) skew(0deg) rotate(90deg);
}
}
@keyframes rotate {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
transform: scale(1) translate(0px, 0px) skew(0deg) rotate(-90deg);
}
}
@keyframes fader {
0.0% {
transform: scale(1) translate(-0px, 0) skew(0deg);
}
100% {
opacity: 0;
}
}
@keyframes typing {
0% {
width: 0%
}
100% {
width: 100%
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<CENTER>
<h2 class="fade">IT'S </h2>
<h2 class="move">
<span id="balance">B</span>
<span id="execution">E</span>
<span id="teamwork">T</span>
<span id="training">T</span>
<span id="experience">E</span>
<span id="results">R</span>
</h2>
<h2 class="fade">TOGETHER </h2>
</CENTER>
<button onclick="typeWriter()">Click me</button>
https://noahark.w3spaces.com/saved-from-Tryit-2022-04-29.html
Any and all help will be extremely appreciated.
Solution
In your particular example, the spacing is coming from the lengths of the words. When I undo the rotation caused by the animation, we can see this:
So, if you force the length of the word to be one character (regardless of how many characters are actually there), then you no longer have the spacing problem caused by the words' length.
.move span {
display: inline-block;
width: 1.5ch;
}
Although forcing the span's width works, it can feel a little naughty. We're now relying on nice overflow behaviour, and hopefully we don't need the true width of the element for anything else.
I found that I didn't have to force width if we start at the end rather than the beginning. By default (no transform applied), it is already arranged as a column of words exactly like what you want at the end of the animation.
Then, you apply the 90 degree rotation to get the horizontal "BETTER" text. The animation undoes the rotation, meaning you always get what you expect at the end.
const betterAcronym = document.querySelector('#better-acronym')
const revealButton = document.querySelector('#reveal-button')
const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const typeElement = async (element) => {
const word = element.dataset['word']
const start = element.textContent.length
for (let c = start; c < word.length; ++c) {
element.textContent += word[c]
await wait(100)
}
}
revealButton.addEventListener('click', async () => {
betterAcronym.classList.add('revealed')
await wait(2750) // length of the animation plus some
Array.from(betterAcronym.children).forEach(typeElement)
})
.acronym {
font-size: 1.25rem;
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-direction: column;
transform: rotate(-90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym > li {
display: inline-block;
transform: rotate(90deg);
transform-origin: 0.5em 0.5em;
transition: transform 2.5s ease-in-out;
}
.acronym.revealed {
transform: rotate(0deg);
}
.acronym.revealed > li {
transform: rotate(0deg);
}
body {
overflow: hidden;
}
button {
font-size: 1.25rem;
}
<ol id="better-acronym" class="acronym">
<li data-word="balance">B</li>
<li data-word="execution">E</li>
<li data-word="teamwork">T</li>
<li data-word="training">T</li>
<li data-word="experience">E</li>
<li data-word="results">R</li>
</ol>
<button id="reveal-button">Reveal</button>
Answered By - Auroratide
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.