【问题标题】:SVG circle animation stroke on hover悬停时的SVG圆形动画笔划
【发布时间】:2017-06-11 07:06:30
【问题描述】:

我目前有一个小 SVG,可以添加完整的笔画。但是,我很难在 hover 上完成一个完整的循环。当用户将鼠标悬停在链接之外时,它应该返回另一个方向。

完整的动画似乎可以正常工作,但是在集成它时,当我只想让它发生时,动画却不断消失。

body,
html {
  position: relative;
  height: 100%;
}
body {
  background-color: #D81D3B;
}
.svg-container {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7em;
  height: 7em;
  transform: translate3d(-50%, -50%, 0);
}
.svg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}
.symbol {
  fill: transparent;
  stroke: #fff;
  stroke-width: 1px;
  stroke-dasharray: 1600;
  stroke-miterlimit: 10;
  stroke-dashoffset: 1600;
  animation: dash 4s linear 1;
}
@keyframes dash {
  from {
    stroke-dashoffset: 1600;
  }
  to {
    stroke-dashoffset: -1600;
  }
}
<div class="svg-container">
  <svg width="100" height="100" class="svg">
    <circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
  </svg>

</div>

<a href="#">Stupid</a>

【问题讨论】:

  • 我很难理解默认状态和悬停状态应该是什么。请说明您正在尝试的确切行为。
  • @SophieRhodes:我添加了一些标签,它们可能对未来的搜索有所帮助。如果您觉得它们不正确,请随时回滚。

标签: javascript html css svg css-animations


【解决方案1】:

根据您的描述,您实际需要的是transition,而不是animation。此外,链接 (a) 元素当前位于 DOM 中的 svg 元素下方,因此它不能用于更改 SVG 元素(或 SVG 的子元素)的样式。它需要位于 SVG 元素的上方(上方意味着链接应该是 SVG 元素的前一个兄弟元素或 SVG 父元素的前一个兄弟元素)。

另一件事是您实际上不需要从stroke-dashoffset:1600 移动到-1600,因为它会绘制圆圈并立即将其擦掉。当悬停在链接元素上时,我们需要它为stroke-dashoffset:0,并在悬停时返回原始状态(stroke-dashoffset: 1600)。过渡会在悬停时自动创建反向效果,无需单独编码。

下面是一个示例 sn-p。

body,
html {
  position: relative;
  height: 100%;
}
body {
  background-color: #D81D3B;
}
.svg-container {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7em;
  height: 7em;
  transform: translate3d(-50%, -50%, 0);
}
.svg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}
.symbol {
  fill: transparent;
  stroke: #fff;
  stroke-width: 1px;
  stroke-dasharray: 1600;
  stroke-miterlimit: 10;
  stroke-dashoffset: 1600;
  transition: all 4s linear;
}
a:hover + .svg-container .symbol {
  stroke-dashoffset: 0;
}
<a href="#">Stupid</a>
<div class="svg-container">
  <svg width="100" height="100" class="svg">
    <circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
  </svg>

</div>

使用过渡或纯 CSS 无法使圆圈在悬停时沿相同方向(顺时针)消失。可以使用下面的 sn-p 中的一些 JS 来实现。使用 JS 时,链接元素可以在文档中的任何位置,因为它没有 CSS 等限制,使用动画会比过渡更有效。

注意:非常快速的悬停进出会破坏动画,因为脚本希望在悬停发生时完成一次迭代。修复此问题将非常棘手和复杂。

window.onload = function() {
  var link = document.querySelector('a');
  var symbol = document.querySelector('.svg-container .symbol');

  /* clockwise paint on hover in */
  link.addEventListener('mouseover', function() {
    symbol.setAttribute('style', 'stroke-dashoffset: 1600; animation: paint 4s linear');
  }, false);

  /* clockwise wipe on hover out */
  link.addEventListener('mouseout', function() {
    symbol.setAttribute('style', 'stroke-dashoffset: 0; animation: wipe 4s linear');
  }, false);
}
body,
html {
  position: relative;
  height: 100%;
}
body {
  background-color: #D81D3B;
}
.svg-container {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 7em;
  height: 7em;
  transform: translate3d(-50%, -50%, 0);
}
.svg {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 100%;
}
.symbol {
  fill: transparent;
  stroke: #fff;
  stroke-width: 1px;
  stroke-dasharray: 1600;
  stroke-miterlimit: 10;
  stroke-dashoffset: 1600;
}
@keyframes paint {
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes wipe {
  to {
    stroke-dashoffset: -1600;
  }
}
<div class="svg-container">
  <svg width="100" height="100" class="svg">
    <circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
  </svg>
</div>
<a href="#">Stupid</a>

【讨论】:

  • 感谢您回来。在悬停效果上,它工作得很好,但是在悬停时,它需要像我当前的动画一样转到另一边。这可能吗?
  • @SophieRhodes:哦,我明白了。但这对于过渡或 CSS 是不可能的。这也不是很容易,需要一些脚本(JS)。因为我们说默认状态是偏移 1600,所以在悬停时它变为 0,然后在悬停时变为 -1600。如果你愿意,我会添加一个 JS 示例。
  • 那将是很棒的学习。我想你正在切换课程?偏移量来回移动 -1600 和 1600
  • @SophieRhodes:我还添加了一个 JS 版本。我在悬停/悬停时切换动画以获得效果。我不是 JS 专家,所以我的脚本可以优化。
猜你喜欢
  • 2016-08-19
  • 2021-01-12
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 2013-08-14
  • 1970-01-01
  • 1970-01-01
  • 2014-11-28
相关资源
最近更新 更多