0

I've been dabbling around with web development to try to pick up a new hobby.

A goal of mine is to figure out the best way to draw 1000 circles (using css), 100 by 100, that resize with the window so there will always been 100 columns and 100 rows. I figured out how to manually draw them all (using Responsive CSS Circles but I'd rather not create 1000 divs.

I would like to figure out a way to draw these circles using a loop, but once I started dabbling with positioning and css things started becoming really difficult for me.

Does anybody have any resources I could reference, or some experience with how to do mass drawing efficiently?

Thanks!

Community
  • 1
  • 1
A O
  • 5,066
  • 3
  • 28
  • 54
  • 100 x 100 would be 10,000 circles. Is that what you meant? – Rick Hitchcock Dec 25 '14 at 18:29
  • Yes haha but the number doesn't matter, I was just using an example. I just want to figure out how to draw a specific number of rows and columns of circles that resize-- without having to manually specify each circle – A O Dec 26 '14 at 18:48

2 Answers2

1

You can do this fairly efficiently in JavaScript, by creating 10,000 divs with these styles:

.circle {
  box-sizing: border-box;  //include border in total width
  width: 0.8%;             //width + margin === 1%, 
  margin: 0.1%;            //... so 100 circles will fill up their container's width
  border: 1px solid #aaa;  //light gray border
  border-radius: 50%;      //create a circle
  float: left;             //put divs next to each other
}

Here's the HTML:

<div id="circles"></div>

Here's the code to create 100,000 circles:

function makeCircles() {
  var x, y, 
      circle,
      div = document.querySelector('#circles');

  for(x = 1 ; x <= 100 ; x++) {
    for(y = 1 ; y <= 100 ; y++) {
      circle= document.createElement('div');
      circle.className = 'circle';
      div.appendChild(circle);
    }
  }
} //makeCircles

height should be equal to width in pixels, so we can't use a percentage for it. It's inefficient to change the height of each circle individually, but we can add a style to the class using JavaScript.

First, we need to get the circle class rules:

var styleSheets = document.styleSheets,
    circle,
    i, j;

for(i = 0 ; i < styleSheets.length ; i++) {
  rules= styleSheets[i].rules ||
         styleSheets[i].cssRules;
  for(j = 0 ; j < rules.length ; j++) {
    if(rules[j].selectorText==='.circle') {
      circle= rules[j];
      break;
    }
  }
}

Now we can make the height equal to the width when resizing the window:

window.onresize= function() {
  var div = document.querySelector('#circles');
  circle.style.height= div.childNodes[0].offsetWidth+'px';
}

Complete fiddle at http://jsfiddle.net/53rf1kez/

Tested in Chrome, IE11, Firefox, and Opera.

Update

Here's an alternative script, which adds a break at the end of each y loop, and changes the container's line height in onsize. It also adds a timer, so that onsize isn't called continuously during resizing:

http://jsfiddle.net/hupw8mfg/

It may be slightly more efficient, because the browser doesn't have to determine where to wrap.

Rick Hitchcock
  • 33,093
  • 3
  • 40
  • 70
  • Thanks for your time! I've been playing around with it, and have a few questions. Why the nested for loops to generate the circles? And do you have any idea how to force a set number of circles per row? Or am I implementing this wrong? I read through the code and I think I understand it, but I don't see anywhere where this happens – A O Dec 26 '14 at 18:36
  • 1
    The 1% distance between divs ensures 100 circles per row, so you're right that only one loop is needed. New rows are automatically added due to wrapping. An alternative method would be to append a `br` element at the end of each y loop. You'll need to change the container's line height in onsize to make that work. I'm on my cell today so can't test that. – Rick Hitchcock Dec 27 '14 at 13:50
  • Thanks for all the time you've put in thusfar! I'd give you more reputation if I could. I have a quick question, you manually call window.onresize(); Is this okay to put directly into my main .js file at the bottom? It kind of makes me uneasy because the file has a bunch of function definitions, and then at the bottom it just calls one of the functions – A O Dec 27 '14 at 18:15
  • 1
    Absolutely fine to do it that way. – Rick Hitchcock Dec 27 '14 at 18:55
  • To me, it would seem to make more sense to import the script in the html, and then call that method also in the HTML. However, when I tried doing that, it didn't work-- and it only seemed to work when I made the method call from within the javascript file. Do you know why that is? It looks liked this in the HTML: – A O Dec 27 '14 at 21:37
  • You may need to put `makeCircles` within a `DOMContentLoaded` event. See http://stackoverflow.com/questions/8575940/how-to-know-when-page-is-ready-without-using-jquery-alternative-way. – Rick Hitchcock Dec 30 '14 at 23:13
0

You can do this by using multiple backgrounds and an SVG image. The css for the backgrounds could be generated in a loop via a CSS preprocessor.

Here is what it would look like for a 4x4 grid (and on jsfiddle):

#container{
 position: relative;
 width: 100%;
}
#container:before{
 content: '';
 display: block;
 padding-top:100%;
}
#content{
 position:  absolute;
 top: 0;
 left: 0;
 bottom: 0;
 right: 0;
  
    background: 
        /* 1st row */
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 0 0 / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 33.3% 0 / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 66.6% 0 / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 100% 0 / 25%,
        
        /* 2nd row */
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 0 33.3% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 33.3% 33.3% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 66.6% 33.3% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 100% 33.3% / 25%,
        
        /* 3rd row */
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 0 66.6% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 33.3% 66.6% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 66.6% 66.6% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 100% 66.6% / 25%,
        
        /* 4th row */
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 0 100% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 33.3% 100% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 66.6% 100% / 25%,
        url(http://upload.wikimedia.org/wikipedia/commons/3/3a/Kleurencirkel.svg) no-repeat 100% 100% / 25%;
}
<div id="container">
  <div id="content"></div>
</div>
Talmid
  • 963
  • 10
  • 16