Google 的 Material Design 旋转器在旋转时收缩和拉伸(stretch):
我发现以下 SVG 微调器可以很好地实现它:https://codepen.io/svnt/pen/qraaRN .
HTML:
<svg class="spinner" viewBox="0 0 50 50"><circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle></svg>
CSS:
/* SVG spinner icon animation */
.spinner {
-webkit-animation: rotate 2s linear infinite;
animation: rotate 2s linear infinite;
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
margin: -25px 0 0 -25px;
width: 50px;
height: 50px;
}
.spinner .path {
stroke: #cccccc;
stroke-linecap: round;
-webkit-animation: dash 1.5s ease-in-out infinite;
animation: dash 1.5s ease-in-out infinite;
}
@-webkit-keyframes rotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@keyframes rotate {
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
@-webkit-keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
@keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
问题是,@keyframes
动画使用了 stroke-dasharray
和 stroke-dashoffset
,它们似乎在主 UI 线程上运行如果我在动画运行时使用 JavaScript 执行一些任务,微调器会失去其平滑度并变得不稳定。
旋转(通过 transform
)效果很好,我知道它运行在 UI 线程之外,所以即使我执行一些 JS 任务,旋转也会在动画时平滑。
当然,我可以只实现一个没有拉伸(stretch)/收缩功能的旋转微调器,但我想知道你们中是否有人知道如何使此类动画看起来始终流畅。有没有办法在旋转时使用 transform
拉伸(stretch)和收缩微调器?
希望我说清楚了。感谢关注!
最佳答案
您可以使用不同的元素来模拟这一点,其中的想法是使用另一个隐藏第一个元素。唯一的缺点是透明度。
这是一个示例,您可以在其中调整不同的值以获得所需的动画。为简单起见使用了 CSS 变量,但这不是强制性的。
.loading {
width:50px;
height:50px;
position:fixed;
top:calc(50% - 25px);
left:calc(50% - 25px);
border-radius:50%;
border:5px solid blue;
animation:load 2s linear infinite;
}
.loading:before,
.loading:after,
.loading span:before,
.loading span:after{
content:"";
position:absolute;
top:-6px;
left:-6px;
right:-6px;
bottom:-6px;
border-radius:50%;
border:7px solid transparent;
border-left-color:white;
animation:hide 1.2s infinite;
}
.loading span:before {
--r:90deg;
}
.loading span:after {
--r:180deg;
}
.loading:before {
--r:260deg; /* a little less than 270deg to keep some border visible */
}
@keyframes load {
to {
transform:rotate(360deg);
}
}
@keyframes hide {
50% {
transform:rotate(var(--r,0deg));
}
100% {
transform:rotate(360deg);
}
}
<div class="loading">
<span></span>
</div>
使用透明度,您可以使用 4 个元素创建边框,您可以旋转这些元素使它们彼此重叠并缩小整体形状。基本上和第一段代码相反的逻辑(我们把蓝色的变成透明的,白色的变成蓝色的)
唯一的缺点是你不能收缩小于一侧的长度
.loading {
width:50px;
height:50px;
position:fixed;
top:calc(50% - 25px);
left:calc(50% - 25px);
animation:load 2s linear infinite;
}
.loading:before,
.loading:after,
.loading span:before,
.loading span:after{
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
border-radius:50%;
border:5px solid transparent;
border-left-color:blue;
animation:hide 1.2s infinite;
}
.loading span:before {
--r:90deg;
}
.loading span:after {
--r:180deg;
}
.loading:before {
--r:200deg;
}
@keyframes load {
to {
transform:rotate(360deg);
}
}
@keyframes hide {
50% {
transform:rotate(var(--r,0deg));
}
100% {
transform:rotate(360deg);
}
}
body {
background:linear-gradient(to right,pink,orange);
}
<div class="loading">
<span></span>
</div>
为了更好地理解这两个代码中发生的事情,删除主旋转并为边框使用不同的颜色
.loading {
width:50px;
height:50px;
position:fixed;
top:calc(50% - 25px);
left:calc(50% - 25px);
/* animation:load 2s linear infinite;*/
}
.loading:before,
.loading:after,
.loading span:before,
.loading span:after{
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:-0;
border-radius:50%;
border:5px solid transparent;
border-left-color:blue;
animation:hide 4s infinite;
}
.loading span:before {
--r:90deg;
border-left-color:red;
}
.loading span:after {
--r:180deg;
border-left-color:green;
}
.loading:before {
--r:260deg;
border-left-color:yellow;
}
@keyframes load {
to {
transform:rotate(360deg);
}
}
@keyframes hide {
50% {
transform:rotate(var(--r,0deg));
}
100% {
transform:rotate(360deg);
}
}
body {
background:linear-gradient(to right,pink,orange);
}
<div class="loading">
<span></span>
</div>
关于javascript - 如何平滑地拉伸(stretch)和收缩旋转线弧?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57774970/