如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画

Posted

技术标签:

【中文标题】如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画【英文标题】:How to Animate the fill attribute of inline SVG on mouseover/mouseout (SMIL) 【发布时间】:2015-10-07 22:21:37 【问题描述】:

我创建了一个简单的内联 SVG。

使用 SMIL,我尝试将父 SVG idmouseover 上的所有路径的 fill 属性设置为粉红色。

mouseout 上,我希望fill始终重置。

希望fill 动画在mouseover 上重复。我只希望它运行一次并“停止”(即保持粉红色),但是,如果动画持续时间完成。

我尝试了以下方法:

#logoSVG 
    width: 100px;
<a href="javascript:void(0)" id="logo">
  <svg version="1.1" id="logoSVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 113.7 62.2" enable-background="new 0 0 113.7 62.2" xml:space="preserve">
    <path id="M" fill="#1E90FF" d="M16.1,38.9l-9-30.4H6.7C7.2,14.8,7.2,18.8,7.2,21v17.9H0V0h11.2l9,29.5l0,0L30,0h11.2v38.5h-7.6
    V20.6c0-0.9,0-1.8,0-3.1c0-1.3,0-4,0.4-9h-0.4l-9.8,30.4L16.1,38.9L16.1,38.9z" />
    <path id="A" fill="#1E90FF" d="M74.7,38.9l-2.7-9.4H58.2l-2.7,9.4h-9L60,0h9.8l13.9,38.9H74.7z M69.8,22.8c-2.7-8.5-4-13-4.5-14.3
    c-0.4-0.9-0.4-1.8-0.9-2.7c-0.4,2.2-2.2,7.6-4.9,16.6h10.3V22.8z" />
    <path id="T" fill="#1E90FF" d="M102.9,38.9h-8.1V7.2H84.6V0h29.1v6.7h-10.3v32.2H102.9z" />
    <rect id="Line" y="55.9" fill="#1E90FF"   />

    <animate xlink:href="#M" attributeName="fill" from="#1E90FF" to="pink" dur="0.8s" begin="logoSVG.mouseover" end="logoSVG.mouseout" id="m-anim" />
    <animate xlink:href="#A" attributeName="fill" from="#1E90FF" to="pink" dur="0.8s" begin="m-anim.begin + 0s" end="logoSVG.mouseout" id="a-anim" />
    <animate xlink:href="#T" attributeName="fill" from="#1E90FF" to="pink" dur="0.8s" begin="m-anim.begin + 0s" end="logoSVG.mouseout" id="t-anim" />
    <animate xlink:href="#Line" attributeName="fill" from="#1E90FF" to="pink" dur="0.8s" begin="m-anim.begin + 0s" end="logoSVG.mouseout" id="line-anim" />
  </svg>
</a>

如您所见,fill 最后并没有“停止”。

我错过了什么吗? mouseover/mouseout 是用于实现此效果的正确值吗?

【问题讨论】:

【参考方案1】:

您可以在 -Tags 中添加“填充”属性,并将其设置为“冻结”,例如:

<animate xlink:href="#M" attributeName="fill" from="#1E90FF"
  to="pink" dur="0.8s" begin="logoSVG.mouseover" 
  end="logoSVG.mouseout" id="m-anim" fill="freeze"/>

From the docs:

freeze - 当动画的活动持续时间在文档持续时间的剩余时间内(或直到动画重新启动)结束时,动画效果被“冻结”。

更新

如果鼠标事件被正确触发,冻结的填充不会变回来。

或者,您可以明确地为每个状态设置动画:

    改变颜色 保持填充 将填充改回原来的颜色

为了清楚起见,我将示例简化为一个字母:

#logoSVG 
    border: 1px dashed #777;
    width: 100px;
<a href="javascript:void(0)" id="logo">
  <svg version="1.1" id="logoSVG" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 113.7 62.2" enable-background="new 0 0 113.7 62.2" xml:space="preserve">
    <path id="M" fill="#1E90FF" d="M16.1,38.9l-9-30.4H6.7C7.2,14.8,7.2,18.8,7.2,21v17.9H0V0h11.2l9,29.5l0,0L30,0h11.2v38.5h-7.6
    V20.6c0-0.9,0-1.8,0-3.1c0-1.3,0-4,0.4-9h-0.4l-9.8,30.4L16.1,38.9L16.1,38.9z" />

    <animate xlink:href="#M" attributeName="fill" from="#1E90FF" to="pink" dur="0.8s" begin="logoSVG.mouseover" end="logoSVG.mouseout" id="m-anim" fill="freeze"/>
    <animate xlink:href="#M" attributeName="fill" from="pink" to="pink" dur="0.8s" begin="logoSVG.mouseover+0.8s" end="logoSVG.mouseout" id="m-anim" fill="freeze"/>
    <animate xlink:href="#M" attributeName="fill" from="#1E90FF" to="#1E90FF" begin="logoSVG.mouseout" end="logoSVG.mouseover" id="m-anim" fill="freeze"/>

  </svg>
</a>

旁注:像 begin="m-anim.begin + 0s" 这样的开始值在 Firefox(开发人员版 41.0a2 (2015-07-18) 中似乎不起作用,至少在我的机器上)

【讨论】:

谢谢 - 它解决了任何重复的问题,但添加此属性可防止这种情况发生...“在鼠标移出时,我希望填充始终重置。”? 抱歉,我没有意识到 - 也许我把鼠标移到了快 我更新了我的答案以使用另一种更明确的方法:为每个所需状态使用 1 个动画标签。第一个更改颜色,一个保留填充,最后一个将填充更改回原始颜色。

以上是关于如何在 mouseover/mouseout (SMIL) 上为内联 SVG 的填充属性设置动画的主要内容,如果未能解决你的问题,请参考以下文章

jQuery - 具有多个 div 的 mouseover/mouseout

jQuery因mouseover,mouseout冒泡产生的闪烁问题

如何解决鼠标移动到子元素 会触发父元素的mouseout事件

jQuery 悬停 mouseover/mouseout 计时

mouseover ,mouseout ,mouseenter,mouseleave的区别

jQuery 问题 - mouseover/mouseout 太快