【发布时间】:2020-08-29 14:32:48
【问题描述】:
const button = document.getElementById('healer')
const preloaded = new Image()
preloaded.src = "https://svgshare.com/i/KzN.svg"
const img = document.getElementById("heal")
//img.style.display = "none"
button.onclick = () => {
button.disabled = true
img.src = "https://svgshare.com/i/KzN.svg"
img.style.display = ""
setTimeout(() => {
button.disabled = false
img.src = ""
//img.style.display = "none"
}, 1000)
}
#monster {
height: 160px;
width: 160px;
}
#heal {
height: 160px;
width: 160px;
position: absolute;
top: 0;
left: 0;
}
<img id="monster" src="https://i.imgur.com/NMocKWy.png">
<img id="heal">
<button id="healer">
Show heal anim
</button>
如您所见,只有第一次点击会产生动画。后续点击无效。我认为这是因为 SVG 设置为仅运行一次动画 (SVG source code),即使 img 标签的 src 属性设置为空然后再次设置为 SVG,浏览器也不会重置动画(即使根据这个 Stackoverflow 线程重置 src 应该重置动画:Proper way to reset a GIF animation with display:none on Chrome)。
将 SVG 设置为无限运行动画 (modified SVG source code) 只是稍微好一点:
const button = document.getElementById('healer')
const preloaded = new Image()
preloaded.src = "https://svgshare.com/i/L0q.svg"
const img = document.getElementById("heal")
//img.style.display = "none"
button.onclick = () => {
button.disabled = true
img.src = "https://svgshare.com/i/L0q.svg"
img.style.display = ""
setTimeout(() => {
button.disabled = false
img.src = ""
//img.style.display = "none"
}, 1000)
}
#monster {
height: 160px;
width: 160px;
}
#heal {
height: 160px;
width: 160px;
position: absolute;
top: 0;
left: 0;
}
<img id="monster" src="https://i.imgur.com/NMocKWy.png">
<img id="heal">
<button id="healer">
Show heal anim
</button>
浏览器似乎一直在内部运行动画,所以只有第一次按钮点击是正确的,随后的点击从中间开始动画并在中间结束,我认为这看起来不太理想。
有什么方法可以让这项工作按预期进行吗? (我正在尝试为类似 Pokemon 的基于浏览器的游戏实现治愈动画)
如果我在 HTML 代码中内联 SVG,我想我可以让它工作,因为这可以让我直接访问样式,并重置样式 AFAIK DOES restart the animation,但我发现 HTML 中的内联图形很难看。这样做是我唯一的选择吗?
BTW display: none' 已被注释掉,因为根据链接的 SO 问题,它可能会与动画重置混淆(但对我来说并没有改变任何东西)。预加载对我来说似乎也没有太大变化,但由于 svgshare 的响应速度慢而需要。我在 Firefox、Windows 上。
【问题讨论】:
标签: javascript html css svg css-animations