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:
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.
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'];
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';
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 div
s
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 div
s 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 div
s
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 div
s evenly
demo on fiddle
the function generate(n, r, id)
takes 3 arguments: n
- number of div
s, 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 div
s 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 div
s, rx
, ry
radii along x , y-axis respectively , id
id
of div
want append elliptically arranged div
s 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
Post a Comment