【问题标题】:CSS concentric circles with orbiting "planets"带有轨道“行星”的 CSS 同心圆
【发布时间】:2020-02-19 03:26:03
【问题描述】:

我正在尝试仅使用 css 渲染“太阳系”图,同心圆很容易使用 css 边界半径、边界和一些变换来完成,但我正在尝试找到一种方法来获得小“行星”遵循“轨道”或彩色边界。必须有更精确的方法来实现这一目标

如果你看这张图片,你会明白我在做什么:

以及它目前的外观,抱歉内联 css...

<div style="width:100%; height:100vh; padding:0px; background-color:white; display:flex; flex-direction:column; position:relative; align-items:flex-end;">
        <div style="width:250px; height:250px; position:absolute; border-radius:50%; background-color:red; top:50%; transform:translateY(-50%) translateX(50%);  right:0px"></div>
        <div style="width:450px; height:450px; position:absolute; border-radius:50%; border:2px solid red; top:50%; transform:translateY(-50%) translateX(50%);  right:0px"></div>
        <div style="width:650px; height:650px; position:absolute; border-radius:50%; border:2px solid red; top:50%; transform:translateY(-50%) translateX(50%);  right:0px"></div>
        <div style="width:850px; height:850px; position:absolute; border-radius:50%; border:2px solid red; top:50%; transform:translateY(-50%) translateX(50%);  right:0px"></div>
        <div style="position:absolute; height:70%; width:100px; top:50%; transform:translateY(-50%); right:15%; outline:1px solid red;">
            <div style="width:25px; height:25px; border-radius:50%; border:1px solid red; position:absolute; top:0px; left:0px;"></div>
            <div style="width:25px; height:25px; border-radius:50%; border:1px solid red; position:absolute; transform:translateY(-50%); top:50%; right:100%;"></div>
            <div style="width:25px; height:25px; border-radius:50%; border:1px solid red; position:absolute; bottom:0px; left:0px;"></div>
        </div>
        <div style="position:absolute; height:80%; width:100px; top:50%; transform:translateY(-50%); right:55%; outline:1px solid red;">
            <div style="width:50px; height:50px; border-radius:50%; border:1px solid red; position:absolute; top:0px; left:0px;"></div>
            <div style="width:50px; height:50px; border-radius:50%; border:1px solid red; position:absolute; transform:translateY(-50%); top:50%; right:100%;"></div>
            <div style="width:50px; height:50px; border-radius:50%; border:1px solid red; position:absolute; bottom:0px; left:0px;"></div>
        </div>
    </div>

【问题讨论】:

  • 如果你的轨道行星的半径是r,轨道圆的直径是d,做一个宽高等于(d + r/2)的盒子。将你的星球放在盒子里 x: 50%, y: 0,然后旋转外盒子。该框应位于圆圈的中心。
  • 跟进我上一条评论的小提琴示例:jsfiddle.net/tyLg48sx

标签: javascript css vue.js


【解决方案1】:

因为它是关于圆的,所以您可以依靠旋转,您只需要知道到中心的距离(半径)。您还可以通过使用更少的元素来优化同心圆。

这是一个示例,我将使用 CSS 变量轻松控制每个元素。请注意the order of transformation is important(我们使用平移居中,旋转,然后再次平移)

.orbit{
  width:150px;
  height:150px;
  padding:30px;
  border-radius:50%;
  background:red content-box;
  border:1px solid red; /*1st orbit at 105px (30px + 150px/2) */
  margin:auto;
  position:relative;
}
/* 2nd at 135px  */
.orbit:before,
.orbit:after{
   content:"";
   position:absolute;
   top: var(--o,-30px);
   bottom: var(--o,-30px);
   left: var(--o,-30px);
   right: var(--o,-30px);
   border:inherit;
   border-radius:inherit
}
/* 3rd orbit at 165px*/
.orbit:after {
  --o:-60px;
}
.orbit span {
  position:absolute;
  z-index:1;
  height:20px;
  width:20px;
  background:blue;
  border-radius:inherit;
  top:50%;
  left:50%;
  transform:translate(-50%,-50%) rotate(var(--r,0deg)) translateX(var(--d,0px));
}
body {
  margin:0;
  height:100vh;
  display:flex;
}
<div class="orbit">
    <span style="--d:105px;--r:80deg"></span>
    <span style="--d:105px;--r:120deg"></span>
    <span style="--d:105px;--r:-80deg"></span>
    <span style="--d:135px;--r:80deg;height:30px;width:30px;background:green"></span>
    <span style="--d:135px;--r:-90deg;height:30px;width:30px;background:green"></span>
    <span style="--d:165px;--r:-45deg"></span>
    <span style="--d:165px;--r:200deg;height:50px;width:50px;background:purple"></span>
</div>

另一个没有透明度的更优化的代码:

.orbit{
  width:150px;
  height:150px;
  padding:30px;
  border-radius:50%;
  background:red content-box;
  border:1px solid red;
  box-shadow:
    0 0 0 29px #fff,
    0 0 0 30px red,
    0 0 0 59px #fff,
    0 0 0 60px red;
  margin:auto;
  position:relative;
}

.orbit span {
  position:absolute;
  height:20px;
  width:20px;
  background:blue;
  border-radius:inherit;
  top:50%;
  left:50%;
  transform:translate(-50%,-50%) rotate(var(--r,0deg)) translateX(var(--d,0px));
}
body {
  margin:0;
  height:100vh;
  display:flex;
}
<div class="orbit">
    <span style="--d:105px;--r:80deg"></span>
    <span style="--d:105px;--r:120deg"></span>
    <span style="--d:105px;--r:-80deg"></span>
    <span style="--d:135px;--r:80deg;height:30px;width:30px;background:green"></span>
    <span style="--d:135px;--r:-90deg;height:30px;width:30px;background:green"></span>
    <span style="--d:165px;--r:-45deg"></span>
    <span style="--d:165px;--r:200deg;height:50px;width:50px;background:purple"></span>
