使用纯 CSS 进行径向擦拭;如果不是 SVG 替代品

Posted

技术标签:

【中文标题】使用纯 CSS 进行径向擦拭;如果不是 SVG 替代品【英文标题】:Radial wipe with pure CSS; if not SVG alternative 【发布时间】:2016-02-20 02:47:46 【问题描述】:

我发现this question 已得到答复,并且似乎使用 SVG 实现了径向擦除动画。

我希望实现类似以下示例的border: 1px solid green; 效果:

不过,我想知道的是,这是否可以通过纯 CSS 实现——那将是理想的。

如果使用 CSS 无法实现,我将如何使用 SVG 解决此类问题?

【问题讨论】:

【参考方案1】:

CSS 不是此类动画的正确工具。虽然您可以使用 CSS 来完成,但最好是使用 SVG。对于纯 CSS 版本,您可以尝试调整 my answer here 中提供的 sn-p,但我不会真正推荐它,因为您可以看到它非常复杂。

您所要做的就是使用circle 元素,将其stroke-dasharray 设置为等于圆的周长,然后像下面的sn-p 那样为stroke-dashoffset 设置动画。

stroke-dasharray 属性为圆(边框)创建一个虚线笔划,其中每个笔划和它们之间的虚线将具有为属性指定的长度。

stroke-dashoffset 属性指定圆的笔划应开始的偏移量。当偏移量为0 时,绿色笔划可见,而当偏移量为314(等于周长)时,笔划之间的破折号可见。因此它最终会产生擦除效果。

svg 
  height: 100px;
  width: 100px;
  transform: rotate(-90deg);

circle 
  stroke: green;
  fill: none;
  stroke-dasharray: 314; /* equal to circumference of circle 2 * 3.14 * 50 */
  animation: wipe 2s linear infinite;

@keyframes wipe 
  0% 
    stroke-dashoffset: 0;
  
  30%, 50% 
    stroke-dashoffset: 314;
  
  80%, 100% 
    stroke-dashoffset: 0;
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<svg viewBox='0 0 100 100'>
  <circle cx='50' cy='50' r='40' />
</svg>

以上示例使用无限动画,因此擦除和重绘将连续运行。如果必须打开/关闭它,那么最好使用transition,如下面的 sn-p 所示。我在:hover 上完成了此操作,但您可以轻松地将其调整为单击或其他事件。

svg 
  height: 100px;
  width: 100px;
  transform: rotate(-90deg);

circle 
  stroke: green;
  fill: none;
  stroke-dasharray: 314; /* equal to circumference of circle 2 * 3.14 * 50 */
  stroke-dashoffset: 0; /* initial setting */
  transition: all 2s;

svg:hover circle
  stroke-dashoffset: 314;
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<svg viewBox='0 0 100 100'>
  <circle cx='50' cy='50' r='40' />
</svg>

【讨论】:

我猜根据他的例子,它应该从314过渡到0。 @ManojKumar:在那个 GIF 中它实际上似乎是双向的,所以编辑了动画 :) 它可能还需要一些旋转(为了让擦除从顶部中间开始,而不是中间),但我可能会把它留给 OP(如果他们想要一个精确的副本)。 @Harry 哇。你简直让我大吃一惊。 SVG 是我刚刚开始理解的东西。很酷。 GIF 是双向的,因为我想打开和关闭此动画以指示 .active 状态。查看您的@keyframes 并尝试计算出需要更改什么值才能使径向擦除开始逆时针90°?这又引出了一个问题——希望你不介意——我一直认为 SVG 是一种预先存在的资产,我可以使用 &lt;img&gt; 标签调用它。我是否理解您在上面的示例中从零开始创建了一个独立的 SVG? @DanMad:是的,我使用的是内联 SVG。也就是说,创建 SVG 圆圈所需的代码嵌入在 html 代码本身中。 SVG 圆通常从 X 轴的 0 度开始,因此要使其从 90 度(逆时针)开始擦除,我们可以在 SVG 元素本身添加一个简单的transform: rotate(-90deg)。我已经更新了答案中的代码 sn-p :) 要打开/关闭动画,最好使用过渡而不是动画,我很快就会添加一个带有悬停过渡的版本。 @Harry:您说过,“CSS 不是此类动画的正确工具。虽然您可以使用 CSS,但最好使用 SVG”。这是为什么呢?

以上是关于使用纯 CSS 进行径向擦拭;如果不是 SVG 替代品的主要内容,如果未能解决你的问题,请参考以下文章

带有图像的透明径向渐变? [复制]

01超精美渐变色动态背景完整示例CSS动效实战(纯CSS与JS动效)

使用 CSS 径向渐变添加模糊

是否可以使用当前的 MDN 画布 2D API 函数在 userSpaceOnUse 坐标中使用 gradientTransforms 渲染 SVG 径向渐变?

Raphael JS 的径向饼图菜单

如何在 CSS 中创建径向菜单?