圆
公式
(x0, y0) 圆心坐标
r:半径
x = x0 + cos(angle) * r
y = y0 + sin(angle) * r
1、轨迹
<div id="div" style="position:relative; width: 20px; height: 20px; background: cadetblue;"></div><script>/*** 圆心 (x0, y0)* 坐标* x1 = x0 + cos(angle * Math.PI / 180) * r* y1 = y0 + sin(angle * Math.PI / 180) * r*/const div = document.querySelector('#div');const x0 = 300;const y0 = 400;const r = 100;let angle = 0;let x = x0 + Math.cos(angle) * r;let y = y0 + Math.sin(angle) * r;div.style.top = `${y}px`;div.style.left = `${x}px`;setInterval(() => {angle += 1;x = x0 + Math.cos(angle * Math.PI / 180) * r;y = y0 + Math.sin(angle * Math.PI / 180) * r;div.style.top = `${y}px`;div.style.left = `${x}px`;}, 10);</script>
2、轨迹分布
<style>body {margin: 0;padding: 0;height: 100vh;}.item {position: absolute;width: 20px;height: 20px;}
</style><div style="position: relative;display: flex;justify-content: center;height: 100%; align-items: center;"><div class="item" style="background-color: red;"></div><div class="item" style="background-color: rgb(255, 170, 0);"></div><div class="item" style="background-color: rgb(0, 157, 255);"></div><div class="item" style="background-color: rgb(0, 81, 255);"></div><div class="item" style="background-color: rgb(0, 255, 115);"></div><div class="item" style="background-color: rgb(187, 255, 0);"></div><div class="item" style="background-color: red;"></div><div class="item" style="background-color: rgb(255, 170, 0);"></div><div class="item" style="background-color: rgb(0, 157, 255);"></div><div class="item" style="background-color: rgb(0, 81, 255);"></div><div class="item" style="background-color: rgb(0, 255, 115);"></div><div class="item" style="background-color: rgb(187, 255, 0);"></div></div><script>/*** 圆心 (x0, y0)* 坐标* x1 = x0 + cos(angle * Math.PI / 180) * r* y1 = y0 + sin(angle * Math.PI / 180) * r*/const div = document.querySelectorAll('.item');const amount = div.length;const x0 = 300;const y0 = 400;const r = 100;const single = 360 / amount;for (let i = 0; i < amount; i++) {const x = x0 + Math.cos(single * i * Math.PI / 180) * r - 10;const y = y0 + Math.sin(single * i * Math.PI / 180) * r - 10;div[i].style.left = `${x}px`;div[i].style.top = `${y}px`;}</script>
3、圆形旋转样例
// 以下代码只适用于节点为偶数个
<style>body {margin: 0;padding: 0;height: 100vh;}.item {position: absolute;width: 20px;font-size: 22px;color: rgb(45, 234, 105);text-align: center;}.content {position: absolute;width: 100px;height: 100px;background-color: antiquewhite;top: 350px;left: 250px;text-align: center;line-height: 100px;border-radius: 50%;font-size: 30px;color: aqua;}
</style><body><div style="position: relative;display: flex;justify-content: center;height: 100%; align-items: center;"><div class="content" id="content"></div><div id="item0" class="item" data-id="item-0"><div id="item-0" style="background-color: red;"></div>0</div><div id="item1" class="item" data-id="item-1"><div id="item-1" style="background-color: rgb(255, 170, 0);"></div>1</div><div id="item2" class="item" data-id="item-2"><div id="item-2" style="background-color: rgb(0, 157, 255);"></div>2</div><div id="item3" class="item" data-id="item-3"><div id="item-3" style="background-color: rgb(0, 81, 255);"></div>3</div><div id="item4" class="item" data-id="item-4"><div id="item-4" style="background-color: rgb(0, 255, 115);"></div>4</div><div id="item5" class="item" data-id="item-5"><div id="item-5" style="background-color: rgb(187, 255, 0);"></div>5</div><div id="item6" class="item" data-id="item-6"><div id="item-6" style="background-color: red;"></div>6</div><div id="item7" class="item" data-id="item-7"><div id="item-7" style="background-color: rgb(255, 170, 0);"></div>7</div><div id="item8" class="item" data-id="item-8"><div id="item-8" style="background-color: rgb(0, 157, 255);"></div>8</div><div id="item9" class="item" data-id="item-9"><div id="item-9" style="background-color: rgb(0, 81, 255);"></div>9</div><div id="item10" class="item" data-id="item-10"><div id="item-10" style="background-color: rgb(0, 255, 115);"></div>10</div><div id="item11" class="item" data-id="item-11"><div id="item-11" style="background-color: rgb(187, 255, 0);"></div>11</div></div><script>/*** 圆心 (x0, y0)* 坐标* x1 = x0 + cos(angle) * r* y1 = y0 + sin(angle) * r*/const div = document.querySelectorAll('.item');const amount = div.length;/*** 圆心坐标* 半径* @type {number}*/const x0 = 300;const y0 = 400;const r = 200;// 旋转角度const single = 360 / amount;// 中间显示内容判断let judgeXY = 0;let fontSizeList = [];function init() {for (let i = 0; i < amount; i++) {const ele = div[i];const angle = single * i * Math.PI / 180;const {x, y, sin} = getLocalInfo(i, angle);const fontSize = 22 + sin * 10;fontSizeList.push({i,fontSize});changeDom(ele, sin, angle, x, y, fontSize);}// 判断是否为最前面的元素fontSizeList.sort((a, b) => b.fontSize - a.fontSize);const {i, fontSize} = fontSizeList[0];document.querySelector('#content').innerText = div[i].innerText;judgeXY = fontSize;}// 循环方法function loop() {for (let i = 0; i < amount; i++) {const ele = div[i];const oldAngle = +ele.getAttribute('angle');const angle = single * Math.PI / 180;const newAngle = oldAngle - angle;const {x, y, sin} = getLocalInfo(i, newAngle);const fontSize = 22 + sin * 10;// 处理元素changeDom(ele, sin, newAngle, x, y, fontSize);// 控制显示信息if (fontSize === judgeXY) {document.querySelector('#content').innerText = ele.innerText;}}}/*** 获取坐标和缩放比* */function getLocalInfo(i, angle) {// 调整第一个元素在正下方 多余加90度const rotate = angle + Math.PI / 2;const x = x0 + Math.cos(rotate) * r - 10;const y = y0 + Math.sin(rotate) * r - 10;// 近大远小去处理const sin = +Math.sin(rotate).toFixed(3);return {x,y,sin}}/*** 这里应该通过 transform: scale() 来控制元素大小*/function changeDom(ele, sin, newAngle, x, y, fontSize) {const id = ele.dataset.id;// 父元素ele.style.fontSize = `${fontSize}px`;ele.setAttribute('angle', newAngle);ele.style.left = `${x}px`;ele.style.top = `${y}px`;// 子元素const contentDom = document.querySelector(`#${id}`);contentDom.style.width = `${20 + sin * 10}px`;contentDom.style.height = `${20 + sin * 10}px`;contentDom.style.margin = `0 auto`}init();setInterval(loop, 2000);</script>
</body>
椭圆
由圆轨迹公式可得出x = x0 + Math.cos(angle) * rx;y = y0 + Math.sin(angle) * ry;rx、ry分别为x轴上的焦半径,y轴的焦半径
// 以下代码只适用于节点为偶数个body {margin: 0;padding: 0;height: 100vh;}.item {position: absolute;width: 20px;font-size: 22px;color: rgb(45, 234, 105);text-align: center;}.content {position: absolute;width: 100px;height: 100px;background-color: antiquewhite;top: 350px;left: 550px;text-align: center;line-height: 100px;border-radius: 50%;font-size: 30px;color: aqua;}
</style><body><div style="position: relative;display: flex;justify-content: center;height: 100%; align-items: center;"><div class="content" id="content"></div><div id="item0" class="item" data-id="item-0"><div id="item-0" style="background-color: red;"></div>0</div><div id="item1" class="item" data-id="item-1"><div id="item-1" style="background-color: rgb(255, 170, 0);"></div>1</div><div id="item2" class="item" data-id="item-2"><div id="item-2" style="background-color: rgb(0, 157, 255);"></div>2</div><div id="item3" class="item" data-id="item-3"><div id="item-3" style="background-color: rgb(0, 81, 255);"></div>3</div><div id="item4" class="item" data-id="item-4" onclick="clickNode(this)"><div id="item-4" style="background-color: rgb(0, 255, 115);"></div>4</div><div id="item5" class="item" data-id="item-5"><div id="item-5" style="background-color: rgb(187, 255, 0);"></div>5</div><div id="item6" class="item" data-id="item-6"><div id="item-6" style="background-color: red;"></div>6</div><div id="item7" class="item" data-id="item-7"><div id="item-7" style="background-color: rgb(255, 170, 0);"></div>7</div><div id="item8" class="item" data-id="item-8"><div id="item-8" style="background-color: rgb(0, 157, 255);"></div>8</div><div id="item9" class="item" data-id="item-9"><div id="item-9" style="background-color: rgb(0, 81, 255);"></div>9</div><div id="item10" class="item" data-id="item-10"><div id="item-10" style="background-color: rgb(0, 255, 115);"></div>10</div><div id="item11" class="item" data-id="item-11"><div id="item-11" style="background-color: rgb(187, 255, 0);"></div>11</div></div><script>/*** 椭圆中心点 (x0, y0)* 坐标* x1 = x0 + cos(angle) * rx* y1 = y0 + sin(angle) * ry*/const div = document.querySelectorAll('.item');const amount = div.length;/*** 椭圆中心点坐标* 半径* @type {number}*/const x0 = 600;const y0 = 400;const rx = 400;const ry = 200;// 旋转角度const single = 360 / amount;// 中间显示内容判断let judgeXY = 0;let fontSizeList = [];function init() {for (let i = 0; i < amount; i++) {const ele = div[i];const angle = single * i * Math.PI / 180;const {x, y, sin} = getLocalInfo(i, angle);const fontSize = 22 + sin * 10;fontSizeList.push({i,fontSize});changeDom(ele, sin, angle, x, y, fontSize);}// 判断是否为最前面的元素fontSizeList.sort((a, b) => b.fontSize - a.fontSize);const {i, fontSize} = fontSizeList[0];document.querySelector('#content').innerText = div[i].innerText;judgeXY = fontSize;}function loop() {for (let i = 0; i < amount; i++) {const ele = div[i];const oldAngle = +ele.getAttribute('angle');const angle = single * Math.PI / 180;const newAngle = oldAngle - angle;const {x, y, sin} = getLocalInfo(i, newAngle);const fontSize = 22 + sin * 10;// 处理元素changeDom(ele, sin, newAngle, x, y, fontSize);// 控制显示信息if (fontSize === judgeXY) {document.querySelector('#content').innerText = ele.innerText;}}}/*** 获取坐标和缩放比* */function getLocalInfo(i, angle) {// 调整第一个元素在正下方const rotate = angle + Math.PI / 2;const x = x0 + Math.cos(rotate) * rx - 10;const y = y0 + Math.sin(rotate) * ry - 10;// 近大远小去处理const sin = +Math.sin(rotate).toFixed(3);return {x,y,sin}}/*** 这里应该通过 transform: scale() 来控制元素大小*/function changeDom(ele, sin, newAngle, x, y, fontSize) {const id = ele.dataset.id;// 父元素ele.style.fontSize = `${fontSize}px`;ele.setAttribute('angle', newAngle);ele.style.left = `${x}px`;ele.style.top = `${y}px`;// 子元素const contentDom = document.querySelector(`#${id}`);contentDom.style.width = `${20 + sin * 10}px`;contentDom.style.height = `${20 + sin * 10}px`;contentDom.style.margin = `0 auto`}init();setInterval(loop, 2000);