3D 穿梭效果?使用 CSS 轻松搞定

开发 前端
打开 UU 加速器首页,瞬间,被它这个背景图吸引。出于对 CSS 的敏感,盲猜了一波这个是用 CSS 实现的,至少也应该是 Canvas。这么个背景图,CSS 不能搞定么?

[[433718]]

背景

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

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

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

[[433719]]

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

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

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

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

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

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

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

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

<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> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
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); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.

一共设置了 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; 

// ...其余样式保持不变 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

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

由于 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); 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

看看,神奇美妙的星空穿梭的效果就出来了,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> 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

修改后的核心 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); 
  } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.

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

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

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

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

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

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

<div></div> 
  • 1.
@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); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.

这里,我们用 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); 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.

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

CodePen Demo -- Pure CSS Galaxy Shuttle 2[4]

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

最后

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

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

参考资料

[1]网易 UU 加速器:

https://uu.163.com/

[2]奇思妙想 CSS 3D 动画 | 仅使用 CSS 能制作出多惊艳的动画?:

https://github.com/chokcoco/iCSS/issues/132

[3]CSS 灵感 -- 3D 宇宙时空穿梭效果:

https://csscoco.com/inspiration/#/./3d/3d-css-galaxy-shuttle

[4]CodePen Demo -- Pure CSS Galaxy Shuttle 2:

https://codepen.io/Chokcoco/pen/NWvYOqW

 

责任编辑:姜华 来源: iCSS前端趣闻
相关推荐

2021-08-30 06:20:39

CSS 技巧3D 效果

2013-01-30 16:15:40

adobeHTML5css3

2010-06-09 16:21:10

OpenSUSE界面

2010-01-04 15:17:52

Ubuntu启动

2021-09-16 07:52:18

SwiftUScroll效果

2021-06-09 08:30:52

CSS33D旋转视图3D动画

2023-05-26 07:08:05

CSS模糊实现文字

2010-06-09 10:13:40

OpenSUSE 3D

2009-04-03 08:33:59

Symbian诺基亚Photo Brows

2021-01-05 08:10:00

Css前端3D旋转透视

2013-11-18 17:33:48

微软Windows 8.1应用

2012-02-24 09:11:45

jQuery

2012-05-10 10:55:03

CSS

2021-06-18 05:59:37

Css前端CSS 特效

2017-07-11 15:00:04

前端CSS3D视角

2023-09-01 09:30:22

Three.js3D 图形库

2011-09-07 10:00:53

Ubuntu3D

2011-08-15 14:16:12

2010-01-06 10:16:06

Ubuntu 3D

2009-05-13 08:13:37

SUSELinux 10.3Nvidia
点赞
收藏

51CTO技术栈公众号