Dynamically arrange some elements around a circle
Asked Answered
B

6

45

I'm looking for a function to arrange some elements around a circle.
result should be something like :

enter image description here

Business answered 14/4, 2012 at 9:8 Comment(3)
@camus my real problem is that i don't know trigonometry ;)Business
only for 4 elements or for n elements in same distance?Earth
@Earth n element with different distance.Business
H
87

Here's some code that should help you:

var numElements = 4,
    angle = 0
    step = (2*Math.PI) / numElements;
for(var i = 0; i < numElements.length; i++) {
    var x = container_width/2 + radius * Math.cos(angle);
    var y = container_height/2 + radius * Math.sin(angle);
    angle += step;
}

It is not complete but should give you a good start.


Update: Here's something that actually works:

var radius = 200; // radius of the circle
var fields = $('.field'),
    container = $('#container'),
    width = container.width(),
    height = container.height(),
    angle = 0,
    step = (2*Math.PI) / fields.length;
fields.each(function() {
    var x = Math.round(width/2 + radius * Math.cos(angle) - $(this).width()/2),
        y = Math.round(height/2 + radius * Math.sin(angle) - $(this).height()/2);
    $(this).css({
        left: x + 'px',
        top: y + 'px'
    });
    angle += step;
});

Demo: http://jsfiddle.net/ThiefMaster/LPh33/
Here's an improved version where you can change the element count.

Hoffer answered 14/4, 2012 at 9:16 Comment(7)
how do you know where the cycle is ?Business
You need to add the circle's coordinates, and subtract half of the element's dimensions, from x and y yourself.Pule
@Hoffer That's Ok friend, just i don't want to use relative positioning. how to do that if fields and cycle are not in the same containerBusiness
I really want to learn about this. Could you please some explanation with mathematical formula on your answer. Pretty Please :)Flexed
@Starx: Sounds like something worth a bounty ;)Hoffer
@ThiefMaster, Common a diamond after your name and you are still greedy?? :PFlexed
This is great but does the variable "angle" hold an angular measurement? Doesn't it instead hold a value expressed radians?Evildoer
P
15

For an element around a centre at (x, y), distance r, the element's centre should be positioned at:

(x + r cos(2kπ/n), y + r sin(2kπ/n))

where n is the number of elements, and k is the "number" of the element you're currently positioning (between 1 and n inclusive).

Pule answered 14/4, 2012 at 9:18 Comment(2)
xy means the same thing as x * y in mathematics.Pule
What is the formula for placing them in an ellipse?Avellaneda
O
6

I've combined ThiefMaster's fiddle with the jQuery pointAt plugin:

Demo: http://jsfiddle.net/BananaAcid/nytN6/

the code is somewhat like above.
might be interesting to some of you.
Orji answered 28/7, 2013 at 18:36 Comment(0)
T
1

Arrange Elements In Circle (Javascript)

function arrangeElementsInCircle (elements, x, y, r) {
    for (var i = 0; i < elements.length; i++) {
        elements[i].scaleX = 1 / elements.length
        elements[i].scaleY = 1 / elements.length
        elements[i].x = (x + r * Math.cos((2 * Math.PI) * i/elements.length))
        elements[i].y = (y + r * Math.sin((2 * Math.PI) * i/store.length))
    }
}

Where x,y is point co-ordinates and elements is array of elements to be placed and r is radius.

Tele answered 22/6, 2018 at 6:44 Comment(0)
D
0

Javascript only version of thiefmaster's answer

function distributeFields(deg){
  deg = deg || 0;
  var radius = 200;
  var fields = document.querySelectorAll('.field'), //using queryselector instead of $ to select items 
      container = document.querySelector('#container'),
      width = container.offsetWidth,  //offsetWidth gives the width of the container
      height = container.offsetHeight,
      angle = deg || Math.PI * 3.5,
      step = (2 * Math.PI) / fields.length;
      console.log(width, height)
      
     //using forEach loop on a NodeList instead of a Jquery .each, 
     //so we can now use "field" as an iterator instead of $(this)

      fields.forEach((field)=>{
        var x = Math.round(width / 2 + radius * Math.cos(angle) - field.offsetWidth/2);
        var y = Math.round(height / 2 + radius * Math.sin(angle) - field.offsetHeight/2);
        console.log(x, y)
        field.style.left = x + 'px';  //adding inline style to the document (field)
        field.style.top= y + 'px';

        angle += step;
      })
}

distributeFields();
Deep answered 19/1, 2021 at 16:32 Comment(2)
Please add comments to your code to explain your answerCsch
Thank you, added the commentsDeep
B
0

In the html there is the data-gap attribute where you can enter the gap between center circle and small circles.

var cs = document.getElementsByClassName('c');
var center = document.getElementById("center");
var amount = cs.length;
var startAngle = -90;
var angleToAdd = 360 / amount;
var offsetPx = -(cs[0].offsetWidth / 2) + (center.offsetWidth / 2);
var radius = (center.offsetWidth / 2) + (cs[0].offsetWidth / 2) + parseInt(center.dataset.gap);

for (i = 0; i < cs.length; i++) {
  angle = startAngle * Math.PI / 180;
  var x = (radius * Math.cos(angle)) + offsetPx;
  var y = (radius * Math.sin(angle)) + offsetPx;
  cs[i].style.transform = "translate(" + x + "px," + y + "px)";
  startAngle += angleToAdd;
}
#display {
  background: gray;
  width: 100%;
  height: 300px;
  border-radius: 10px;
  position: relative;
}

#center {
  width: 130px;
  aspect-ratio: 1;
  background: gold;
  border: 2px solid teal;
  color: white;
  position: relative;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 100%;
}

.c {
  width: 50px;
  aspect-ratio: 1;
  background: gold;
  border: 2px solid teal;
  color: white;
  position: absolute;
  border-radius: 100%;
}
<section id="display">
  <div id="center" data-gap="15">
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
    <div class="c"></div>
  </div>
</section>
Bogosian answered 11/1 at 14:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.