CSS 实现行星环效应
Achieving a planet with rings effect with CSS
我正在尝试制作一个有光环的行星,就像这张照片
我目前正在以一种看起来非常肮脏的方式来做这件事。环(椭圆)是一个 div 没有背景和旋转的黑色边框,我通过在顶部添加另一半红色圆圈来实现环在行星后面的效果。
这是 JSFiddle 下面是一个片段演示。
.elipse {
width: 300px;
height: 105px;
background: none;
border-radius: 50%;
-ms-transform: rotate(40deg); /* IE 9 */
-webkit-transform: rotate(40deg); /* Safari */
transform: rotate(40deg);
position: absolute;
left: 45px;
top: 45px;
border: 5px solid black;
}
.full-planet {
height: 170px;
width: 170px;
border-radius: 170px 170px 170px 170px;
-moz-border-radius: 170px 170px 170px 170px;
-webkit-border-radius: 170px 170px 170px 170px;
position: absolute;
left: 120px;
top: 20px;
background: red;
}
.half-planet {
height: 85px;
width: 170px;
border-radius: 170px 170px 0 0;
-moz-border-radius: 170px 170px 0 0;
-webkit-border-radius: 170px 170px 0 0;
-ms-transform: rotate(40deg); /* IE 9 */
-webkit-transform: rotate(40deg); /* Safari */
transform: rotate(40deg);
position: absolute;
left: 147px;
top: 30px;
background: red;
}
.cont {
padding-left: 100px;
padding-top: 100px;
position: relative;
width: 0;
height: 0;
}
<div class='container'>
<div class="full-planet"></div>
<div class='elipse'></div>
<div class="half-planet"></div>
</div>
调整参数以获得漂亮的对齐非常麻烦。例如,如果我必须更改一个参数,我几乎必须更改所有其他参数以保持一致。有没有办法做到这一点,这样我就不需要根据我的愿景不断调整参数?
我觉得有一种更简洁的方法可以做到这一点。
使用 SVG:
我通常会推荐使用 SVG effects/shapes 因为使用 SVG 绘制圆弧要容易得多。 SVG 元素的 z-index 取决于它们在 DOM 中出现的顺序。所以也更容易控制他们的顺序。 SVG 本质上也是响应式的。
您可以在 this page 中找到有关如何使用 SVG 绘制椭圆弧的更多信息。
svg {
width: 200px;
height: 200px;
margin: 20px;
}
<svg viewBox='0 0 130 130'>
<path d='M0,78 a65,25 0 1 1 102.5,45' stroke='black' stroke-width='2' fill='transparent' transform='rotate(45,100,100)' />
<circle cx='65' cy='65' r='45' fill='red' />
<path d='M0,78 a65,25 0 1 0 102.5,45' stroke='black' stroke-width='2' fill='transparent' transform='rotate(45,100,100)' />
</svg>
使用CSS:
使用 CSS 将很难创建这种效果,您很可能需要额外的元素来产生这种效果。在您的代码中,您在顶部放置了一个额外的半圆以使环的一部分落后,而在我下面的代码片段中,我为环的一部分使用了一个带有较低 z-index
的额外元素。然而,我对几乎所有设置都使用了百分比,因此当一个参数发生变化时,不需要更改很多参数。正如您在代码片段输出中看到的(将鼠标悬停在形状上),它也非常灵敏。
.wrapper {
position: relative;
height: 200px;
width: 200px;
}
.ring { /* produces the front part of the ring */
position: absolute;
height: 100%;
width: 45%;
left: 27.5%; /* half of 100% - width (to position in center) */
border: 2px solid;
border-color: black transparent black black;
border-radius: 50%;
transform: rotate(-45deg);
z-index: 2; /* brings it forward */
}
.ring-behind { /* produces the part that goes behind */
position: absolute;
height: 100%;
width: 45%;
left: 27.5%; /* half of 100% - width (to position in center) */
border: 2px solid;
border-color: transparent black transparent transparent;
border-radius: 50%;
transform: rotate(-45deg);
z-index: -1; /* sends it behind */
}
.planet {
position: absolute;
height: 75%;
width: 75%;
top: 12.5%; /* half of 100% - height (to position in middle) */
left: 12.5%; /* half of 100% - width (to position in center) */
border-radius: 50%;
background: red;
z-index: 1; /* above the back part of the ring but below the front */
}
/* just for demo */
.wrapper {
transition: all 1s;
}
.wrapper:hover {
height: 300px;
width: 300px;
}
<div class='wrapper'>
<div class='ring'></div>
<div class='ring-behind'></div>
<div class='planet'></div>
</div>
总有一天事情会变得更容易...
CSS 解决方案,因为它应该是(一个 div 用于行星,一个用于环,响应式标记等等......但仅适用于 webkit)
.planet {
width: 330px;
height: 330px;
background-color: lightgreen;
border-radius: 50%;
margin: 100px;
position: relative;
perspective: 1000px;
transform-style: preserve-3d;
box-shadow: inset green -20px -20px 70px;
}
.ring {
width: 150%;
height: 150%;
border: solid 10px red;
border-radius: 50%;
top: -25%;
left: -25%;
position: absolute;
transform: rotate3d(0.8, 0.2, 0, 75deg);
box-sizing: border-box;
}
<div class="planet">
<div class="ring"></div>
</div>
我正在尝试制作一个有光环的行星,就像这张照片
我目前正在以一种看起来非常肮脏的方式来做这件事。环(椭圆)是一个 div 没有背景和旋转的黑色边框,我通过在顶部添加另一半红色圆圈来实现环在行星后面的效果。
这是 JSFiddle 下面是一个片段演示。
.elipse {
width: 300px;
height: 105px;
background: none;
border-radius: 50%;
-ms-transform: rotate(40deg); /* IE 9 */
-webkit-transform: rotate(40deg); /* Safari */
transform: rotate(40deg);
position: absolute;
left: 45px;
top: 45px;
border: 5px solid black;
}
.full-planet {
height: 170px;
width: 170px;
border-radius: 170px 170px 170px 170px;
-moz-border-radius: 170px 170px 170px 170px;
-webkit-border-radius: 170px 170px 170px 170px;
position: absolute;
left: 120px;
top: 20px;
background: red;
}
.half-planet {
height: 85px;
width: 170px;
border-radius: 170px 170px 0 0;
-moz-border-radius: 170px 170px 0 0;
-webkit-border-radius: 170px 170px 0 0;
-ms-transform: rotate(40deg); /* IE 9 */
-webkit-transform: rotate(40deg); /* Safari */
transform: rotate(40deg);
position: absolute;
left: 147px;
top: 30px;
background: red;
}
.cont {
padding-left: 100px;
padding-top: 100px;
position: relative;
width: 0;
height: 0;
}
<div class='container'>
<div class="full-planet"></div>
<div class='elipse'></div>
<div class="half-planet"></div>
</div>
调整参数以获得漂亮的对齐非常麻烦。例如,如果我必须更改一个参数,我几乎必须更改所有其他参数以保持一致。有没有办法做到这一点,这样我就不需要根据我的愿景不断调整参数? 我觉得有一种更简洁的方法可以做到这一点。
使用 SVG:
我通常会推荐使用 SVG effects/shapes 因为使用 SVG 绘制圆弧要容易得多。 SVG 元素的 z-index 取决于它们在 DOM 中出现的顺序。所以也更容易控制他们的顺序。 SVG 本质上也是响应式的。
您可以在 this page 中找到有关如何使用 SVG 绘制椭圆弧的更多信息。
svg {
width: 200px;
height: 200px;
margin: 20px;
}
<svg viewBox='0 0 130 130'>
<path d='M0,78 a65,25 0 1 1 102.5,45' stroke='black' stroke-width='2' fill='transparent' transform='rotate(45,100,100)' />
<circle cx='65' cy='65' r='45' fill='red' />
<path d='M0,78 a65,25 0 1 0 102.5,45' stroke='black' stroke-width='2' fill='transparent' transform='rotate(45,100,100)' />
</svg>
使用CSS:
使用 CSS 将很难创建这种效果,您很可能需要额外的元素来产生这种效果。在您的代码中,您在顶部放置了一个额外的半圆以使环的一部分落后,而在我下面的代码片段中,我为环的一部分使用了一个带有较低 z-index
的额外元素。然而,我对几乎所有设置都使用了百分比,因此当一个参数发生变化时,不需要更改很多参数。正如您在代码片段输出中看到的(将鼠标悬停在形状上),它也非常灵敏。
.wrapper {
position: relative;
height: 200px;
width: 200px;
}
.ring { /* produces the front part of the ring */
position: absolute;
height: 100%;
width: 45%;
left: 27.5%; /* half of 100% - width (to position in center) */
border: 2px solid;
border-color: black transparent black black;
border-radius: 50%;
transform: rotate(-45deg);
z-index: 2; /* brings it forward */
}
.ring-behind { /* produces the part that goes behind */
position: absolute;
height: 100%;
width: 45%;
left: 27.5%; /* half of 100% - width (to position in center) */
border: 2px solid;
border-color: transparent black transparent transparent;
border-radius: 50%;
transform: rotate(-45deg);
z-index: -1; /* sends it behind */
}
.planet {
position: absolute;
height: 75%;
width: 75%;
top: 12.5%; /* half of 100% - height (to position in middle) */
left: 12.5%; /* half of 100% - width (to position in center) */
border-radius: 50%;
background: red;
z-index: 1; /* above the back part of the ring but below the front */
}
/* just for demo */
.wrapper {
transition: all 1s;
}
.wrapper:hover {
height: 300px;
width: 300px;
}
<div class='wrapper'>
<div class='ring'></div>
<div class='ring-behind'></div>
<div class='planet'></div>
</div>
总有一天事情会变得更容易...
CSS 解决方案,因为它应该是(一个 div 用于行星,一个用于环,响应式标记等等......但仅适用于 webkit)
.planet {
width: 330px;
height: 330px;
background-color: lightgreen;
border-radius: 50%;
margin: 100px;
position: relative;
perspective: 1000px;
transform-style: preserve-3d;
box-shadow: inset green -20px -20px 70px;
}
.ring {
width: 150%;
height: 150%;
border: solid 10px red;
border-radius: 50%;
top: -25%;
left: -25%;
position: absolute;
transform: rotate3d(0.8, 0.2, 0, 75deg);
box-sizing: border-box;
}
<div class="planet">
<div class="ring"></div>
</div>