有问题的动画是使用带有固定边框的旋转变换来创建移动边框的错觉,而实际上并非如此.使用正方形,你不能使用类似的模型,因为当我们旋转正方形时它不像圆圈那样保持不变.
所以可用的选项是使用基于SVG stroke-dashoffset的动画,如下面的代码片段所示. stroke-dasharray属性提供笔划的长度/宽度(第一个参数)和空间的长度/宽度(第二个参数). stroke-dashoffset属性指定应该绘制笔划的起始位置的偏移量.
polygon {
stroke: red;
stroke-width: 3;
stroke-dasharray: 50, 750;
stroke-dashoffset: 0;
fill: none;
animation: border 5s linear infinite;
}
@keyframes border {
to {
stroke-dashoffset: -800;
}
}
如果您需要纯CSS解决方案,那么您可以使用基于线性渐变的解决方案,如下面的代码段所示.在这里,我们基于线性渐变创建四条背景图像,这些渐变具有相同的边框厚度.这些条带具有所需宽度的颜色,然后对其余条带透明.通过设置背景位置的动画,我们可以获得接近我们正在寻找的效果的东西.
请注意,背景位置动画仅适用于固定像素值,因此需要事先知道框的尺寸.每次值更改时,都需要相应地重新配置背景位置值.
div {
height: 200px;
width: 200px;
box-sizing: border-box;
background-image: linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px), linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px);
background-size: 100% 3px, 3px 100%, 100% 3px, 3px 100%; /* one of the values is the border thickness, other is 100% */
background-repeat: no-repeat;
background-position: -50px 0px, right -50px, 200px bottom, 0px 200px; /* positions such that none of the images are visible at start */
animation: border 5s linear; /* add infinite if you need infinite animation */
}
@keyframes border {
/* animate position such that they come into view and go out of it one by one */
25% {
background-position: 200px 0px, right -50px, 200px bottom, 0px 200px;
}
50% {
background-position: 200px 0px, right 200px, 200px bottom, 0px 200px;
}
75% {
background-position: 200px 0px, right 200px, -50px bottom, 0px 200px;
}
100% {
background-position: 200px 0px, right 200px, -50px bottom, 0px -50px;
}
}
如果你想要一个更接近SVG的纯CSS解决方案,那么我们可以为动画添加更多的关键帧,如下面的代码片段.
div {
height: 200px;
width: 200px;
box-sizing: border-box;
background-image: linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px), linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px);
background-size: 100% 3px, 3px 100%, 100% 3px, 3px 100%;
background-repeat: no-repeat;
background-position: -50px 0px, right -50px, 200px bottom, 0px 200px;
animation: border 5s linear;
}
@keyframes border {
20% {
background-position: 150px 0px, right -50px, 200px bottom, 0px 200px;
}
25% {
background-position: 200px 0px, right 0px, 200px bottom, 0px 200px;
}
45% {
background-position: 200px 0px, right 150px, 200px bottom, 0px 200px;
}
50% {
background-position: 200px 0px, right 200px, 150px bottom, 0px 200px;
}
70% {
background-position: 200px 0px, right 200px, 0px bottom, 0px 200px;
}
75% {
background-position: 200px 0px, right 200px, -50px bottom, 0px 150px;
}
95% {
background-position: 200px 0px, right 200px, -50px bottom, 0px 0px;
}
100% {
background-position: 200px 0px, right 200px, -50px bottom, 0px -50px;
}
}
这是一个使用纯CSS的更完整的无限动画:
div {
height: 200px;
width: 200px;
box-sizing: border-box;
background-image: linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px), linear-gradient(to right, red 50px, transparent 50px), linear-gradient(to bottom, red 50px, transparent 50px);
background-size: 100% 3px, 3px 100%, 100% 3px, 3px 100%;
background-repeat: no-repeat;
background-position: 0px 0px, right -50px, 200px bottom, 0px 200px;
animation: border 5s linear infinite;
}
@keyframes border {
20% {
background-position: 150px 0px, right -50px, 200px bottom, 0px 200px;
}
25% {
background-position: 200px 0px, right 0px, 200px bottom, 0px 200px;
}
45% {
background-position: 200px 0px, right 150px, 200px bottom, 0px 200px;
}
50% {
background-position: 200px 0px, right 200px, 150px bottom, 0px 200px;
}
70% {
background-position: 200px 0px, right 200px, 0px bottom, 0px 200px;
}
75% {
background-position: 200px 0px, right 200px, -50px bottom, 0px 150px;
}
95% {
background-position: 200px 0px, right 200px, -50px bottom, 0px 0px;
}
95.1% {
background-position: -50px 0px, right 200px, -50px bottom, 0px 0px;
}
100% {
background-position: 0px 0px, right 200px, -50px bottom, 0px -50px;
}
}