动态动画 svg 元素
Dynamically animate an svg element
我正在实现一个简单的游戏,玩家要控制屏幕中间的一个红色圆圈。圆作为 SVG 元素实现。
我希望能够使用 SVG 动画 (SMIL) 在 SVG viewBox 中的任意两个位置之间移动圆圈。每个动画的触发器是左键单击屏幕上的任意位置。
我已经 written code,我相信它应该可以在 Firefox 和 Chrome 中使用。在 Chrome 中,它仅适用于第一个动画,而对于所有后续动画,圆仅适用于 "teleports"。在 Firefox 中没有动画 (并且控制台中没有错误).
我的代码中是否存在错误,或者 SMIL 是否过于不成熟是否存在一些众所周知的问题?
我能否让 SMIL 在此用例中工作,还是应该改用 canvas?
这是我目前得到的代码:
<!DOCTYPE html>
<html>
<body>
<svg id="canvas" width="800" height="800" onclick="Move()">
<circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
</circle>
</svg>
<script>
function createAnimation(attribute, playerID, duration, from, to) {
var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
animation.setAttribute("attributeType", "XML")
animation.setAttribute("attributeName", attribute)
animation.setAttribute("dur", duration)
animation.setAttribute("to", to)
animation.setAttribute("from", from)
animation.setAttribute("fill", "freeze")
animationID = playerID + "animation" + attribute
animation.setAttribute("id", animationID)
player = document.getElementById(playerID)
previous_animation = document.getElementById(animationID)
if (previous_animation != null) {
player.removeChild(previous_animation)
}
player.appendChild(animation)
}
function Move() {
console.log(event.clientX);
console.log(event.clientY);
createAnimation("cx", "player1", "2s", document.getElementById("player1").getAttribute("cx"), event.clientX);
createAnimation("cy", "player1", "2s", document.getElementById("player1").getAttribute("cy"), event.clientY);
}
</script>
</body>
</html>
有很多问题...
- Firefox 中没有事件(或更确切地说是 evt)对象,除非您从调用者那里传递一个对象。此错误确实出现在 Firefox 浏览器控制台中。
- Firefox 仍然实现了 SVG 1.1 动画,它不会更新属性值,您需要调用 animVal 来获取值
- 动画一次后,时间轴现在为 2 秒,因此下次您在 2 秒的文档中为 0-2 秒的动画制作动画时,它会跳到那里。每当下面的答案有变动时,我都会将时间轴重置为 0。
<!DOCTYPE html>
<html>
<body>
<svg id="canvas" width="800" height="800" onclick="Move(evt)">
<circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
</circle>
</svg>
<script>
function createAnimation(attribute, playerID, duration, from, to) {
var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
animation.setAttribute("attributeType", "XML")
animation.setAttribute("attributeName", attribute)
animation.setAttribute("dur", duration)
animation.setAttribute("to", to)
animation.setAttribute("from", from)
animation.setAttribute("fill", "freeze")
animationID = playerID + "animation" + attribute
animation.setAttribute("id", animationID)
player = document.getElementById(playerID)
previous_animation = document.getElementById(animationID)
if (previous_animation != null) {
player.removeChild(previous_animation)
}
player.appendChild(animation)
}
function Move(evt) {
console.log(evt.clientX);
console.log(evt.clientY);
createAnimation("cx", "player1", "2s", document.getElementById("player1").cx.animVal.value, evt.clientX);
createAnimation("cy", "player1", "2s", document.getElementById("player1").cy.animVal.value, evt.clientY);
document.getElementById("canvas").setCurrentTime(0);
}
</script>
</body>
</html>
我正在实现一个简单的游戏,玩家要控制屏幕中间的一个红色圆圈。圆作为 SVG 元素实现。
我希望能够使用 SVG 动画 (SMIL) 在 SVG viewBox 中的任意两个位置之间移动圆圈。每个动画的触发器是左键单击屏幕上的任意位置。
我已经 written code,我相信它应该可以在 Firefox 和 Chrome 中使用。在 Chrome 中,它仅适用于第一个动画,而对于所有后续动画,圆仅适用于 "teleports"。在 Firefox 中没有动画 (并且控制台中没有错误).
我的代码中是否存在错误,或者 SMIL 是否过于不成熟是否存在一些众所周知的问题?
我能否让 SMIL 在此用例中工作,还是应该改用 canvas?
这是我目前得到的代码:
<!DOCTYPE html>
<html>
<body>
<svg id="canvas" width="800" height="800" onclick="Move()">
<circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
</circle>
</svg>
<script>
function createAnimation(attribute, playerID, duration, from, to) {
var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
animation.setAttribute("attributeType", "XML")
animation.setAttribute("attributeName", attribute)
animation.setAttribute("dur", duration)
animation.setAttribute("to", to)
animation.setAttribute("from", from)
animation.setAttribute("fill", "freeze")
animationID = playerID + "animation" + attribute
animation.setAttribute("id", animationID)
player = document.getElementById(playerID)
previous_animation = document.getElementById(animationID)
if (previous_animation != null) {
player.removeChild(previous_animation)
}
player.appendChild(animation)
}
function Move() {
console.log(event.clientX);
console.log(event.clientY);
createAnimation("cx", "player1", "2s", document.getElementById("player1").getAttribute("cx"), event.clientX);
createAnimation("cy", "player1", "2s", document.getElementById("player1").getAttribute("cy"), event.clientY);
}
</script>
</body>
</html>
有很多问题...
- Firefox 中没有事件(或更确切地说是 evt)对象,除非您从调用者那里传递一个对象。此错误确实出现在 Firefox 浏览器控制台中。
- Firefox 仍然实现了 SVG 1.1 动画,它不会更新属性值,您需要调用 animVal 来获取值
- 动画一次后,时间轴现在为 2 秒,因此下次您在 2 秒的文档中为 0-2 秒的动画制作动画时,它会跳到那里。每当下面的答案有变动时,我都会将时间轴重置为 0。
<!DOCTYPE html>
<html>
<body>
<svg id="canvas" width="800" height="800" onclick="Move(evt)">
<circle id="player1" cx="300" cy="300" r="40" stroke="blue" stroke-width="4" fill="red">
</circle>
</svg>
<script>
function createAnimation(attribute, playerID, duration, from, to) {
var animation = document.createElementNS("http://www.w3.org/2000/svg", "animate")
animation.setAttribute("attributeType", "XML")
animation.setAttribute("attributeName", attribute)
animation.setAttribute("dur", duration)
animation.setAttribute("to", to)
animation.setAttribute("from", from)
animation.setAttribute("fill", "freeze")
animationID = playerID + "animation" + attribute
animation.setAttribute("id", animationID)
player = document.getElementById(playerID)
previous_animation = document.getElementById(animationID)
if (previous_animation != null) {
player.removeChild(previous_animation)
}
player.appendChild(animation)
}
function Move(evt) {
console.log(evt.clientX);
console.log(evt.clientY);
createAnimation("cx", "player1", "2s", document.getElementById("player1").cx.animVal.value, evt.clientX);
createAnimation("cy", "player1", "2s", document.getElementById("player1").cy.animVal.value, evt.clientY);
document.getElementById("canvas").setCurrentTime(0);
}
</script>
</body>
</html>