skip to Main Content

so I’m doing a simple css text animation, and is getting delayed at the end for god know’s 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 below:

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>

2

Answers


  1. 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>
    Login or Signup to reply.
  2. 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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search