Reputation: 53
I'm creating a simple css text animation, and is getting delayed at the end for god knows why, I'm am extremely tired and only need to make this work.
Basically I have a SVG with a <text>
tag with "Fussi's" inside, and I just want to animate this word a little bit for a loading page. I played around with some stroke-dashoffset and stroke-dasharray, and the animation itself works fine, but when it comes to 100%, it takes a delay to go back to 0%
Again, the problem itself is when the first loop end (the forward animation) but it takes a while to start the backwards animation.
Here's my code:
body {
box-sizing: border-box;
margin: 0;
background-color: white;
}
#loading {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
font-family: 'Leckerli One', cursive;
font-size: x-small;
}
svg text {
fill: rgb(188, 188, 188);
stroke: black;
stroke-width: 0.5;
stroke-dasharray: 125;
stroke-dashoffset: 0;
letter-spacing: 3px;
animation: 2s infinite alternate ease-in-out animate-name;
}
@keyframes animate-name {
100% {
stroke-dashoffset: 125;
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Julius+Sans+One&family=Leckerli+One&display=swap" rel="stylesheet">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animated Background</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="loading">
<svg viewBox = "0 0 400 160">
<text x="50%" y="50%" dy=".32em" text-anchor="middle" class="text-body">
Fussi's
</text>
</svg>
</div>
</body>
</html>
Upvotes: 2
Views: 343
Reputation: 10015
The real issue here is to determine the correct stroke-dasharray
property value. Some resources on the internet suggest using Inkscape, for instance, exporting the text as SVG paths, and then running getTotalLength()
javascript method on the SVG path DOM object.
I found another, more pragmatic way, of doing so: start with a low stroke-dasharray
value, before enabling animation, and then manually tweak the value on pixel by pixel increments on devtools inspector (you can use keyboard arrows for such), and then stop when the stroke has filled the entire text. It's way easier and you can leverate your text
instead of a path
.
After finding this magic number, you can enable animation setting the stroke-dashoffset
to this value on the animation 100%
state.
As an illustration, check the code below, in which I set a larger stroke width for ease of viewing and arbitrarily set 4rem
on the text font size.
body {
box-sizing: border-box;
margin: 0;
background-color: white;
}
#loading {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
font-family: 'Leckerli One', cursive;
font-size: 4rem;
}
svg text {
fill: rgb(188, 188, 188);
stroke: black;
stroke-width: 2;
stroke-dasharray: 220;
stroke-dashoffset: 0;
letter-spacing: 3px;
animation: 3s infinite alternate linear animate-name;
}
@keyframes animate-name {
100% {
stroke-dashoffset: 220;
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Julius+Sans+One&family=Leckerli+One&display=swap" rel="stylesheet">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animated Background</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="loading">
<svg viewBox = "0 0 400 160">
<text x="50%" y="50%" dy=".32em" text-anchor="middle" class="text-body">
Fussi's
</text>
</svg>
</div>
</body>
</html>
Upvotes: 1
Reputation: 1066
The "delay" is actually occuring at the start of the animation, not the end. What's happening is that the initial stroke-dashoffset
value of 0
is too small—the stroke is actually wrapped around at the start. As result, it actually is animating during that time, but there's no visual change because it's essentially untracing that redundancy. The effect this has is that when the animation alternates, it will spend time in that "delay" twice as long.
Solution
You just need to find the correct starting stroke-dashoffset
Through trial and error, I changed the initial value to 91
and that seemed to work (why? I'm not sure, to be honest. I just knew what the problem was but didn't know the mathematical issue).
body {
box-sizing: border-box;
margin: 0;
background-color: white;
}
#loading {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
font-family: 'Leckerli One', cursive;
font-size: x-small;
}
svg text {
fill: rgb(188, 188, 188);
stroke: black;
stroke-width: 0.5;
stroke-dasharray: 125;
stroke-dashoffset: 91;
letter-spacing: 3px;
animation: 2s infinite alternate ease-in-out animate-name;
}
@keyframes animate-name {
100% {
stroke-dashoffset: 125;
}
}
<!DOCTYPE html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Julius+Sans+One&family=Leckerli+One&display=swap" rel="stylesheet">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Animated Background</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="loading">
<svg viewBox = "0 0 400 160">
<text x="50%" y="50%" dy=".32em" text-anchor="middle" class="text-body">
Fussi's
</text>
</svg>
</div>
</body>
</html>
Upvotes: 1