动画SVG,圆形描边悬停

5

想模仿动画箭头:

http://uve.info/

鼠标悬停时,描边覆盖圆形。我已经在Illustrator中创建了形状,定位很容易,只需对描边进行动画处理即可。

HTML(内联SVG):

<svg id="right_arrow" class="direction__right direction__item" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
    <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28"/>
    <path class="arrow offset-colour" d="M40,1c21.5,0,39,17.5,39,39S61.5,79,40,79S1,61.5,1,40S18.5,1,40,1 M40,0C17.9,0,0,17.9,0,40s17.9,40,40,40s40-17.9,40-40S62.1,0,40,0L40,0z"/>
</svg>

路径已经是一个圆。我想要另一条路径覆盖在当前路径上,以模仿uve.info网站。整个动画由悬停完成。这是箭头在动画中间应该看起来的样子,但证明很麻烦。

uve.info arrow animation

最好的方法是如何调用描边效果?

谢谢大家。


1
Stroke-dasharray / offset - Paulie_D
1个回答

13

如果你的目标浏览器比较现代,我建议使用SVG动画。

你可以通过使用stroke-dasharray和等长的dash offset来使描边动起来,其长度应为圆的周长(2 * PI * r)。调整dash length和offset的动画值可以创建不同的效果。

以下是如何实现的示例:

.circle:hover {
  /* calculate using: (2 * PI * R) */
  stroke-dasharray: 227;
  stroke-dashoffset: 0;
  animation-iteration-count: infinite;
  animation-name: rotate;
  animation-duration: 2s;
  animation-direction: alternate;
  animation-timing-function: linear;
}

@keyframes rotate {
  to {
    stroke-dashoffset: 227;
  }
}
<svg id="right_arrow" class="direction__right direction__item" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
  <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28" />
  <circle cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="2" />
  <circle class="circle" cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="4" />
</svg>

使用CSS的animation属性和@keyframes,你可以做出各种花哨的效果。如果你想保持简单,也可以尝试使用transition属性,就像下面的例子一样。注意,我使用了svg的transform属性来改变虚线描边的起点。

.another-circle {
  stroke-dasharray: 227;
  stroke-dashoffset: 227;
  transition: stroke-dashoffset 2s linear;
}
.another-circle:hover {
  stroke-dashoffset: 0;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="80px" height="80px" viewBox="0 0 80 80" xml:space="preserve">
  <polygon class="ring offset-colour" points="32.5,52 47.5,40 32.5,28" />
  <circle cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="2" />
  <circle transform="rotate(-90 40 40)" class="another-circle" cx="40" cy="40" r="36" fill="transparent" stroke="black" stroke-width="4" />
</svg>


很好的回答!我已经使用了transform将起始点转换为“deg”,但是有没有办法在未启动悬停状态时反转动画?理想情况下,描边应该只在悬停开始时出现。 - Neil
1
谢谢。我包含了另一个例子,展示了一个稍微不同的方法,通过使用简单的“过渡”而不是复杂的动画来反转动画。我不确定你需要多么花哨(例如:是否需要使用“动画”)。 - user3297291
看起来很棒,我喜欢当你离开悬停状态时的效果。但是我想了解一下你在SVG上使用内联样式的方向,例如transform rotate属性(为什么有3个值)。我还想了解227值的描边与您如何得出该数字之间的相关性。 - Neil
1
内联 SVG 变换可能有点棘手,但在这种情况下非常简单:第一个值是旋转角度,第二个和第三个值表示旋转中心(x 和 y)。因此,为了从圆的顶部开始,我们逆时针旋转 90 度(360/4)。我们想围绕圆的中心(cxcy)旋转,所以它们是第二和第三个值。227 只是比描边长度稍长一点,可以使用以下公式计算:2 * PI * r,在这种情况下是 2 * 3.14 * 36 = 226.08。 - user3297291
这更有意义。个人认为,您可以使用transform-origin: 50%来实现相同的结果吗?另外,如果我计划缩放圆形矢量,那么我必须更改227还是可以保持不变? - Neil
1
cxcyr都是相对于viewBox的。您可以使用widthheight缩放您的<svg>而不更改viewBox;这样您就不必更新圆的中心或描边长度。我认为您无法在内部SVG元素上使用CSS变换,但您仍需在规范中进行确认。 - user3297291

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接