Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to make a for loop to draw an SVG

Tags:

javascript

svg

I have just started learning about SVGs and wanted to create a for loop to draw many circles in my HTML. Can it be done the way I'm trying to do it, or is what I'm trying to do not possible?

<html>
<body>

<h1>My first SVG for loop</h1>

<script type="text/javascript">
    
    var circlex = 50; 
    var circley = 50;

    for (var i = 0; i < 100; i++) {

    <svg width="100" height="100">
         <circle cx="circlex + 1" cy="circley + 1" r="40" stroke="green" stroke-width="4" fill="yellow" />
    </svg>
    };

</script>

</body>
</html>
like image 404
user2703522 Avatar asked Dec 10 '15 11:12

user2703522


2 Answers

So close yet so far

You can not put html code directly into JavaScript (that would be cool)
The way JavaScript adds new elements is through DOM manipulation.
So let's go trough the code:

  1. First created an empty SVG document with an xmlns (just set xmlns="http://www.w3.org/2000/svg", it works 99% of the time) and we need an ID to select the element.
  2. Get the SVG element in JavaScript: document.getElementById("svg_circles"). Here we use the ID we set on the element to save it to a variable.
  3. In the for loop: create a circle element: var circle = document.createElementNS(NS, "circle"); The namespace NS is found in 1. it's http://www.w3.org/2000/svg. This seems complex but is needed and just something you have to memorize.
  4. Set circle attributes: now to the attributes: I set the position cx and cy with .setAttribute(). You can try to position them differently. I also set the size r attribute and the fill (the long line of code on the fill is just for fun on my part, it creates random colors)
  5. Now we are done with the circles, but the JavaScript code does not know where to put them. So we tell it: svgCircle.appendChild() sets the element as a child of our SVG document. So: svgCircle.appendChild(circle); where circle is the created SVG element.

document.addEventListener("DOMContentLoaded", function(event) {
  var circlex = 0;
  var circley = 0;

  var svgCircle = document.getElementById("svg_circles");
  var NS = "http://www.w3.org/2000/svg";
  for (var i = 0; i < 100; i++) {
    var circle = document.createElementNS(NS, "circle");
    console.log(circle);
    circle.setAttribute("cx", circlex + i);
    circle.setAttribute("cy", circley + i);
    circle.setAttribute("r", 10);
    circle.setAttribute("fill", "rgb(" + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + "," + Math.floor(Math.random() * 255) + ")");
    svgCircle.appendChild(circle);
  };
});
<svg id="svg_circles" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
</svg>
like image 70
Persijn Avatar answered Sep 30 '22 18:09

Persijn


It is little bit complex than your example, here is fiddle where I converted your pseudo code to js code. This approach could be ok if you using some server side rendering e.g. .net mvc and than iterate svg element. But in js you need to create dom elements pass the configuration and than append that to dom. Here is code: https://jsfiddle.net/9c7ro6x3/1/

  var circlex = 50;
  var circley = 50;

  var svg = document.createElementNS("http://www.w3.org/2000/svg", 'svg');
  for (var i = 0; i < 100; i++) {
   circlex = circlex + 1;
   circley = circley + 1;

   var circle = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
   circle.setAttribute("cx", circlex);
   circle.setAttribute("cy", circley);
   circle.setAttribute("r", "40");
   circle.setAttribute("stroke", "green");
   circle.setAttribute("strokeWidth", 4);
   circle.setAttribute("fill", "yellow");
   svg.appendChild(circle);
};
document.body.appendChild(svg);
like image 37
Grissom Avatar answered Sep 30 '22 19:09

Grissom