实例详解之怎样使用css实现3D穿梭效果

 3569

本篇文章给大家带来了怎样使用css来实现星际3D穿越效果的问题,希望对大家有帮助。


实例详解之怎样使用css实现3D穿梭效果


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

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

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


实例详解之怎样使用css实现3D穿梭效果


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

  1. <div class="g-container">
  2.   <div class="g-group">
  3.       <div class="item item-right"></div>
  4.       <div class="item item-left"></div>   
  5.       <div class="item item-top"></div>
  6.       <div class="item item-bottom"></div> 
  7.       <div class="item item-middle"></div>    
  8.   </div>
  9. </div>
  1. body {
  2.   background: #000;
  3. }
  4. .g-container {
  5.   position: relative;
  6. }
  7. .g-group {
  8.   position: absolute;
  9.   width: 100px;
  10.   height: 100px;
  11.   left: -50px;
  12.   top: -50px;
  13.   transform-style: preserve-3d;
  14. }
  15. .item {
  16.   position: absolute;
  17.   width: 100%;
  18.   height: 100%;
  19.   background: rgba(255, 255, 255, .5);
  20. }
  21. .item-right {
  22.   background: red;
  23.   transform: rotateY(90deg) translateZ(50px);
  24. }
  25. .item-left {
  26.   background: green;
  27.   transform: rotateY(-90deg) translateZ(50px);
  28. }
  29. .item-top {
  30.   background: blue;
  31.   transform: rotateX(90deg) translateZ(50px);
  32. }
  33. .item-bottom {
  34.   background: deeppink;
  35.   transform: rotateX(-90deg) translateZ(50px);
  36. }
  37. .item-middle {
  38.   background: rgba(255, 255, 255, 0.5);
  39.   transform: rotateX(180deg) translateZ(50px);
  40. }

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

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


实例详解之怎样使用css实现3D穿梭效果


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

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

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

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


实例详解之怎样使用css实现3D穿梭效果


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


实例详解之怎样使用css实现3D穿梭效果


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

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

  1. .g-container{
  2.   position: relative;
  3.   perspective: 4px;
  4.   perspective-origin: 50% 50%;
  5. }
  6. .g-group{
  7.   position: absolute;
  8.   // ... 一些定位高宽代码
  9.   transform-style: preserve-3d;
  10.   + animation: move 8s infinite linear;
  11. }
  12. @keyframes move {
  13.   0%{
  14.     transform: translateZ(-50px) rotate(0deg);
  15.   }
  16.   100%{
  17.     transform: translateZ(50px) rotate(0deg);
  18.   }
  19. }

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


实例详解之怎样使用css实现3D穿梭效果


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

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

通过叠加两组同样的效果,一组比另一组通过负的 animation-delay 提前行进,使两组动画衔接起来(一组结束的时候另外一组还在行进中)

再通过透明度的变化,隐藏掉 item-middle 迎面飞来的突兀感

最后,可以通过父元素的滤镜 hue-rotate 控制图片的颜色变化

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

  1. <div class="g-container">
  2.   <div class="g-group">
  3.       <div class="item item-right"></div>
  4.       <div class="item item-left"></div>   
  5.       <div class="item item-top"></div>
  6.       <div class="item item-bottom"></div> 
  7.       <div class="item item-middle"></div>    
  8.   </div>
  9.   <!-- 增加一组动画 -->
  10.   <div class="g-group">
  11.       <div class="item item-right"></div>
  12.       <div class="item item-left"></div>   
  13.       <div class="item item-top"></div>
  14.       <div class="item item-bottom"></div>   
  15.       <div class="item item-middle"></div>    
  16.   </div>
  17. </div>

