悬停时SVG圈动画描边

时间:2017-01-25 22:27:25

标签: javascript html css svg css-animations

我目前有一个小型SVG可以增加一个完整的笔画。但是,我很难在悬停上完成整个循环。当用户将链接悬停时,它应该以相反的方式返回。

完整的动画似乎有效,但在整合时,动画会在我只想要它发生的时候消失。

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>

1 个答案:

答案 0 :(得分:3)

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

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

以下是一个示例代码段。

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,无法在悬停时使圆圈沿同一方向(顺时针方向)擦除。它可以通过下面的代码片段中的一些JS来实现。使用JS时,link元素可以在文档中的任何位置,因为它没有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>

相关问题