html - Positioning divs in a circle using JavaScript -


i trying position 15 div elements evenly in circle radius of 150px. i'm using following code, seems give oddly eccentric ellipse overlaps.

fiddle

// hold global reference div#main element.  assign ... somewhere useful :)  var main = document.getelementbyid('main');  var circlearray = [];    // move circle based on distance of approaching mouse  var movecircle = function(circle, dx, dy) {    };    // @ circle elements, , figure out if of them have move.  var checkmove = function() {    };  var setup = function() {    (var = 0; < 15; i++) {      //create element, add array, , assign it's coordinates trigonometrically.      //then add "main" div      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round((150 * math.cos(i * (2 * math.pi / 15)))) + 'px';      circlearray[i].posy = math.round((150 * math.sin(i * (2 * math.pi / 15)))) + 'px';      circlearray[i].style.position = "relative";      circlearray[i].style.top = circlearray[i].posy;      circlearray[i].style.left = circlearray[i].posx;      main.appendchild(circlearray[i]);    }  };  setup();  window.addeventlistener('load', function() {    });
div {    box-sizing: border-box;  }  div#main {    position: absolute;    left: 50%;    top: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 10px;    -webkit-border-radius: 10px;    -moz-border-radius: 10px;  }
<div id="main"></div>

any suggestions might doing wrong?

first of all, equation co-ordinate on circle simply:

(x, y) = (r * cos(θ), r * sin(θ)) 

where, r radius of circle , θ angle in radians.


the reason why code creating eccentric ellipse because when assign .top , .left css values, not considering take top-left corner reference. i've fixed code , creates perfect circle.

changes made code:

  1. added array theta holds angles.

    var theta = [0, math.pi / 6, math.pi / 4, math.pi / 3, math.pi / 2, 2 * (math.pi / 3), 3 * (math.pi / 4), 5 * (math.pi / 6), math.pi, 7 * (math.pi / 6), 5 * (math.pi / 4), 4 * (math.pi / 3), 3 * (math.pi / 2), 5 * (math.pi / 3), 7 * (math.pi / 4), 11 * (math.pi / 6)]; 

    the image below shows angles i've used.

    enter image description here

  2. added array colors holds different colors.

    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue']; 
  3. made changes trigonometric equations.

    circlearray[i].posx = math.round(radius * (math.cos(theta[i]))) + 'px'; circlearray[i].posy = math.round(radius * (math.sin(theta[i]))) + 'px'; 
  4. changed way .top , .left assigned.

    circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px'; circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px'; 

    where mainheight height of #main div.


[1] 16 divs

demo on fiddle

