我正在创建一个简单的CSS文本动画,但最后却被延迟了,天知道为什么,我非常累,只需要完成这项工作。
基本上我有一个带有
<text>
标签的 SVG,里面有“Fussi's”,我只是想为加载页面稍微动画一下这个词。我尝试了一些Stroke-DashOffset和Stroke-DashArray,动画本身工作正常,但是当达到100%时,需要延迟才能回到0%
同样,问题本身是当第一个循环结束(向前动画)但需要一段时间才能开始向后动画。
这是我的代码:
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>
“延迟”实际上发生在动画的开始,而不是结束。发生的情况是
stroke-dashoffset
的初始 0
值太小 — 笔划实际上在开始时就被缠绕了。结果,它实际上在这段时间内处于动画状态,但没有视觉变化,因为它本质上是在消除冗余。这样做的效果是,当动画交替时,“延迟”时间会增加两倍。
解决方案
你只需要找到正确的开始
stroke-dashoffset
通过反复试验,我将初始值更改为91
,这似乎有效(为什么?说实话,我不确定。我只知道问题出在哪里)是但不知道数学问题)。
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>
这里真正的问题是确定正确的
stroke-dasharray
属性值。互联网上的一些资源建议使用 Inkscape,例如,将文本导出为 SVG 路径,然后在 SVG 路径 DOM 对象上运行 getTotalLength()
javascript 方法。
我找到了另一种更实用的方法:在启用动画之前,从较低的
stroke-dasharray
值开始,然后在开发工具检查器上逐像素增量地手动调整值(您可以使用键盘箭头来实现这样的效果) ),然后当笔划填满整个文本时停止。这更容易,您可以利用 text
而不是 path
。
找到这个幻数后,您可以启用动画,在动画
stroke-dashoffset
状态上将 100%
设置为该值。
作为示例,请查看下面的代码,其中我设置了较大的笔画宽度以方便查看,并在文本字体大小上任意设置
4rem
。
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>