背景

周末在家习惯性登陆 Apex,准备玩几盘。在登陆加速器的过程中,发现加速器到期了。

我一直用的腾讯网游加速器,然而点击充值按钮,提示最近客户端升级改造,暂不支持充值(这个操作把我震惊了~)。只能转头下载网易 UU 加速器

打开 UU 加速器首页,映入眼帘的是这样一幅画面:

瞬间,被它这个背景图吸引。

出于对 CSS 的敏感,盲猜了一波这个用 CSS 实现的,至少也应该是 Canvas。打开控制台,稍微有点点失望,居然是一个 .mp4文件:

再看看 Network 面板,这个 .mp4 文件居然需要 3.5M?

emm,瞬间不想打游戏了。这么个背景图,CSS 不能搞定么

使用 CSS 3D 实现星际 3D 穿梭效果

这个技巧,我在 奇思妙想 CSS 3D 动画 | 仅使用 CSS 能制作出多惊艳的动画? 也有提及过,感兴趣的可以一并看看。

假设我们有这样一张图形:

这张图先放着备用。在使用这张图之前,我们会先绘制这样一个图形:

<div class="g-container">
<div class="g-group">
<div class="item item-right"></div>
<div class="item item-left"></div>
<div class="item item-top"></div>
<div class="item item-bottom"></div>
<div class="item item-middle"></div>
</div>
</div>
body {
background: #000;
}
.g-container {
position: relative;
}
.g-group {
position: absolute;
width: 100px;
height: 100px;
left: -50px;
top: -50px;
transform-style: preserve-3d;
}
.item {
position: absolute;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, .5);
}
.item-right {
background: red;
transform: rotateY(90deg) translateZ(50px);
}
.item-left {
background: green;
transform: rotateY(-90deg) translateZ(50px);
}
.item-top {
background: blue;
transform: rotateX(90deg) translateZ(50px);
}
.item-bottom {
background: deeppink;
transform: rotateX(-90deg) translateZ(50px);
}
.item-middle {
background: rgba(255, 255, 255, 0.5);
transform: rotateX(180deg) translateZ(50px);
}

一共设置了 5 个子元素,不过仔细看 CSS 代码,其中 4 个子元素都设置了 rotateX/Y(90deg/-90deg),也就是绕 X 轴或者 Y 轴旋转了 90°,在视觉上是垂直屏幕的一张平面,所以直观视觉上我们是不到的,只能看到一个平面 .item-middle

我将 5 个子 item 设置了不同的背景色,结果如下:

现在看来,好像平平无奇,确实也是。

不过,见证奇迹的时候来了,此时,我们给父元素 .g-container 设置一个极小的 perspective,譬如,设置一个 perspective: 4px,看看效果:

.g-container {
position: relative;
+ perspective: 4px;
}
// ...其余样式保持不变

此时,画风骤变,整个效果就变成了这样:

由于 perspective 生效,原本的平面效果变成了 3D 的效果。接下来,我们使用上面准备好的星空图,替换一下上面的背景颜色,全部都换成同一张图,神奇的事情发生了:

由于设置的 perspective 非常之下,而每个 item 的 transform: translateZ(50px) 设置的又比较大,所以图片在视觉上被拉伸的非常厉害。但是整体是充满整个屏幕的。

接下来,我们只需要让视角动起来,给父元素增加一个动画,通过控制父元素的 translateZ() 进行变化即可:

.g-container{
position: relative;
perspective: 4px;
perspective-origin: 50% 50%;
} .g-group{
position: absolute;
// ... 一些定位高宽代码
transform-style: preserve-3d;
+ animation: move 8s infinite linear;
} @keyframes move {
0%{
transform: translateZ(-50px) rotate(0deg);
}
100%{
transform: translateZ(50px) rotate(0deg);
}
}

看看,神奇美妙的星空穿梭的效果就出来了,Amazing:

美中不足之处在于,动画没能无限衔接上,开头和结尾都有很大的问题。

当然,这难不倒我们,我们可以:

  1. 通过叠加两组同样的效果,一组比另一组通过负的 animation-delay 提前行进,使两组动画衔接起来(一组结束的时候另外一组还在行进中)
  2. 再通过透明度的变化,隐藏掉 item-middle 迎面飞来的突兀感
  3. 最后,可以通过父元素的滤镜 hue-rotate 控制图片的颜色变化

我们尝试修改 HTML 结构如下:

<div class="g-container">
<div class="g-group">
<div class="item item-right"></div>
<div class="item item-left"></div>
<div class="item item-top"></div>
<div class="item item-bottom"></div>
<div class="item item-middle"></div>
</div>
<!-- 增加一组动画 -->
<div class="g-group">
<div class="item item-right"></div>
<div class="item item-left"></div>
<div class="item item-top"></div>
<div class="item item-bottom"></div>
<div class="item item-middle"></div>
</div>
</div>

