关于css3:3D-穿梭效果使用-CSS-轻松搞定

34次阅读

共计 5097 个字符,预计需要花费 13 分钟才能阅读完成。

背景

周末在家习惯性登陆 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 本人尝试尝试。

最初

好了,本文到此结束,心愿本文对你有所帮忙 :)

想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 — iCSS 前端趣闻 😄

更多精彩 CSS 技术文章汇总在我的 Github — iCSS,继续更新,欢送点个 star 订阅珍藏。

如果还有什么疑难或者倡议,能够多多交换,原创文章,文笔无限,满腹经纶,文中若有不正之处,万望告知。

正文完
 0