修改后的核心 CSS 如下:

  1. .g-container{
  2.   perspective: 4px;
  3.   position: relative;
  4.   // hue-rotate 变化动画,可以让图片颜色一直变换
  5.   animation: hueRotate 21s infinite linear;
  6. }
  7. .g-group{
  8.   transform-style: preserve-3d;
  9.   animation: move 12s infinite linear;
  10. }
  11. // 设置负的 animation-delay,让第二组动画提前进行
  12. .g-group:nth-child(2){
  13.   animation: move 12s infinite linear;
  14.   animation-delay: -6s;
  15. }
  16. .item {
  17.   background: url(https://z3.ax1x.com/2021/08/20/fLwuMd.jpg);
  18.   background-size: cover;
  19.   opacity: 1;
  20.   // 子元素的透明度变化,减少动画衔接时候的突兀感
  21.   animation: fade 12s infinite linear;
  22.   animation-delay: 0;
  23. }
  24. .g-group:nth-child(2) .item {
  25.   animation-delay: -6s;
  26. }
  27. @keyframes move {
  28.   0%{
  29.     transform: translateZ(-500px) rotate(0deg);
  30.   }
  31.   100%{
  32.     transform: translateZ(500px) rotate(0deg);
  33.   }
  34. }
  35. @keyframes fade {
  36.   0%{
  37.     opacity: 0;
  38.   }
  39.   25%,
  40.   60%{
  41.     opacity: 1;
  42.   }
  43.   100%{
  44.     opacity: 0;
  45.   }
  46. }
  47. @keyframes hueRotate {
  48.   0% {
  49.     filter: hue-rotate(0);
  50.   }
  51.   100% {
  52.     filter: hue-rotate(360deg);
  53.   }
  54. }

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


实例详解之怎样使用css实现3D穿梭效果


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

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


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

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

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

  1. <div></div>
  1. @function randomNum($max, $min: 0, $u: 1) {
  2. @return ($min + random($max)) * $u;
  3. }
  4. @function randomColor() {
  5.     @return rgb(randomNum(255), randomNum(255), randomNum(255));
  6. }
  7. @function shadowSet($maxWidth, $maxHeight, $count) {
  8.     $shadow : 0 0 0 0 randomColor();
  9.     
  10.     @for $i from 0 through $count {         
  11.         $x: #{random(10000) / 10000 * $maxWidth};
  12.         $y: #{random(10000) / 10000 * $maxHeight};
  13.         
  14.         $shadow: $shadow, #{$x} #{$y} 0 #{random(5)}px randomColor();
  15.     }
  16.     
  17.     @return $shadow;
  18. }
  19. body {
  20.     background: #000;
  21. }
  22. div {
  23.     width: 1px;
  24.     height: 1px;
  25.     border-radius: 50%;
  26.     box-shadow: shadowSet(100vw, 100vh, 500);
  27. }

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

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


实例详解之怎样使用css实现3D穿梭效果


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

  1. // 原 CSS,使用了一张星空图
  2. .item {
  3.   position: absolute;
  4.   width: 100%;
  5.   height: 100%;
  6.   background: url(https://z3.ax1x.com/2021/08/20/fLwuMd.jpg);
  7.   background-size: cover;
  8.   animation: fade 12s infinite linear;
  9. }
  10. // 修改后的 CSS 代码
  11. .item {
  12.   position: absolute;
  13.   width: 100%;
  14.   height: 100%;
  15.   background: #000;
  16.   animation: fade 12s infinite linear;
  17. }
  18. .item::after {
  19.   content: "";
  20.   position: absolute;
  21.   top: 0;
  22.   left: 0;
  23.   right: 0;
  24.   bottom: 0;
  25.   width: 1px;
  26.   height: 1px;
  27.   border-radius: 50%;
  28.   box-shadow: shadowSet(100vw, 100vh, 500);
  29. }

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


实例详解之怎样使用css实现3D穿梭效果


CodePen Demo -- Pure CSS Galaxy  Shuttle 2

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

最后

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


作者:chokcoco

链接:https://juejin.cn/post/7028757824695959588

来源:稀土掘金



TAG标签:
本文网址:https://www.zztuku.com/index.php/detail-10902.html
站长图库 - 实例详解之怎样使用css实现3D穿梭效果
申明:本文转载于《掘金》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