圆
公式
(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);