奇思妙想 CSS 3D 动画 | 仅使用 CSS 能制作出多惊艳的动画? (下)

简介: 奇思妙想 CSS 3D 动画 | 仅使用 CSS 能制作出多惊艳的动画? (下)

3D 计数器


当然,发挥想象,我们还可以利用 3D 文字效果,制作出非常多有意思的效果。

譬如这个,我之前运用在我们业务的可视化看板项目中的 3D 计数器:


image.png


代码比较长,就不贴出来了,但是也是使用纯 CSS 可以实现的效果。

完整的代码,你可以猛击这里 CSS 灵感 -- 3D 数字计数动画


空间效果



嗯,上述章节主要是关于文字的 3D 效果,下面我们继续探寻 3D 在营造空间效果上的神奇之处。


优秀的 3D 效果,能让人有一种身临其境的感觉,都说 CSS 3D 其实作用有限,能做的不多,但是不代表它不能实现酷炫逼真的效果。


要营造逼真的 3D 效果,关键是恰当好处的运用 perspective 属性。


简单掌握原理,我们也可以很轻松的利用 CSS 3D 绘制一些非常有空间美感的效果。

这里我带领大家快速绘制一副具有空间美感的 CSS 3D 作品。


空间 3D 效果热身


首先,我们借助 Grid/Flex 等布局,在屏幕上布满格子(item),随意点就好:


<ul class="g-container">
  <li></li>
  <li></li>
  // ... 很多子 li
  <li></li>
</ul>


初始背景色为黑色,每个 item 填充为白色

cf780cde8fc34099be5409fb5e0e96f0_tplv-k3u1fbpfcp-zoom-1.png


接着,改变下每个 item 的形状,让他变成长条形的,可以改变通过改变 item 宽度,使用渐变填充部分等等方式:

0dbee3db707c4aababc3f0af9a33b1df_tplv-k3u1fbpfcp-zoom-1.png


接下来,父容器设置 transform-style: preserve-3d 和 perspective,子元素设置 transform: rotateX(45deg),神奇的事情就发生了:

1effec05c82248aabef76a48cbc80321_tplv-k3u1fbpfcp-zoom-1.png

Wow,仅仅 3 步,我们就初步得到了一副具有空间美感的图形,让我们再回到每个子 item 的颜色设置,给它们随机填充不同的颜色,并且加上一个 transform: translate3d() 的动画,一个简单的 CSS 3D 作品就绘制完成了:

image.png


于这个技巧的变形和延伸,我们就可以绘制非常多类似的效果。

在这里,我再次推荐 CSS-Doodle 这个工具,它可以帮助我们快速的创造复杂 CSS 效果。


CSS-doodle 是一个基于 Web-Component 的库。允许我们快速的创建基于 CSS Grid 布局的页面,以实现各种 CSS 效果(或许可以称之为 CSS 艺术)。


我们可以把上述的线条切换成圆弧:


image.png


完整的代码可以戳这里,利用 CSS-Doodle 也就几十行:CodePen Demo - CSS-Doodle Random Circle

又譬如袁川老师创作的 Seeding:


image.png


利用图片素材


当然,基于上述技巧,有的时候会认为利用 CSS 绘制一些线条、圆弧、方块比较麻烦。可以进一步尝试利用现有的素材基于 CSS 3D 进行二次创作,这里有一个非常有意思的技巧。


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


27bebf3a9aa54ef6ae7622ab6b0be327_tplv-k3u1fbpfcp-zoom-1.png


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


<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 设置了不同的背景色,结果如下:

5137e98d402e433498ef5340a11808dd_tplv-k3u1fbpfcp-zoom-1.png


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


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


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


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


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

130324531-73948c83-aa87-4d4f-87e1-fe2bb055dc74.png

由于设置的 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 宇宙时空穿梭效果


3D 无限延伸视角动画


OK,当掌握了上述技巧之后,我们可以很容易的对其继续变形发散,实现各种各样的无限延伸的 3D 视角动画。


这里还有一个非常有意思的运用了类似技巧的动画:


image.png


原理与上述的星空穿梭大致相同,4 面墙的背景图使用 CSS 渐变可以很轻松的绘制出来,接下来就只是需要考虑如何让动画能无限循环下去,控制好首尾的衔接。

该效果最早见于 jkantner 的 CodePen,在此基础上我对其进行了完善和丰富,完整代码,你可以猛击这里:CSS 灵感 -- 3D 无限延伸视角动画


视差效果


由于 CSS 3D 的特性,它天生就非常适合拿来制作一些视差效果。


本章节的内容之前在我的另外一篇文章,也有过一些讨论 -- CSS 实现视差效果