var setup = function() {    var radius = 150;    var main = document.getelementbyid('main');    var mainheight = parseint(window.getcomputedstyle(main).height.slice(0, -2));    var theta = [0, math.pi / 6, math.pi / 4, math.pi / 3, math.pi / 2, 2 * (math.pi / 3), 3 * (math.pi / 4), 5 * (math.pi / 6), math.pi, 7 * (math.pi / 6), 5 * (math.pi / 4), 4 * (math.pi / 3), 3 * (math.pi / 2), 5 * (math.pi / 3), 7 * (math.pi / 4), 11 * (math.pi / 6)];    var circlearray = [];    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue'];    (var = 0; < 16; i++) {      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round(radius * (math.cos(theta[i]))) + 'px';      circlearray[i].posy = math.round(radius * (math.sin(theta[i]))) + 'px';      circlearray[i].style.position = "absolute";      circlearray[i].style.backgroundcolor = colors[i];      circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px';      circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px';      main.appendchild(circlearray[i]);    }  };  setup();
div#main {    height: 300px;    width: 300px;    position: absolute;    margin: 0 auto;    transform: translate(-50%, -50%);    top: 50%;    left: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 50%;  }  body {    margin: 0 auto;    background: papayawhip;  }
<div id="main"></div>


[2] 15 divs positioned evenly

demo on fiddle

var setup = function() {    var radius = 150;    var main = document.getelementbyid('main');    var mainheight = parseint(window.getcomputedstyle(main).height.slice(0, -2));    var theta = [0, (2 * (math.pi / 15)), (4 * (math.pi / 15)), (2 * (math.pi / 5)), (8 * (math.pi / 15)), (2 * (math.pi / 3)), (4 * (math.pi / 5)), (14 * (math.pi / 15)), (16 * (math.pi / 15)), (6 * (math.pi / 5)), (4 * (math.pi / 3)), (22 * (math.pi / 15)), (8 * (math.pi / 5)), (26 * (math.pi / 15)), (28 * (math.pi / 15))];    var circlearray = [];    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue'];    (var = 0; < 15; i++) {      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round(radius * (math.cos(theta[i]))) + 'px';      circlearray[i].posy = math.round(radius * (math.sin(theta[i]))) + 'px';      circlearray[i].style.position = "absolute";      circlearray[i].style.backgroundcolor = colors[i];      circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px';      circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px';      main.appendchild(circlearray[i]);    }  };  setup();
div#main {    height: 300px;    width: 300px;    position: absolute;    margin: 0 auto;    transform: translate(-50%, -50%);    top: 50%;    left: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 50%;  }  body {    margin: 0 auto;    background: papayawhip;  }
<div id="main"></div>


[3] better - 24 divs

demo on fiddle

var setup = function() {    var radius = 150;    var main = document.getelementbyid('main');    var mainheight = parseint(window.getcomputedstyle(main).height.slice(0, -2));    var theta = [0, math.pi / 12, math.pi / 6, math.pi / 4, math.pi / 3, 5 * (math.pi / 12), math.pi / 2, 7 * (math.pi / 12), 2 * (math.pi / 3), 3 * (math.pi / 4), 5 * (math.pi / 6), 11 * (math.pi / 12), math.pi, 13 * (math.pi / 12), 7 * (math.pi / 6), 5 * (math.pi / 4), 4 * (math.pi / 3), 17 * (math.pi / 12), 3 * (math.pi / 2), 19 * (math.pi / 12), 5 * (math.pi / 3), 7 * (math.pi / 4), 11 * (math.pi / 6), 23 * (math.pi / 12)];    var circlearray = [];    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue', 'coral', 'blueviolet', 'burlywood', 'cornflowerblue', 'crimson', 'darkgoldenrod', 'olive', 'sienna'];    (var = 0; <= 23; i++) {      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round(radius * (math.cos(theta[i]))) + 'px';      circlearray[i].posy = math.round(radius * (math.sin(theta[i]))) + 'px';      circlearray[i].style.position = "absolute";      circlearray[i].style.backgroundcolor = colors[i];      circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px';      circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px';      main.appendchild(circlearray[i]);    }  };  setup();
div#main {    height: 300px;    width: 300px;    position: absolute;    margin: 0 auto;    transform: translate(-50%, -50%);    top: 50%;    left: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 50%;  }  body {    margin: 0 auto;    background: papayawhip;  }
<div id="main"></div>


[4] , keeps getting better - dynamically position number of divs evenly

demo on fiddle

the function generate(n, r, id) takes 3 arguments: n - number of divs, r - radius , id - main in our case.

var theta = [];    var setup = function(n, r, id) {    var main = document.getelementbyid(id);    var mainheight = parseint(window.getcomputedstyle(main).height.slice(0, -2));    var circlearray = [];    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue', 'coral', 'blueviolet', 'burlywood', 'cornflowerblue', 'crimson', 'darkgoldenrod', 'olive', 'sienna', 'red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue', 'coral', 'blueviolet', 'burlywood', 'cornflowerblue', 'crimson', 'darkgoldenrod', 'olive', 'sienna'];    (var = 0; < n; i++) {      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round(r * (math.cos(theta[i]))) + 'px';      circlearray[i].posy = math.round(r * (math.sin(theta[i]))) + 'px';      circlearray[i].style.position = "absolute";      circlearray[i].style.backgroundcolor = colors[i];      circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px';      circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px';      main.appendchild(circlearray[i]);    }  };    var generate = function(n, r, id) {    var frags = 360 / n;    (var = 0; <= n; i++) {      theta.push((frags / 180) * * math.pi);    }    setup(n, r, id)  }  generate(40, 150, 'main');
div#main {    height: 300px;    width: 300px;    position: absolute;    margin: 0 auto;    transform: translate(-50%, -50%);    top: 50%;    left: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 50%;  }  body {    margin: 0 auto;    background: papayawhip;  }
<div id="main"></div>


[5] dynamically position number of divs on ellipse

the equation co-ordinate on ellipse is:

(x, y) = (rx * cos(θ), ry * sin(θ))

where, rx radius along x-axis , ry radius along y-axis.


in case, function generate(n, rx, ry, id) takes 4 arguments, n number of divs, rx , ry radii along x , y-axis respectively , id id of div want append elliptically arranged divs in.

demo on fiddle

var theta = [];    var setup = function(n, rx, ry, id) {    var main = document.getelementbyid(id);    var mainheight = parseint(window.getcomputedstyle(main).height.slice(0, -2));    var circlearray = [];    var colors = ['red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue', 'coral', 'blueviolet', 'burlywood', 'cornflowerblue', 'crimson', 'darkgoldenrod', 'olive', 'sienna', 'red', 'green', 'purple', 'black', 'orange', 'yellow', 'maroon', 'grey', 'lightblue', 'tomato', 'pink', 'maroon', 'cyan', 'magenta', 'blue', 'chocolate', 'darkslateblue', 'coral', 'blueviolet', 'burlywood', 'cornflowerblue', 'crimson', 'darkgoldenrod', 'olive', 'sienna'];    (var = 0; < n; i++) {      var circle = document.createelement('div');      circle.classname = 'circle number' + i;      circlearray.push(circle);      circlearray[i].posx = math.round(rx * (math.cos(theta[i]))) + 'px';      circlearray[i].posy = math.round(ry * (math.sin(theta[i]))) + 'px';      circlearray[i].style.position = "absolute";      circlearray[i].style.backgroundcolor = colors[i];      circlearray[i].style.top = ((mainheight / 2) - parseint(circlearray[i].posy.slice(0, -2))) + 'px';      circlearray[i].style.left = ((mainheight / 2) + parseint(circlearray[i].posx.slice(0, -2))) + 'px';      main.appendchild(circlearray[i]);    }  };    var generate = function(n, rx, ry, id) {    var frags = 360 / n;    (var = 0; <= n; i++) {      theta.push((frags / 180) * * math.pi);    }    setup(n, rx, ry, id)  }  generate(16, 150, 75, 'main');
div#main {    height: 300px;    width: 300px;    position: absolute;    margin: 0 auto;    transform: translate(-50%, -50%);    top: 50%;    left: 50%;  }  div.circle {    position: absolute;    width: 20px;    height: 20px;    border: 2px solid black;    border-radius: 50%;  }  body {    margin: 0 auto;    background: papayawhip;  }
<div id="main"></div>


edit[9th december 2015]:

here's more flexible version start offset, clock wise , anti-clock wise functionality.

/*  usage: position.ellipse(n, rx, ry, so, wh, idd, cls, cw);    n = number of divs,        rx = radius along x-axis,        ry = radius along y-axis,        = startoffset,        wh = width/height of divs,        idd = id of main div(ellipse),        cls = classname of divs;        cw = clockwise(true/false)  */    var position = {    ellipse: function(n, rx, ry, so, wh, idd, cls, cw) {      var m = document.createelement('div'),        ss = document.stylesheets;      ss[0].insertrule('#' + idd + ' { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); border-radius: 50%; box-shadow: inset 0 0 ' + wh + 'px ' + wh / 4 + 'px black; background: rgba(0, 0, 0, 0.2); width: ' + string((rx * 2) + wh) + 'px; height: ' + string((ry * 2) + wh) + 'px; }', 1);      ss[0].insertrule('.' + cls + '{ position: absolute; background: black; color: papayawhip; text-align: center; font-family: "open sans condensed", sans-serif; border-radius: 50%; transition: transform 0.2s ease; width: ' + wh + 'px; height: ' + wh + 'px; line-height: ' + wh + 'px;}', 1);      ss[0].insertrule('.' + cls + ':hover { transform: scale(1.2); cursor: pointer; background: rgba(0, 0, 0, 0.8); }', 1);      m.id = idd;      (var = 0; < n; i++) {        var c = document.createelement('div');        c.classname = cls;        c.innerhtml = + 1;        c.style.top = string(ry + -ry * math.cos((360 / n / 180) * (i + so) * math.pi)) + 'px';        c.style.left = string(rx + rx * (cw ? math.sin((360 / n / 180) * (i + so) * math.pi) : -math.sin((360 / n / 180) * (i + so) * math.pi))) + 'px';        m.appendchild(c);      }      document.body.appendchild(m);    }  }    position.ellipse(20, 150, 150, 0, 42, 'main', 'circle', true);
@import url(http://fonts.googleapis.com/css?family=open+sans+condensed:300);   body {    margin: 0 auto;    background: rgb(198, 193, 173);  }


Comments

Popular posts from this blog

java - Plugin org.apache.maven.plugins:maven-install-plugin:2.4 or one of its dependencies could not be resolved -

Round ImageView Android -

How can I utilize Yahoo Weather API in android -