Search code examples
cssanimationcss-animationssvg-animatestroke-dasharray

Unknown delay between infinite alternate css animation's


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>

Solution

  • 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>