首页 > 解决方案 > 如何制作从 div 底部到顶部的 SVG 高度动画?

问题描述

我正在尝试用线和圆制作 SVG 动画。线条应该是动画的,圆圈应该相对于线条高度移动。这条线应该从 div 的底部开始,在动画后它应该用圆圈实现 div 广告的顶部,然后应该动画到底部,然后从底部到顶部,从顶部到底部一直只有一个,除非 - 如果用户将鼠标悬停在圆圈上它应该停止,如果用户将鼠标悬停在圆圈上,它应该在停止时启动。

div {
  height: 100px;
}
<div>
<svg xmlns="http://www.w3.org/2000/svg" width="171" height="728" viewBox="0 0 171 728">
<defs><style>.a{fill:#000;}</style></defs><circle class="a" cx="85.5" cy="85.5" r="85.5"></circle>
<rect class="a" width="7" height="0" transform="translate(82 113)">
<animate id="animation"
    attributeName="height"
    attributeType="XML"
    from="0" to="615"
    begin="0s" dur="5s"
    fill="freeze" />
<animate id="animation2"
    attributeName="height"
    attributeType="XML"
    from="615" to="0"
    begin="5s" dur="10s"
    fill="freeze" />
</rect>
</svg>
</div>

标签: svgsvg-animate

解决方案


动画可以有两个以上的状态。要来回移动值,您可以编写values="728;113;728". 然后,您需要定义keyTimes="0;.5;1"在简单持续时间内分布这些状态 - 这意味着,所有值都需要介于 0 和 1 之间,如果dur="10s",则将在该时间的一小部分内达到状态,即 0 秒、5 秒和 10 秒。keyTimesvalues必须匹配的值的数量。

要使动画无休止地重复,您需要设置repeatCount="indefinite".

动画的开始和结束时间可以与事件相关。end="stop.mouseenter"表示当鼠标进入带有id="stop"(圆圈)的元素时动画将停止。为了重新启动动画,您可以利用动画可以有多个开始时间这一事实。begin="0s;stop.mouseleave"意味着它将在加载后直接启动,并且当鼠标离开元素时也会启动id="stop".

停止时,动画被移除,因此线条返回到其基本状态(无长度),并将从那里重新开始。这显然与暂停动画不同(将其冻结在鼠标悬停开始时的状态),但您的问题并未说明这是否是您想要实现的目标。这些声明性动画没有暂停动画的机制。为此,您需要一个 CSS 动画,这看起来会有所不同。

最后,如果您使用<line>元素而不是<rect>. 然后您只需要为y1属性设置动画,将其从最低点移动到最高点,然后再返回。

注意我已经给线一个单独的类,因为它需要有一个明确的颜色和宽度。

div {
  height: 100px;
}
.b {
  stroke: black;
  stroke-width: 7px;
}
<div>
<svg xmlns="http://www.w3.org/2000/svg" width="171" height="728" viewBox="0 0 171 728">
<defs><style>.a{fill:#000;}</style></defs>
<circle id="stop" class="a" cx="85.5" cy="85.5" r="85.5"></circle>
<line class="b" x1="85.5" y1="728" x2="85.5"  y2="728">
<animate id="animation"
    attributeName="y1"
    attributeType="XML"
    values="728;113;728"
    keyTimes="0;.5;1"
    begin="0s;stop.mouseleave"
    end="stop.mouseenter"
    dur="10s"
    repeatCount="indefinite" />
</line>
</svg>
</div>


推荐阅读