45

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

enter image description here

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
Omid
  • 4,575
  • 9
  • 43
  • 74

5 Answers5

86

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.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • how do you know where the cycle is ? – Omid Apr 14 '12 at 09:21
  • You need to add the circle's coordinates, and subtract half of the element's dimensions, from `x` and `y` yourself. – Delan Azabani Apr 14 '12 at 09:23
  • @ThiefMaster 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 container – Omid Apr 14 '12 at 09:36
  • 1
    I really want to learn about this. Could you please some explanation with mathematical formula on your answer. Pretty Please :) – Starx Sep 28 '12 at 08:06
  • 1
    @Starx: Sounds like something worth a bounty ;) – ThiefMaster Sep 28 '12 at 11:11
  • 2
    @ThiefMaster, Common a diamond after your name and you are still greedy?? :P – Starx Sep 28 '12 at 15:24
  • This is great but does the variable "angle" hold an angular measurement? Doesn't it instead hold a value expressed radians? – NShiell Apr 04 '22 at 13:50
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).

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
Delan Azabani
  • 79,602
  • 28
  • 170
  • 210
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.
BananaAcid
  • 3,221
  • 35
  • 38
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.

Amit Kumar Khare
  • 565
  • 6
  • 17
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();
k1st
  • 81
  • 7