原理就是:


  1. 我们给容器设置上 transform-style: preserve-3d 和 perspective: [x]px,那么处于这个容器的子元素就将位于3D空间中,
  2. 再给子元素设置不同的 transform: translateZ(),这个时候,不同元素在 3D Z轴方向距离屏幕(我们的眼睛)的距离也就不一样
  3. 滚动滚动条,由于子元素设置了不同的 transform: translateZ(),那么他们滚动的上下距离 translateY 相对屏幕(我们的眼睛),也是不一样的,这就达到了滚动视差的效果。


核心代码表示就是:


<div class="g-container">
    <div class="section-one">translateZ(-1)</div>
    <div class="section-two">translateZ(-2)</div>
    <div class="section-three">translateZ(-3)</div>
</div>
html {
    height: 100%;
    overflow: hidden;
}
body {
    perspective: 1px;
    transform-style: preserve-3d;
    height: 100%;
    overflow-y: scroll;
    overflow-x: hidden;
}
.g-container {
    height: 150%;
    .section-one {
        transform: translateZ(-1px);
    }
    .section-two {
        transform: translateZ(-2px);
    }
    .section-three {
        transform: translateZ(-3px);
    }
}


总结就是父元素设置 transform-style: preserve-3d 和 perspective: 1px,子元素设置不同的 transform: translateZ,滚动滚动条,效果如下:


image.gif


CodePen Demo -- CSS 3D parallax


很明显,当滚动滚动条时,不同子元素的位移程度从视觉上看是不一样的,也就达到了所谓的滚动视差效果。


滚动视差文字阴影/虚影效果/多图展示


那么,运用 translate3d 的视差效果,又能有一些什么好玩的效果呢?下面这个滚动视差文字阴影/虚影效果很有意思:

image.png


CodePen Demo -- CSS translate3d Parallax


另外一种就是我们可以把这个技巧运用到类似个人主页,图片展示等一些大屏场景下。

核心就是给每张图片设置不同的 translateZ,给父元素设置一个 persepective 即可,这样,在上下滚动的过程中,就能出现简单的视差效果:


image.png

CodePen Demo -- CSS Scroll Parallax Effect

同理,这个滚动视差不仅仅可以作用于上下的滚动,对于左右方向的滚动也是同样生效的:

image.png


CodePen Demo -- CSS-Only Horizontal Parallax Gallery By Paulina Hetman


其他实用场景介绍



在这一章节,会介绍一些有趣的,可以落地的 3D 效果或者动画。


404 Rolling Box


在我自己的个人网站的 404 页面,就使用 CSS 3D 实现的立方体制作的一个 404 效果:



image.png


其核心就在于在一个 CSS 3D 立方体的基础上:


  1. 添加立方体的滚动动画
  2. 控制下落的缓动函数,及落地的震荡动画(为了效果更为逼真,运用了设计动画中的预备动作、跟随和重叠动画等技巧)
  3. 控制立方体及地面数字画面的平移
  4. 控制动画的无限循环


整体制作还是非常有难度的,但是用在自己的 404 页面,确实也是非常的酷炫。这个效果,我最早见于 Yusuke Nakaya 大神,完整的代码你可以戳这里:CodePen -- Only CSS: 404 Rolling Box


立方体进度条



嗯,下面这个还是借助了立方体。我们来实现一个立方体进度条~


首先,实现一个立方体,结构如下:


<div class="demo-cube perspective">
  <ul class="cube">
    <li class="top"></li>
    <li class="bottom"></li>
    <li class="front"></li>
    <li class="back"></li>
    <li class="right"></li>
    <li class="left"></li>
  </ul>
</div>


image.png



我们可以把这个立方体想象成一个立体的进度条容器,通过控制 6 面的颜色,我们可以巧妙的得到一种 3D 进度条效果。

当然,其实我们不需要那么多面,4 个面即可,去掉左右,然后利用渐变修改一下立方体各个面的颜色,去掉 border,核心的 CSS 代码如下:


.demo-cube {
  position: relative;
  .cube {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 300px;
    height: 100px;
    transform-style: preserve-3d;
    transform: translate(-50%, -50%) rotateX(-33.5deg);
    li {
      position: absolute;
      width: 300px;
      height: 100px;
      background: linear-gradient(90deg, rgba(156, 39, 176, .3), rgba(255, 34, 109, .8) 70%, rgba(255, 255, 255, .6) 70%, rgba(255, 255, 255, .6));
    }
    .top {
      transform: rotateX(90deg) translateZ(50px);
    }
    .bottom {
      transform: rotateX(-90deg) translateZ(50px);
    }
    .front {
      transform: translateZ(50px);
    }
    .back {
      transform: rotateX(-180deg) translateZ(50px);
    }
  }
}


我们就可以得到一个非常酷炫的 3D 进度条效果:

image.png


利用 CSS Property 给 3D 进度条加上动画


当然,进度条嘛,它需要一个填充动画。由于我们使用的是渐变实现的进度条的进度,需要去控制其中的颜色百分比变化。

而正常而言,CSS 是不支持渐变的动画的,不过这也难不倒我们,因为我们可以使用 CSS @Property 。

简单改造一下代码:


