在半圆周围移动元素-围绕父元素的轨道div



我试图让这些球沿着父div的边界移动。父div是一个药丸/disrectangle。我相信一定有办法用三角函数或者圆的方程来做这个。所以直边是200px长,每个半圆的半径是100px。所以从0-100px到300-400px,需要计算每个球的顶部样式。有人做过类似的事情或者有什么建议吗?

HTML:

<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<button id="start_stop">Orbit</button>
<div id="oval">
<div id="ball0" class="ball"></div>
<div id="ball1" class="ball"></div>
<div id="ball2" class="ball"></div>
<div id="ball3" class="ball"></div>
</div>
<script src="orbit.js"></script>
</html>

CSS:

#oval {
position: absolute;
margin-top: 200px;
height: 200px;
width: 400px;
border: 3px solid black;
border-radius: 400px/400px;
right: 50%;
transform: translate(50%, -50%);
}

.ball {
height: 30px;
width: 30px;
border-radius: 30px;
position: absolute;
}
#ball0 {
left:270px;
top:185px;
/*right: 100px;
bottom: -15;*/
background-color: blue;
}
#ball1 {
left:100px;
/* bottom:-15px; */
top: 185px;
background-color: green;
}
#ball2 {
top:-15px;
/* right: 100px; */
left: 270px;
background-color: yellow;
}
#ball3 {
top:-15px;
left: 100px;
background-color: red;
}

JS:

var oval = document.getElementById('oval');
var balls = document.getElementsByClassName('ball');
var run_animation = false;
var req;
document.getElementById("start_stop").addEventListener("click", toggle);
function toggle() {
run_animation = !run_animation
if(run_animation) {
req = window.requestAnimationFrame(orbit);
}
}
console.log(balls.length);
var max_x = oval.clientWidth; // - 100;
var min_x = 0;
var step = 0;
var map = {
"ball0": {"top": 185, "left": 270, forward: true},
"ball1": {"top": 185, "left": 100, forward: true},
"ball2": {"top": -15, "left": 270, forward: false},
"ball3": {"top": -15, "left": 100, forward: false}
}
function get_y(x){
//some math here?
// return 100 * Math.sin(x);
// return Math.sqrt(100**2 + x**2);
}
function orbit() {
if (run_animation){
for(var i=0; i<balls.length; i++){
var curr_left = map["ball"+i].left;
if (curr_left >= max_x) map["ball"+i].forward = false;
if (curr_left <= min_x ) map["ball"+i].forward = true;
if(map["ball"+i].forward){
map["ball"+i].left += 3;
}
else {
forward = false
map["ball"+i].left -= 3;
}
//left edge - curve around semicircle
if(map["ball"+i].left <= 100) {
// map["ball"+i].top = -1 * get_y(map["ball"+i].left);
}
//right edge - curve around semicircle
if(map["ball"+i].left >= 300) {
// map["ball"+i].top = -1 * get_y(map["ball"+i].left);
}
balls[i].style.left = map["ball"+i].left + 'px';
balls[i].style.top  = map["ball"+i].top + 'px';
}
req = window.requestAnimationFrame(orbit);
}
else {
console.log("cancel");
window.cancelAnimationFrame(req);
}
}
/* orbit(); */
req = window.requestAnimationFrame(orbit);

https://jsfiddle.net/gzjfxtbu/2/

我做到了。我不确定这是不是最好的方法。我还想找出其他方法来完成这个任务。最后,我打算把球变成包含信息和图像的实际div。所以我不确定是否SVG路由是最好的?

希望这能帮助到一些人。

JS:

var oval = document.getElementById('oval');
var balls = document.getElementsByClassName('ball');
var run_animation = false;
var req;
document.getElementById("start_stop").addEventListener("click", toggle);
function toggle() {
run_animation = !run_animation
if(run_animation) {
req = window.requestAnimationFrame(orbit);
}
}
console.log(balls.length);
var max_x = oval.clientWidth;
var min_x = 0;
var step = 0;
var map = {
"ball0": {"top": 185, "left": 270, forward: false},
"ball1": {"top": 185, "left": 100, forward: false},
"ball2": {"top": -15, "left": 270, forward: true},
"ball3": {"top": -15, "left": 100, forward: true}
}
function get_y(x){
//some math here?
// return 100 * Math.sin(x);
return 1 * (Math.sqrt(100**2 - (100-x)**2));
}
function get_y2(x) {
return 1 * (Math.sqrt(100**2 - (300-x)**2));
}
function orbit() {
if (run_animation){
for(var i=0; i<balls.length; i++){
var curr_left = map["ball"+i].left;
if (curr_left >= max_x) map["ball"+i].forward = false;
if (curr_left <= min_x ) map["ball"+i].forward = true;
if(map["ball"+i].forward){
map["ball"+i].left += 3;
}
else {
map["ball"+i].left -= 3;
}
//left edge - curve around semicircle
if(map["ball"+i].left <= 85 && !map["ball"+i].forward ) {
map["ball"+i].top = 1*get_y(map["ball"+i].left) + 85;
}
else if(map["ball"+i].left <= 85 && map["ball"+i].forward ) {
map["ball"+i].top =  -1*get_y(map["ball"+i].left) + 85;
}
//right edge - curve around semicircle
if(map["ball"+i].left >= 315 && map["ball"+i].forward) {
map["ball"+i].top = -1*get_y2(map["ball"+i].left) + 85;
}
else if(map["ball"+i].left >= 315 && !map["ball"+i].forward) {
map["ball"+i].top = get_y2(map["ball"+i].left) + 85;
}
balls[i].style.left = map["ball"+i].left + 'px';
balls[i].style.top  = map["ball"+i].top + 'px';
}
req = window.requestAnimationFrame(orbit);
}
else {
console.log("cancel");
window.cancelAnimationFrame(req);
}
}
/* orbit(); */
req = window.requestAnimationFrame(orbit);

HTML:

<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="style.css">
</head>
<button id="start_stop">Orbit</button>
<div id="oval">
<div id="ball0" class="ball">0</div>
<div id="ball1" class="ball">1</div>
<div id="ball2" class="ball">2</div>
<div id="ball3" class="ball">3</div>
</div>
<script src="orbit.js"></script>
</html>

CSS:

#oval {
position: absolute;
margin-top: 100px;
height: 200px;
width: 400px;
border: 3px solid black;
border-radius: 400px/400px;
right: 50%;
transform: translate(50%, -50%);
}

.ball {
height: 30px;
width: 30px;
border-radius: 30px;
position: absolute;
}
#ball0 {
left:270px;
top:185px;
/*right: 100px;
bottom: -15;*/
background-color: blue;
}
#ball1 {
left:100px;
/* bottom:-15px; */
top: 185px;
background-color: green;
}
#ball2 {
top:-15px;
/* right: 100px; */
left: 270px;
background-color: yellow;
}
#ball3 {
top:-15px;
left: 100px;
background-color: red;
}

https://jsfiddle.net/nwm3r4he/3/

最新更新