【发布时间】:2021-12-11 04:34:25
【问题描述】:
我试图让这些球沿着这个父 div 的边界移动。父 div 是药丸/不规则矩形。我确信必须有一种方法可以使用圆的一些三角函数或方程来做到这一点。所以直边长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);
【问题讨论】:
-
我在想我不需要余弦。正弦,我可以像往常一样增加和减少 x 值。只需要弯曲 Y。不过我可能是错的。
-
svg 上的 animateMotion 会是一种有用的方式,而不是必须在 JS 中完成所有数学和动画吗?参见例如developer.mozilla.org/en-US/docs/Web/SVG/Element/animateMotion
-
你知道,你可能是对的。我想知道这是否是最好的方法。我尝试使用键路径,但这变成了一堆来跟踪每个 div。我将研究 svg 替代方案。特别是因为我想让这个响应/可调整大小。
标签: javascript html css animation web-frontend