修改后的核心 CSS 如下:

.g-container{
perspective: 4px;
position: relative;
// hue-rotate 变化动画,可以让图片颜色一直变换
animation: hueRotate 21s infinite linear;
} .g-group{
transform-style: preserve-3d;
animation: move 12s infinite linear;
}
// 设置负的 animation-delay,让第二组动画提前进行
.g-group:nth-child(2){
animation: move 12s infinite linear;
animation-delay: -6s;
}
.item {
background: url(https://z3.ax1x.com/2021/08/20/fLwuMd.jpg);
background-size: cover;
opacity: 1;
// 子元素的透明度变化,减少动画衔接时候的突兀感
animation: fade 12s infinite linear;
animation-delay: 0;
}
.g-group:nth-child(2) .item {
animation-delay: -6s;
}
@keyframes move {
0%{
transform: translateZ(-500px) rotate(0deg);
}
100%{
transform: translateZ(500px) rotate(0deg);
}
}
@keyframes fade {
0%{
opacity: 0;
}
25%,
60%{
opacity: 1;
}
100%{
opacity: 0;
}
}
@keyframes hueRotate {
0% {
filter: hue-rotate(0);
}
100% {
filter: hue-rotate(360deg);
}
}

最终完整的效果如下,星空穿梭的效果,整个动画首尾相连,可以一直无限下去,几乎没有破绽,非常的赞:

上述的完整代码,你可以猛击这里:CSS 灵感 -- 3D 宇宙时空穿梭效果

这样,我们就基本还原了上述见到的网易 UU 加速器首页的动图背景。

更进一步,一个图片我都不想用

当然,这里还是会有读者吐槽,你这里不也用了一张图片资源么?没有那张星空图行不行?这张图我也懒得去找。

当然可以,CSS YYDS。这里我们尝试使用 box-shadow,去替换实际的星空图,也是在一个 div 标签内实现,借助了 SASS 的循环函数:

<div></div>
@function randomNum($max, $min: 0, $u: 1) {
@return ($min + random($max)) * $u;
} @function randomColor() {
@return rgb(randomNum(255), randomNum(255), randomNum(255));
} @function shadowSet($maxWidth, $maxHeight, $count) {
$shadow : 0 0 0 0 randomColor(); @for $i from 0 through $count {
$x: #{random(10000) / 10000 * $maxWidth};
$y: #{random(10000) / 10000 * $maxHeight}; $shadow: $shadow, #{$x} #{$y} 0 #{random(5)}px randomColor();
} @return $shadow;
} body {
background: #000;
} div {
width: 1px;
height: 1px;
border-radius: 50%;
box-shadow: shadowSet(100vw, 100vh, 500);
}

这里,我们用 SASS 封装了一个函数,利用多重 box-shadow 的特性,在传入的大小的高宽内,生成传入个数的点。

这样,我们可以得到这样一幅图,用于替换实际的星空图:

我们再把上述这个图,替换实际的星空图,主要是替换 .item 这个 class,只列出修改的部分:

// 原 CSS,使用了一张星空图
.item {
position: absolute;
width: 100%;
height: 100%;
background: url(https://z3.ax1x.com/2021/08/20/fLwuMd.jpg);
background-size: cover;
animation: fade 12s infinite linear;
} // 修改后的 CSS 代码
.item {
position: absolute;
width: 100%;
height: 100%;
background: #000;
animation: fade 12s infinite linear;
}
.item::after {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 1px;
height: 1px;
border-radius: 50%;
box-shadow: shadowSet(100vw, 100vh, 500);
}

这样,我们就实现了这样一个效果,在不借助额外资源的情况下,使用纯 CSS 实现上述效果:

CodePen Demo -- Pure CSS Galaxy Shuttle 2

通过调整动画的时间,perspective 的值,每组元素的 translateZ() 变化距离,可以得到各种不一样的观感和效果,感兴趣的读者可以基于我上述给的 DEMO 自己尝试尝试。

最后

好了,本文到此结束,希望本文对你有所帮助

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

3D 穿梭效果?使用 CSS 轻松搞定的更多相关文章

  1. CSS 轻松搞定标签(元素)居中问题

    在CSS里,标签位置居中一直是困扰Web前端的难题.在本文中,我对这类问题进行了探究和给出了几点建议,供读者参考. 1 行内标签 1.1 水平居中 在父级标签中使用 text-align: cente ...

  2. 3D 穿梭效果?使用 UWP 也能搞定

    昨天 ChokCoco 大佬搞了个 3D 穿梭效果出来,具体可见这里: 3D 穿梭效果?使用 CSS 轻松搞定 这个效果太神奇了,他还问我能不能用 WPF 搞出来,因为我完全没用过 WPF 的 3D, ...

  3. Webcast / 技术小视频制作方法——自己动手录制video轻松搞定

    Webcast / 技术小视频制作方法——自己动手录制video轻松搞定 http://blog.sina.com.cn/s/blog_67d387490100wdnh.html 最近申请加入MSP的 ...

  4. 【微服务】之四:轻松搞定SpringCloud微服务-负载均衡Ribbon

    对于任何一个高可用高负载的系统来说,负载均衡是一个必不可少的名称.在大型分布式计算体系中,某个服务在单例的情况下,很难应对各种突发情况.因此,负载均衡是为了让系统在性能出现瓶颈或者其中一些出现状态下可 ...

  5. 【微服务】之五:轻松搞定SpringCloud微服务-调用远程组件Feign

    上一篇文章讲到了负载均衡在Spring Cloud体系中的体现,其实Spring Cloud是提供了多种客户端调用的组件,各个微服务都是以HTTP接口的形式暴露自身服务的,因此在调用远程服务时就必须使 ...

  6. 几行c#代码,轻松搞定一个女大学生

    几行c#代码,轻松搞定一个女大学生 的作业... 哈哈,标题党了哈,但是是真的,在外面敲代码,想赚点外快,接到了一个学生的期末考试,是一个天气预报的程序.程序并不难. 看到这个需求第一个想法就是只要找 ...

  7. Python高级特性: 12步轻松搞定Python装饰器

    12步轻松搞定Python装饰器 通过 Python 装饰器实现DRY(不重复代码)原则:  http://python.jobbole.com/84151/   基本上一开始很难搞定python的装 ...

  8. 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体解释

    转载请注明来源: http://blog.csdn.net/kjunchen/article/details/50909410 使用BleLib的轻松搞定Android低功耗蓝牙Ble 4.0开发具体 ...

  9. 盘它!基于CANN的辅助驾驶AI实战案例,轻松搞定车辆检测和车距计算!

    摘要:基于昇腾AI异构计算架构CANN(Compute Architecture for Neural Networks)的简易版辅助驾驶AI应用,具备车辆检测.车距计算等基本功能,作为辅助驾驶入门级 ...

随机推荐

  1. P5782-[POI2001]和平委员会【2-SAT】

    正题 题目链接:https://www.luogu.com.cn/problem/P5782 题目大意 \(n\)对人,每对之间恰好有一个人出席.\(m\)对仇恨关系表示两个人不能同时出席. 求是否有 ...

  2. 卧槽,redis分布式如果用不好,坑真多

    前言 在分布式系统中,由于redis分布式锁相对于更简单和高效,成为了分布式锁的首先,被我们用到了很多实际业务场景当中. 但不是说用了redis分布式锁,就可以高枕无忧了,如果没有用好或者用对,也会引 ...

  3. Phalcon多模块如何实现连接不同数据库 《Phalcon入坑指南系列 五》

    本系列目录 一.Phalcon在Windows上安装 <Phalcon入坑指南系列 一> 二.Phalcon入坑必须知道的功能<Phalcon入坑指南系列 二> 三.Phalc ...

  4. AI 事件驱动场景 Serverless 实践

    作者 | 李鹏(元毅) 来源 | Serverless 公众号 一.事件驱动框架:Knative Eventing 事件驱动是指事件在持续事务管理过程中,进行决策的一种策略.可以通过调动可用资源执行相 ...

  5. Serverless 在 SaaS 领域的最佳实践

    作者 | 计缘 来源 | Serverless 公众号 随着互联网人口红利逐渐减弱,基于流量的增长已经放缓,互联网行业迫切需要找到一片足以承载自身持续增长的新蓝海,产业互联网正是这一宏大背景下的新趋势 ...

  6. 痞子衡嵌入式:i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT全系列下FlexSPI外设AHB Master ID定义与AHB RX Buffer指定的异同. 因为 i.MXRT 全系列 ...

  7. Vulnhub实战-DockHole_1靶机👻

    Vulnhub实战-DockHole_1靶机 靶机地址:https://www.vulnhub.com/entry/darkhole-1,724/ 1.描述 我们下载下来这个靶机然后在vmware中打 ...

  8. 2021.3.10--vj补题

    B - Saving the City cf--1443B Bertown is a city with nn buildings in a straight line. The city's sec ...

  9. 消息队列那么多,为什么建议深入了解下RabbitMQ?

    你为啥要在项目中选择xxx消息中间件? 提起消息队列,也许你的脑海里会不自觉地蹦出好多概念:JMS.Kafka.RocketMQ.AMQP.RabbitMQ.ActiveMQ.Pulsar.Redis ...

  10. HCNP Routing&Switching之BGP报文结构、类型和状态

    前文我们了解了BGP的邻居建立条件.优化以及BGP认证相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15395723.html:今天我们来聊一聊BGP ...