如何创建自适应SVG边框动画

时间:2019-07-18 22:44:21

标签: animation svg responsive stroke-dasharray

我想为按钮元素创建边框动画。设计是将倾斜矩形的两端打开,然后在悬停时关闭。

这就是我们想要做的(请问我的艺术“风格”): Button

以下是一些代码和一个codepen示例:

a svg rect {
  stroke: red;
  stroke-width: 5;
  transition: 1s;
  stroke-dasharray: 100%;
  stroke-dashoffset: 0;
}

a:hover svg rect {
  stroke-dasharray: 0%;
stroke-dashoffset: 0;
}

codepen example

我在理解笔触-dasharray背后的数学方法时遇到了麻烦,但是似乎不需要太多复杂的数学操作就可以实现。

另一个问题是它需要响应。因此按钮可以包含不同数量的文本。

让我知道是否需要进一步说明。

2 个答案:

答案 0 :(得分:3)

我使用的是多边形,而不是使用倾斜的svg元素。这样,我可以计算多边形的总长度(周长)。我使用javascript:console.log(poly.getTotalLength())完成了此操作。这给了我543.7。对于多边形的stroke-dasharray,我使用的是250, 21.85,其中250 + 21.85 = 543.7 /2。

我正在将stroke-dashoffset设置为543.7 / 2 = 271.85;和stroke-dasharray到271.850。(笔划从250变为271.85,间隙从21.85变为0)

我进行的另一项更改:我使用的是svg <a>元素,而不是您正在使用的元素,并且多边形具有pointer-events:all;,我已添加此元素以使其对鼠标敏感尽管是fill:none

希望您会发现它有用。

polygon {
  stroke: red;
  stroke-width: 4;
  stroke-dasharray:250, 21.85;
  fill: none;
  transition: 1s;
  pointer-events:all;
}

polygon:hover{
  stroke: #ff0;
  stroke-dashoffset: 271.85;
  stroke-dasharray: 271.85 0;
}
<svg viewBox = "0 0 250 50" width="250">
  <a xlink:href="#" class="py-2 px-5">
    <text x="125" y="30" text-anchor="middle">Button Button Button</text>
    <polygon id="poly" points="2,48 220,48 248,2 30,2 2,48" />
  </a>
</svg>

答案 1 :(得分:3)

我认为,这是创建符合您要求的自动响应按钮的最佳方法。

它有几个缺点:

  1. 按钮轮廓中的间隙根据标签长度而变化。
  2. 它需要一个相当新的浏览器(以便在pathLength元素上支持<rect>

.btn {
  display: inline-block;
  position: relative;
  overflow: auto;
}

.btn + .btn {
  margin-left: 20px;
}

.btn svg {
  position: absolute;
  top: 0;
  left: 0;
}

.label {
  position: relative;
  font-size: 18px;
  font-weight: bold;
  padding: 5px 20px;
}

.btn, .btn svg {
  overflow: visible;
}

.btn svg rect {
  fill: gold;
  stroke: black;
  stroke-width: 2px;
  stroke-dasharray: 47 3;
  transform-origin: 50% 50%;
  transform-box: fill-box;
  transform: skewX(-10deg) scale(1, -1);
  transition: all 0.75s;
}

.btn:hover svg rect {
  stroke-dasharray: 50 0;
  stroke-dashoffset: 50;
}
<div class="btn">
  <svg width="100%" height="100%">
    <rect width="100%" height="100%" pathLength="100"/>
  </svg>
  <div class="label">Button</div>
</div>

<div class="btn">
  <svg width="100%" height="100%">
    <rect width="100%" height="100%" pathLength="100"/>
  </svg>
  <div class="label">Much longer button</div>
</div>