</div>

【讨论】:

    【解决方案2】:

    您也可以从阴影中绘制圆,并从另一侧旋转元素,因此您只需要注意它的宽度:

    示例:

    html {
      display: flex;
      min-height: 100vh;
    }
    body {
      margin: auto;
    }
    ul,
    li,
    span {
      margin: 0;
      padding: 0;
    }
    li {
      position: absolute;
      color: gray;
      list-style-position: inside;
      font-size: 2.5vw;
      top: 0.2em;
      right:0.0em;
      line-height: 0;
      height:0;
      white-space: nowrap;
      transform-origin: center right;
      margin: -0.4vw 0;
    }
    span {
      position: absolute;
      color: black;
      transform: translate(-70%, 1.5em) rotate(0);
      font-size: 0.5em;
      color: tomato;
    }
    
    body {
      position: relative;
      width:0.4em;
      height:0.4em;
      border-radius: 50%;
      background:orange;
      box-shadow: 
      inset 0 0 0 5px orange,
        0 0 0 3vw     orange, 
        0 0 1vw 3vw   orange, 
        0 0 0 3vw     #333,
        0 0 0 6vw     #444, 
        0 0 0 6vw     blue, 
        0 0 0 6.2vw   blue,
        
        0 0 0 6.2vw   #333,
        0 0 0 7.5vw   #333, 
        0 0 0 7.5vw   blue, 
        0 0 0 7.7vw   blue, 
        
        0 0 0 7.75vw  #333,
        0 0 0 8.7vw   #222, 
        0 0 0 9.5vw   #222, 
        0 0 0 9.55vw  green, 
        0 0 0 9.7vw   green,
        
        0 0 0 9.75vw  #222, 
        0 0 0 11.5vw  #111,
        0 0 0 11.5vw  blue,
        0 0 0 11.7vw  blue,
        
        0 0 0 11.75vw  #222, 
        0 0 0 15.2vw  #111,
        0 0 0 15.2vw  blue,
        0 0 0 15.4vw  blue,
        
        0 0 0 15.45vw #222, 
        0 0 0 17.4vw  #111,
        0 0 0 17.4vw  blue,
        0 0 0 17.6vw  blue,
        
        0 0 0 17.65vw #222, 
        0 0 0 19.3vw  #111,
        0 0 0 19.3vw  blue,
        0 0 0 19.5vw  blue,
        
        0 0 0 19.55vw #222, 
        0 0 0 22.3vw  #111,
        0 0 0 22.3vw  blue,
        0 0 0 22.5vw  blue,
        
        0 0 0 100vw ;
    }
    li:nth-child(1) {
      width: 6.9vw;
      animation: rotate 1s -1s linear infinite ;
    }
    li:nth-child(1) span {
      animation: rotateName 1s -1s linear infinite ;
    }
    li:nth-child(2) {
      color:brown;
      width: 8.4vw;
      animation: rotate 1.5s -1.5s linear infinite ;
    }
    li:nth-child(2) span {
      animation: rotateName  1.5s -1.5s  linear infinite ;
    }
    
    li:nth-child(3) {
      color:rgb(0, 120, 212);
      width: 10.6vw;
      animation: rotate 2s 1s linear infinite ;
    }
    li:nth-child(3) span {
      animation: rotateName 2s  1s linear infinite ;
    }
    
    li:nth-child(4) {
      color:red;
      width: 12.5vw;
      animation: rotate 2.5s -2.5s linear infinite ;
    }
    li:nth-child(4) span {
      animation: rotateName  2.5s -2.5s  linear infinite ;
    }
    li:nth-child(5) {
      color:gold;
      width: 15.5vw;
      animation: rotate 3s -3s linear infinite ;
    }
    li:nth-child(5) span {
      animation: rotateName  3s -3s  linear infinite ;
    }
    li:nth-child(6) {
      color:turquoise;
      width: 17.5vw;
      animation: rotate 3.5s -3.5s linear infinite ;
    }
    li:nth-child(6) span {
      animation: rotateName  3.5s -3.5s  linear infinite ;
    }
    li:nth-child(7) {
      color:darkgreen;
      width: 19.5vw;
      animation: rotate 4s -4s linear infinite ;
    }
    li:nth-child(7) span {
      animation: rotateName  4s -4s  linear infinite ;
    }
    li:nth-child(8) {
      color:cyan;
      width: 22.5vw;
      animation: rotate 4.5s -4.5s linear infinite ;
    }
    li:nth-child(8) span {
      animation: rotateName  4.5s -4.5s  linear infinite ;
    }
    
    body:before {
      content:'SUN';
      position:absolute;
      font-size:1.5vw;
      transform:translate(-50%,-0.5em);
      color:red;text-shadow: 0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold,0 0 0.2em gold ;
    }
    
     
    @keyframes rotate {
      100% {transform:rotate(360deg)}
    }
    @keyframes rotateName {
       100%{transform: translate(-70%, 1.5em) rotate(-360deg)}
    }
    <ul>
      <li><span>Mercury</span></li>
      <li><span>Venus</span></li>
      <li><span>Earth</span></li>
      <li><span>Mars</span></li>
      <li><span>Jupiter</span></li>
      <li><span>Saturne</span></li>
      <li><span>Uranus</span></li>
      <li><span>Neptune</span></li>
    </ul>

    受How to set an animation to have elements moving around a circle? 的启发,第三个 sn-p 直观地展示了它的工作原理。

    【讨论】:

      猜你喜欢
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-04
      • 1970-01-01
      相关资源
      最近更新 更多