视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何用CSS和D3实现宇宙飞船的动态效果
2020-11-27 18:47:48 责编:小采
文档
这篇文章给大家介绍的内容是关于如何用CSS和D3实现宇宙飞船的动态效果,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

效果预览

代码解读

定义 dom,spacecraft 表示飞船,容器中包含 1 个表示尾冀的元素 fins

<div class="spacecraft">
 <div class="fins"></div>
</div>

居中显示:

body {
 margin: 0;
 height: 100vh;
 display: flex;
 align-items: center;
 justify-content: center;
 background: linear-gradient(black, midnightblue);
}

画出飞船的船舱:

.spacecraft {
 width: 7em;
 height: 11em;
 font-size: 16px;
 background: 
 linear-gradient(whitesmoke, darkgray);
 border-radius: 50% / 70% 70% 5% 5%;
}

用伪元素画出飞船尾部的火焰:

.spacecraft::before {
 content: '';
 position: absolute;
 width: 6em;
 height: 2em;
 background-color: #444;
 border-radius: 20%;
 top: 10em;
 left: 0.5em;
 z-index: -1;
}

.spacecraft::after {
 content: '';
 position: absolute;
 box-sizing: border-box;
 width: 4em;
 height: 4em;
 background: gold;
 top: 10em;
 left: 1.5em;
 border-radius: 80% 0 50% 45% / 50% 0 80% 45%;
 transform: rotate(135deg);
 border: 0.5em solid orange;
 z-index: -2;
}

画出飞船两侧的尾冀:

.fins::before,
.fins::after {
 content: '';
 position: absolute;
 width: 2em;
 height: 6em;
 background: linear-gradient(tomato, darkred);
 top: 7em;
}

.fins::before {
 left: -2em;
 border-radius: 3em 0 50% 100%;
}

.fins::after {
 right: -2em;
 border-radius: 0 3em 100% 50%;
}

用径向渐变画出飞船的舷窗:

.spacecraft {
 background: 
 radial-gradient(
 circle at 3.5em 5em,
 transparent 1.5em,
 lightslategray 1.5em, lightslategray 2em,
 transparent 2em
 ),
 radial-gradient(
 circle at 3.3em 5.2em,
 deepskyblue 1.4em,
 transparent 1.6em
 ),
 radial-gradient(
 circle at 3.5em 5em,
 white 1.5em,
 transparent 1.5em
 ),
 linear-gradient(whitesmoke, darkgray);
}

增加飞船火焰喷射的动画效果:

.spacecraft::after {
 animation: flame-spout 0.3s infinite;
}

@keyframes flame-spout {
 0%, 100% {
 filter: opacity(0.1);
 }

 50% {
 filter: opacity(1);
 }
}

接下来画星空。
在 dom 中增加 stars 容器,其中包含表示星星的 4 个子元素:

<div class="stars">
 <span></span>
 <span></span>
 <span></span>
 <span></span>
</div>
<div class="rocket">
 <div class="fins"></div>
</div>

定义星星的样式:

.stars span {
 position: absolute;
 width: 2px;
 height: 8px;
 border-radius: 50%;
 background-color: white;
 top: calc(50% - 7em);
}

用变量使星星分布在水平方向的不同位置:

.stars span {
 left: calc(var(--left) * 1vw);
}

.stars span:nth-child(1) {
 --left: 20;
}

.stars span:nth-child(2) {
 --left: 40;
}

.stars span:nth-child(3) {
 --left: 60;
}

.stars span:nth-child(4) {
 --left: 80;
}

用变量设置星星的尺寸和不透明度,使每颗星星看起来稍有差异:

.stars span {
 width: calc(var(--size) * 1px);
 height: calc(var(--size) * 4px);
 filter: opacity(var(--opacity));
}

.stars span:nth-child(1) {
 --size: 0.8;
 --opacity: 0.5;
}

.stars span:nth-child(2) {
 --size: 1.25;
 --opacity: 0.6;
}

.stars span:nth-child(3) {
 --size: 1.5;
 --opacity: 0.7;
}

.stars span:nth-child(4) {
 --size: 2;
 --opacity: 0.8;
}

定义星星从太空中飘过的动画效果:

.stars span {
 top: -5vh;
 animation: star-move linear infinite;
}

@keyframes star-move {
 to {
 top: 100vh;
 }
}

用变量设置动画的时长和延时时间:

.stars span {
 animation-duration: calc(var(--duration) * 1s);
 animation-delay: calc(var(--delay) * 1s);
}

.stars span:nth-child(1) {
 --duration: 1;
 --delay: -0.05;
}

.stars span:nth-child(2) {
 --duration: 1.5;
 --delay: -0.1;
}

.stars span:nth-child(3) {
 --duration: 2;
 --delay: -0.15;
}

.stars span:nth-child(4) {
 --duration: 2.5;
 --delay: -0.2;
}

隐藏屏幕外的内容:

body {
 overflow: hidden;
}

接下来用 d3 批量处理表示星星的 dom 元素和 css 变量。
引入 d3 库:

<script src="https://d3js.org/d3.v5.min.js"></script>

用 d3 创建表示星星的 dom 元素:

const COUNT_OF_STARS = 4;

d3.select('.stars')
 .selectAll('span')
 .data(d3.range(COUNT_OF_STARS))
 .enter()
 .append('span');

用 d3 为 css 变量 --left, --size, --opacity 赋值,--left 的取值范围是 1 到 100,--size 的取值范围是 1 到 2.5,'--opacity' 的取值范围是 0.5 到 0.8:

d3.select('.stars')
 .selectAll('span')
 .data(d3.range(COUNT_OF_STARS))
 .enter()
 .append('span')
 .style('--left', () => Math.ceil(Math.random() * 100))
 .style('--size', () => Math.random() * 1.5 + 1)
 .style('--opacity', () => Math.random() * 0.3 + 0.5);

用 d3 为 css 变量 --duration--delay 赋值,--duration 的取值范围是 1 到 3,--delay 的取值是依次减少 0.05:

d3.select('.stars')
 .selectAll('span')
 .data(d3.range(COUNT_OF_STARS))
 .enter()
 .append('span')
 .style('--left', () => Math.ceil(Math.random() * 100))
 .style('--size', () => Math.random() * 1.5 + 1)
 .style('--opacity', () => Math.random() * 0.3 + 0.5)
 .style('--duration', () => Math.random() * 2 + 1)
 .style('--delay', (d) => d * -0.05);

刪除掉 html 文件中相关的 dom 声明和 css 文件中的变量声明。

最后,把星星的数量增加到 30 颗:

const COUNT_OF_STARS = 30;

大功告成!

相关文章推荐:

如何使用纯CSS实现一颗土星的效果

如何使用CSS和D3实现无尽六边形空间的效果

下载本文
显示全文
专题