html - 在方形元素上制作移动边框动画

标签 html css animation css-animations

我正在尝试让移动边框 CSS 动画在正方形上工作,但我不太清楚如何让它工作。它在一个圆圈上工作正常,因为我只使用关键帧的旋转过渡。这是我当前的标记。

.box {
  width: 50px;
  height: 50px;
  margin: 50px auto;
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  position: relative;
  -webkit-transition: all 1s ease;
  transition: all 1s ease;
}
.box .border {
  position: absolute;
  top: -4px;
  left: -4px;
  width: 50px;
  height: 50px;
  background: transparent;
  border: 4px solid transparent;
  border-top-color: orangered;
  border-radius: 50%;
  animation-name: border;
  -webkit-animation-duration: 2s;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
}
@-webkit-keyframes border {
  from {
    -webkit-transform: rotate(0deg);
  }
  to {
    -webkit-transform: rotate(360deg);
  }
<div class="box">
  <div class="border"></div>
</div>

最佳答案

有问题的动画是使用 rotate 变换和 stationary 边框来创建移动边框的错觉,但实际上不是。对于正方形,您不能使用类似的模型,因为当我们旋转正方形时它不会像圆一样保持不变。

因此可用的选项是使用基于 SVG stroke-dashoffset 的动画,如下面的代码片段所示。 stroke-dasharray 属性提供笔划的长度/宽度(第一个st 参数)和空间的长度/宽度(第 2nd参数)。 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;
  }
}
<svg width="210" height="210">
  <polygon points="5,5 205,5 205,205 5,205" />
</svg>


如果您想要一个纯 CSS 解决方案,那么您可以使用基于线性渐变 的解决方案,如下面的代码片段所示。在这里,我们根据边界厚度相同的线性渐变创建四个 strip 背景图像。这些条具有所需宽度的颜色,其余部分是透明的。通过为 background-position 设置动画,我们可以获得接近我们正在寻找的效果。

请注意,background-position 动画仅适用于固定像素值,因此需要事先知道框的尺寸。每次值更改时,都需要相应地重新配置 background-position 值。

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;
  }
}
<div class='border-animation'></div>

如果您想要一个更接近 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;
  }
}
<div class='border-animation'></div>

这是一个使用纯 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;
  }
}
<div class='border-animation'></div>

关于html - 在方形元素上制作移动边框动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41547998/

相关文章:

javascript - 谷歌地图计算文本框更改按钮单击的不同距离

html - 如何从 Chrome 中以一致的大小打印 HTML 页面?

css - 如何覆盖/重叠两个用 css 设计的 div 看起来像文本气泡?

css - 标题中的可点击 Logo 链接

css - 使用纯 CSS 动画移动的云

graphics - 如何实现高速动画?

javascript - Angular 中的随机动画

html - 标签上的相对位置问题

html - 如何让两个div内容垂直居中?

css - 可变大小的 float div