@property --per {
  syntax: '<percentage>';
  inherits: false;
  initial-value: 0%;
}
.demo-cube .cube {
  .top,
  .front,
  .bottom,
  .back {
    background: linear-gradient(90deg, rgba(255, 217, 34, .6), rgba(255, 34, 109, .8) var(--per), rgba(255, 34, 109, .1) var(--per), rgba(255, 34, 109, .1));
    animation: perChange 6s infinite;
  }
}
@keyframes perChange {
  0% {
    --per: 0%;
  }
  90%,
  to {
    --per: 80%;
  }
}


这样,我们就实现了一个会动的 3D 进度条,只需要控制 --per CSS 自定义属性即可,效果如下:

image.png


对于 CSS @Property 不算很了解的,可以看看作者的这篇文章 -- CSS @property,让不可能变可能,它的出现,让 CSS 极大的提升了制作各种动画的能力。


上述的完整代码,你可以猛击这里:CSS 灵感 -- 3D 立方体进度条


总结一下


感谢阅读到此,如果认真看完上述内容,相信你一定会惊叹于 CSS 的神奇。希望本文的内容能够让你:


  • 了解 CSS 3D 的各种用途
  • 激发你新的灵感,感受动画之美
  • 提升你的 CSS 动画制作水平


当然,新奇有趣的 CSS 3D 内容还有很多,我还有非常多个有意思的 DEMO 没有贴出来,当然对于本文的内容,我觉得已经足够充实,剩下的下次继续分享。


仅使用 CSS 能制作出多惊艳的动画?我觉得这个问题没有答案,随着 CSS 语言不断发展,各种新特性的持续加入,虽然某些方面比不上一些更专业的语言,但是它也在便利性、易学性上有着自己的优势。

目录
相关文章
|
2月前
|
机器学习/深度学习 前端开发 JavaScript
|
2月前
|
前端开发 搜索推荐 UED
实现 CSS 动画效果的兼容性
【10月更文挑战第16天】实现 CSS 动画效果的兼容性需要对不同浏览器的特性有深入的了解,并采取适当的策略和方法。通过不断的实践和优化,你可以在各种浏览器上创造出流畅、美观且兼容的动画效果,为用户带来更好的体验。在实际开发中,要密切关注浏览器的发展动态,及时掌握最新的兼容性技巧和解决方案,以确保你的动画设计能够在广泛的用户群体中得到良好的呈现。
109 58
|
20天前
jQuery+CSS3模拟过山车动态的文字动画特效源码
jQuery+CSS3模拟过山车动态的文字动画特效源码实现在全黑的背景下,画面中的文本呈现过山车的轨迹动画上下滚动转圈,且伴随文本颜色渐变效果,非常有意思,欢迎对此特效感兴趣的朋友前来下载参考。
22 1
|
24天前
|
Web App开发 前端开发 JavaScript
如何在不牺牲动画效果的前提下,优化 CSS3 动画的性能?
如何在不牺牲动画效果的前提下,优化 CSS3 动画的性能?
42 1
|
2月前
|
前端开发 JavaScript API
探索 CSS Houdini:轻松构建酷炫的 3D 卡片翻转动画
本文通过构建一个 3D 翻卡动画深入探讨了 CSS Houdini 的强大功能,展示了如何通过 Worklets、自定义属性、Paint API 等扩展 CSS 的能力,实现高度灵活的动画效果。文章首先介绍了 Houdini 的核心概念与 API,并通过构建一个动态星空背景、圆形进度条以及交互式 3D 翻卡动画的实际示例,展示了如何利用 CSS Houdini 赋予网页设计更多创造力。最后,还演示了如何将这种 3D 翻卡效果集成到公司网站中,提升用户体验。CSS Houdini 的创新能力为网页设计带来了前所未有的灵活性,推动了前端开发迈向新的高度。
38 0
探索 CSS Houdini:轻松构建酷炫的 3D 卡片翻转动画
|
3月前
|
JavaScript 前端开发
JS配合CSS3实现动画和拖动小星星小Demo
本文通过代码示例展示了如何使用JavaScript和CSS3实现动画效果和拖动小星星的交互效果,包括文字掉落动画和鼠标拖动产生小星星动画的实现方法。
51 0
JS配合CSS3实现动画和拖动小星星小Demo
|
2月前
|
前端开发
CSS 动画介绍及语法
CSS 动画介绍及语法
30 0
|
4月前
|
前端开发 UED 开发者
有趣的CSS - 文字加载动画效果
这个文本加载动画简单而有趣,可以在网站标题、广告标语或者关键信息的展示上吸引用户的注意力。开发者可以根据需要调整动画的持续时间、步骤数,或者光标颜色等,来适应特定的设计需求。使用这种动态元素,增强网站的互动性和用户体验,同时也为网站增添了一抹活泼的风格。
106 5
|
4月前
|
前端开发 JavaScript 开发者
css过渡与动画
css过渡与动画
43 0