围绕半圆移动元素 - 围绕父级轨道 div

Move elements around semicircle - orbit div around parent

我正在尝试让这些球沿着父级 div 的边界移动。父 div 是 pill/discorectangle。我确信必须有一种方法可以使用一些三角函数或圆的方程来做到这一点。所以直边长 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/