123 lines
4.1 KiB
JavaScript
123 lines
4.1 KiB
JavaScript
document.addEventListener("DOMContentLoaded", function () {
|
|
const astroCircle = document.getElementById("astroCircle");
|
|
if (!astroCircle) return;
|
|
|
|
const segmentNumbers = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
|
|
|
|
const circleSize = astroCircle.offsetWidth;
|
|
const centerX = circleSize / 2;
|
|
const centerY = circleSize / 2;
|
|
const radius = circleSize / 2;
|
|
|
|
const numberRadius = radius + (circleSize < 400 ? 18 : 28);
|
|
const signRadius = radius * 0.84;
|
|
|
|
drawSegments(astroCircle, centerX, centerY, radius, segmentNumbers, signNames, numberRadius, signRadius);
|
|
|
|
if (typeof samplePlanets !== "undefined" && Array.isArray(samplePlanets)) {
|
|
placePlanetsByLongitude(astroCircle, samplePlanets, centerX, centerY, radius);
|
|
}
|
|
});
|
|
|
|
function drawSegments(astroCircle, centerX, centerY, radius, segmentNumbers, signNames, numberRadius, signRadius) {
|
|
for (let i = 0; i < 12; i++) {
|
|
const angleDeg = i * 30;
|
|
|
|
const line = document.createElement("div");
|
|
line.classList.add("segment-line");
|
|
line.style.transform = `translateX(-50%) rotate(${angleDeg}deg)`;
|
|
astroCircle.appendChild(line);
|
|
|
|
const midAngle = angleDeg + 15;
|
|
const midRad = degToRad(midAngle - 90);
|
|
|
|
const numberX = centerX + numberRadius * Math.cos(midRad);
|
|
const numberY = centerY + numberRadius * Math.sin(midRad);
|
|
|
|
const number = document.createElement("div");
|
|
number.classList.add("segment-number");
|
|
number.innerText = segmentNumbers[i];
|
|
number.style.left = `${numberX}px`;
|
|
number.style.top = `${numberY}px`;
|
|
astroCircle.appendChild(number);
|
|
|
|
const signX = centerX + signRadius * Math.cos(midRad);
|
|
const signY = centerY + signRadius * Math.sin(midRad);
|
|
|
|
const sign = document.createElement("div");
|
|
sign.classList.add("sign-label");
|
|
sign.innerText = signNames[i];
|
|
sign.style.left = `${signX}px`;
|
|
sign.style.top = `${signY}px`;
|
|
astroCircle.appendChild(sign);
|
|
}
|
|
}
|
|
|
|
function placePlanetsByLongitude(astroCircle, planets, centerX, centerY, radius) {
|
|
const sortedPlanets = [...planets].sort((a, b) => {
|
|
return (a.longitude || 0) - (b.longitude || 0);
|
|
});
|
|
|
|
const usedSlots = [];
|
|
|
|
sortedPlanets.forEach((planet) => {
|
|
const longitude = normalizeLongitude(Number(planet.longitude || 0));
|
|
|
|
// 0° Aries starts at top, so subtract 90°
|
|
const angleRad = degToRad(longitude - 90);
|
|
|
|
// base position inside circle
|
|
let ringRadius = radius * 0.67;
|
|
|
|
// detect nearby planets and move slightly inward/outward
|
|
let closeCount = 0;
|
|
for (let i = 0; i < usedSlots.length; i++) {
|
|
const diff = smallestAngleDifference(longitude, usedSlots[i].longitude);
|
|
if (diff < 12) {
|
|
closeCount++;
|
|
}
|
|
}
|
|
|
|
// alternate offsets for crowded areas
|
|
if (closeCount > 0) {
|
|
const offsetPattern = [0, -18, 18, -32, 32, -44, 44];
|
|
const offset = offsetPattern[Math.min(closeCount, offsetPattern.length - 1)];
|
|
ringRadius += offset;
|
|
}
|
|
|
|
const x = centerX + ringRadius * Math.cos(angleRad);
|
|
const y = centerY + ringRadius * Math.sin(angleRad);
|
|
|
|
const planetEl = document.createElement("div");
|
|
planetEl.classList.add("planet-tag");
|
|
planetEl.innerText = planet.short;
|
|
planetEl.title =
|
|
`${planet.name} | ${planet.sign} | ${planet.degree} | ${planet.nakshatra} | ${longitude.toFixed(2)}°`;
|
|
|
|
planetEl.style.left = `${x}px`;
|
|
planetEl.style.top = `${y}px`;
|
|
|
|
astroCircle.appendChild(planetEl);
|
|
|
|
usedSlots.push({
|
|
longitude: longitude,
|
|
x: x,
|
|
y: y
|
|
});
|
|
});
|
|
}
|
|
|
|
function degToRad(deg) {
|
|
return deg * Math.PI / 180;
|
|
}
|
|
|
|
function normalizeLongitude(value) {
|
|
let result = value % 360;
|
|
if (result < 0) result += 360;
|
|
return result;
|
|
}
|
|
|
|
function smallestAngleDifference(a, b) {
|
|
let diff = Math.abs(a - b) % 360;
|
|
return diff > 180 ? 360 - diff : diff;
|
|
} |