Skip to content
Advertisement

Svg animations replaying in the same spot

I am working on a tower defense game with HTML, CSS, and JS. I want to be able to create svg circles that will follow a path using an svg animation. In order to do this, I wrote this code:

<div id="trackPart">
  <progress id="healthBar" max="200" value="200" onclick="this.value = randInt(0, this.max)" ></progress>
  <svg viewbox="0 0 1000 3000" id="track" xmlns="http://www.w3.org/2000/svg">
    <path id="path" fill="none" stroke="red" stroke-width="15" d="M 0, 50 h 900 v 100 h -800 v 100 h 800 v 300 h -900" style="cursor: pointer"/>
  </svg>
</div>
var path = document.getElementById("path")
var svgurl = "http://www.w3.org/2000/svg"
var svg = document.getElementById("track")

listOfColors = ["green", "blue", "purple", "lime", "yellow"]

function attackerSVG(color) {
  let element = document.createElementNS(svgurl, "circle")
  element.setAttribute("cx", 0)
  element.setAttribute("cy", 0)
  element.setAttribute("r", 15)
  element.setAttribute("fill", color)

  let animation = document.createElementNS(svgurl, "animateMotion")
  animation.setAttribute("dur", "30s")
  animation.setAttribute("repeatCount", "indefinite")
  animation.setAttribute("rotate", "auto")
  animation.setAttribute("path", String(path.getAttribute("d")))
  animation.setAttribute("onrepeat", "console.log("repeat")")
  animation.setAttribute("restart", "always")
  animation.beginElement()

  element.appendChild(animation)
  svg.appendChild(element)
  return element
}

attackerSVG("black")

The first time I run the attackerSvg function, everything works fine. A circle is created at the start of the path and follows it. However, once I create another one, it starts its animation sequence where the other svg circles are. If you want to see what I mean, you can go here https://replit.com/@hello1964/Tower-defense-game#script.js

Whenever you see the circle change color, it’s a new circle being created. When you look in the console it will print “repeat” every time a circle finishes a cycle. Since they are all in the same spot, it will print it multiple times. I would really appreciate the help, thank you.

Advertisement

Answer

SVG maintain their own timings. Adding an element to the SVG, will start it at the current clock. To do what you want, you actually need to delay the start

// outside globally somwhere
let count = 0;

// inside function attackerSVG
animation.setAttribute('begin', `${++count}s`)
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement