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`)