效果GIF
在线效果
代码
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<style>
* {}
body {
background-color: aqua;
}
.wrapper {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.circle {
border-radius: 50%;
}
.inner {
position: relative;
width: 400px;
height: 400px;
}
.small {
width: 40px;
height: 40px;
}
.red {
background-color: red;
}
.white {
background-color: white;
}
/* 参照定位 */
/* .pos-99 {
background-color: black;
position: absolute;
top: 0;
left: 200px;
margin-left: -20px;
z-index: 1;
} */
.pos-1 {
position: absolute;
/* 2019-2月 CSS 宣布支持三角函数 但目前尚未普及到浏览器 */
/* top: calc((cos(30deg) + 1) * 200); */
/* left: calc((sin(30deg) + 1)* 200); */
}
</style>
</head>
<body>
<div class="wrapper">
<div class="inner circle red">
<!--
<div class="circle small white pos-12"></div>
<div class="circle small white pos-1"></div>
<div class="circle small white pos-2"></div>
<div class="circle small white pos-3"></div>
<div class="circle small white pos-4"></div>
<div class="circle small white pos-5"></div>
-->
</div>
</div>
<script>
var n = 10,/* 内部小球的个数 */
during = 3000;/*单个小球单次动画时间*/
var R = parseInt($('.inner.circle').css('width')) / 2;
$(function () {
initcircle();
initPostition();
start();
})
function initcircle() {
$container = $('.inner.circle.red');
for (let i = 0; i < n; i++) {
$container.append($('<div></div>').addClass('circle small white pos-' + i));
}
}
function initPostition() {
$('.circle.small').each((i, t) => {
$t = $(t);
const r = parseInt($t.css('width')) / 2;
$t.css('position', 'absolute');
$t.css('left', (R * (1 + Math.sin(Math.PI / 180 * (i * (180 / n))))) -
(r * (1 + Math.sin(Math.PI / 180 * (i * (180 / n))))) + 'px');
$t.css('top', (R * (1 - Math.cos(Math.PI / 180 * (i * (180 / n))))) -
(r * (1 - Math.cos(Math.PI / 180 * (i * (180 / n))))) + 'px');
// 为了方便实现动画 直接计算 left 和 top
//$t.css('margin-left', -r * (1 + Math.sin(Math.PI / 180 * (i * (180 / n)))) + 'px');
//$t.css('margin-top', -r * (1 - Math.cos(Math.PI / 180 * (i * (180 / n)))) + 'px');
})
}
function move(i, t) {
const $t = $(t);
const r = parseInt($t.css('width')) / 2;
var left = (R * (1 + Math.sin(Math.PI / 180 * (i * (180 / n))))) -
(r * (1 + Math.sin(Math.PI / 180 * (i * (180 / n)))));
var top = (R * (1 - Math.cos(Math.PI / 180 * (i * (180 / n))))) -
(r * (1 - Math.cos(Math.PI / 180 * (i * (180 / n)))));
$t.animate({
'left': left,
'top': top,
},
during,
'swing',
() => {
move((i < n) ? (i + n) : (i - n), t);
}
)
}
function start() {
$('.circle.small').each((i, t) => {
setTimeout(() => {
move(i + n, t);
}, (during / n) * i);
})
}
</script>
</body>
</html>