Estoy tratando de alinear elementos alrededor de un círculo como este:
este es mi código, he agregado una función de arrastre para rotar el cuadro contenedor, no soy muy experto en matemáticas, así que no sé a dónde ir desde aquí.
https://codepen.io/pedro_coelho/pen/GRQKWPW
const box = wrapper.getBoundingClientRect() const xCenter = (box.left + box.right) / 2; const yCenter = (box.top + box.bottom) / 2; console.log(xCenter, yCenter); wrapper.style.transformOrigin = `${xCenter}, ${yCenter}`; //wrapper.style.transform = 'rotate(30deg)'; document.onmousedown = dragMouseDown; let mouseX, mouseY, offsetX,offsetY; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); // get the mouse cursor position at startup: mouseX = e.clientX; mouseY = e.clientY; document.onmouseup = closeDragElement; // call a function whenever the cursor moves: document.onmousemove = elementDrag; } function elementDrag(e) { e = e || window.event; e.preventDefault(); // calculate the new cursor position: offsetX = mouseX - e.clientX; offsetY = mouseY - e.clientX; // rotate: wrapper.style.transform = `rotate(${offsetX/5}deg)`; } function closeDragElement() { // stop moving when mouse button is released: document.onmouseup = null; document.onmousemove = null; }En lugar de hacer los cálculos usted mismo, CSS puede ayudar, ya que rotará un elemento una cantidad determinada de grados.
Si creamos elementos que tienen una altura, el radio del círculo y algo de ancho (que usted decida) y los colocamos en el centro superior del elemento contenedor (.circle), podemos rotar el enésimo sobre su punto central inferior un número de grados dependiendo en su posición de niño.
Esto podría darnos algo como esto para 10 elementos con un ángulo de 36 grados entre ellos:
Dentro de cada uno de esos elementos (o los que desee mostrar) puede colocar sus divs que tienen la imagen y cualquier otra cosa que desee, en la parte superior del elemento.
Luego tenemos que girar todo el círculo hacia atrás una cantidad para obtener el mismo número de elementos a cada lado de la vertical.
Este fragmento utiliza variables CSS para realizar el cálculo y puede establecer la cantidad de elementos que se mostrarán y el ángulo entre ellos, CSS hace el resto.
.circle { position: relative; --w: 50vmin; width: var(--w); height: var(--w); rdisplay: flex; --show: 5; /* put to the number you want to have */ --angle: 36; /* put to the angle between them */ --num: calc(360 / var(--angle)); transform: rotate(calc(((var(--show) + 1) / 2 * var(--angle)) * -1deg)); } .element { width: calc(var(--w) / 6); /* set to whatever width you want */ height: 50%; top: 0; left: calc(50% - 1vw); transform-origin: center bottom; transform: rotate(calc(360deg * var(--n) / var(--num))); position: absolute; } .element>* { background-position: center center; background-size: contain; background-repeat: no-repeat; position: absolute; top: 0; left: 0; width: 100%; aspect-ratio: 1 / 1.5; /* put this to what you want */ } .element:nth-child(1) { --n: 1; } .element:nth-child(2) { --n: 2; } .element:nth-child(3) { --n: 3; } .element:nth-child(4) { --n: 4; } .element:nth-child(5) { --n: 5; } .element:nth-child(1)>* { background-image: url(https://picsum.photos/id/1015/200/200); } .element:nth-child(2)>* { background-image: url(https://picsum.photos/id/1015/200/200); } .element:nth-child(3)>* { background-image: url(https://picsum.photos/id/1015/200/200); } .element:nth-child(4)>* { background-image: url(https://picsum.photos/id/1015/200/200); } .element:nth-child(5)>* { background-image: url(https://picsum.photos/id/1015/200/200); } <meta name="viewport" content="width=device-width, initial-scale=1"> <div class="circle"> <div class="element"> <div></div> </div> <div class="element"> <div></div> </div> <div class="element"> <div></div> </div> <div class="element"> <div></div> </div> <div class="element"> <div></div> </div> </div>