SMIL 动画不在 Mouseout 上结束
SMIL Animation Not Ending On Mouseout
我正在尝试制作一个 SVG 图标,该图标在悬停时使用 SMIL 进行动画处理(好吧,我不关心它是 SMIL 还是 CSS,我只是不想使用 JS)并且我已经走了很远,但我 运行 遇到了一个我无法在网上找到答案甚至提及的问题。动画在鼠标悬停(悬停)时开始,但在鼠标移出时动画元素之一(第二个圆圈)保持动画,我完全不知道为什么。
你也可以在https://codepen.io/anon/pen/LmjpVQ
看到它
感谢您提前提供的任何帮助。
svg { width: 100px; color: red; }
<svg id="location" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="circleClip">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#circleClip)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover+2s" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover+2" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" stroke-width="0" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" stroke-width="0" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
</svg>
您陷入的陷阱是,与 HTML 元素不同,鼠标事件仅在指针位于绘制区域(描边或填充)上方时才会默认引发,但无论opacity
设置为什么。您甚至可以微调 pointer-events
以包含或排除 visibility: hidden
或 fill: none
.
的事件
每次您设置动画的扩展圆经过指针下方时都会引发 mouseover
事件,使用 pointer-events:all
您可以防止 mousout
当鼠标结束在内部时,但是仅在动画重复重置半径之前。这让事情变得非常混乱。
最简单的解决方案是在整个图标的顶部放置一个带有opacity="0"
的不可见矩形,这样"inside" 和"outside" 就有了清晰的边界。要进行更多微调,请定义一个覆盖要捕获鼠标移动区域的形状。
svg { width: 100px; color: red; }
<svg id="loc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="c">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#c)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover+2s" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover+2" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
<rect opacity="0" width="100%" height="100%" />
</svg>
我正在尝试制作一个 SVG 图标,该图标在悬停时使用 SMIL 进行动画处理(好吧,我不关心它是 SMIL 还是 CSS,我只是不想使用 JS)并且我已经走了很远,但我 运行 遇到了一个我无法在网上找到答案甚至提及的问题。动画在鼠标悬停(悬停)时开始,但在鼠标移出时动画元素之一(第二个圆圈)保持动画,我完全不知道为什么。
你也可以在https://codepen.io/anon/pen/LmjpVQ
看到它感谢您提前提供的任何帮助。
svg { width: 100px; color: red; }
<svg id="location" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="circleClip">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#circleClip)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover+2s" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover+2" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" stroke-width="0" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" stroke-width="0" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
</svg>
您陷入的陷阱是,与 HTML 元素不同,鼠标事件仅在指针位于绘制区域(描边或填充)上方时才会默认引发,但无论opacity
设置为什么。您甚至可以微调 pointer-events
以包含或排除 visibility: hidden
或 fill: none
.
每次您设置动画的扩展圆经过指针下方时都会引发 mouseover
事件,使用 pointer-events:all
您可以防止 mousout
当鼠标结束在内部时,但是仅在动画重复重置半径之前。这让事情变得非常混乱。
最简单的解决方案是在整个图标的顶部放置一个带有opacity="0"
的不可见矩形,这样"inside" 和"outside" 就有了清晰的边界。要进行更多微调,请定义一个覆盖要捕获鼠标移动区域的形状。
svg { width: 100px; color: red; }
<svg id="loc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="c">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#c)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover+2s" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover+2" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
<rect opacity="0" width="100%" height="100%" />
</svg>