本文默认读者掌握一定的 css 3d 知识,能够绘制初步的 3d 动画效果。当然这里会再简单过一下 css 3d 的基础知识。
要利用 css3 实现 3d 的效果,最主要的就是借助 transform-style
属性。transform-style
只有两个值可以选择:
// 语法:transform-style: flat|prerve-3d; transform-style: flat; // 默认,子元素将不保留其 3d 位置transform-style: prerve-3d; // 子元素将保留其 3d 位置。
当我们指定一个容器的 transform-style 的属性值为 prerve-3d 时,容器的后代元素便会具有 3d 效果,这样说有点抽象,也就是当前父容器设置了 prerve-3d 值后,它的子元素就可以相对于父元素所在的平面,进行 3d 变形操作。
perspective
为一个元素设置三维透视的距离,仅作用于元素的后代,而不是其元素本身。
简单来说,当元素没有设置 perspective
时,也就是当 perspective:none/0
时所有后代元素被压缩在同一个二维平面上,不存在景深的效果。
而如果设置 perspective
后,将会看到三维的效果。
// 语法perspective: number|none;// 语法perspective-origin: x-axis y-axis;// x-axis : 定义该视图在 x 轴上的位置。默认值:50%// y-axis : 定义该视图在 y 轴上的位置。默认值:50%
而 perspective-origin
表示 3d 元素透视视角的基点位置,默认的透视视角中心在容器是 perspective
所在的元素,而不是他的后代元素的中点,也就是 perspective-origin: 50% 50%
。
对于初次接触 css 3d 的同学而言,可以通过绘制正方体快速熟悉语法,了解规则。
而 webpack 的 logo,正是由 2 个 立方体组成:
以其中一个正方体而言,实现它其实非常容易:
1. 一个正方体由 6 个面组成,所以首先设定一个父元素 div,然后这个 div 再包含 6 个子 div,同时,父元素设置transform-style: prerve-3d
;2. 6个子元素,依次首先旋转不同角度,再通过 translatez
位移正方体长度的一半距离即可3. 父元素可以通过 transform
和 perspective
调整视觉角度以一个正方体为例子,简单的伪代码如下:
<ul class="cube-inner"> <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>
.cube { width: 100px; height: 100px; transform-style: prerve-3d; transform-origin: 50px 50px; transform: rotatex(-33.5deg) rotatey(45deg); li { position: absolute; top: 0; left: 0; width: 100px; height: 100px; background: rgba(141, 214, 249); border: 1px solid #fff; } .top { transform: rotatex(90deg) translatez(50px); } .bottom { transform: rotatex(-90deg) translatez(50px); } .front { transform: translatez(50px); } .back { transform: rotatex(-180deg) translatez(50px); } .left { transform: rotatey(-90deg) translatez(50px); } .right { transform: rotatey(90deg) translatez(50px); }}
叠加两个,调整颜色和透明度,我们可以非常轻松的实现 webpack 的 logo:
当然,这里的 logo 为了保证每条线条视觉上的一致性,其实是没有设置景深效果 perspective
的,我们可以尝试给顶层父容器添加一下如下代码,通过 transform
和 perspective
调整视觉角度,设置景深效果:
.father { transform-style: prerve-3d; perspective: 200px; transform: rotatex(10deg);}
就可以得到真正的 3d 效果,感受很不一样:
完整的代码,你可以戳这里:codepen demo — webpack logo
ok,热身完毕,接下来,让我们插上想象的翅膀,走进 css 3d 的世界。
首先,看看一些有意思的 css 3d 文字特效。
要实现文字的 3d 效果,看起来是立体的,通常的方式就是叠加多层。
下面有一些实现一个文字的 3d 效果的方式。
假设我们有如下结构:
<div class="g-container"> <p>lorem ipsum</p></div>
如果什么都不加,文字的展示可能是这样的:
我们可以通过叠加阴影多层,营造 3d 的感觉,主要是合理控制阴影的距离及颜色,核心 css 代码如下:
p { text-shadow: 4px 4px 0 rgba(0, 0, 0, .8), 8px 8px 0 rgba(0, 0, 0, .6), 12px 12px 0 rgba(0, 0, 0, .4), 16px 16px 0 rgba(0, 0, 0, .2), 20px 20px 0 rgba(0, 0, 0, .05);}
这样,就有了基础的 3d 视觉效果。
基于此,我们可以实现一些 3d 文字效果,来看一个 3d 氖灯文字效果,核心就是:
利用 text-shadow
叠加多层文字阴影
利用 animation 动态改变阴影颜色
<div class="container"><p class="a">css 3d</p><p class="b">neon</p><p class="a">effect</p></div>
核心 css 代码:
.container {transform: rotatex(25deg) rotatey(-25deg);}.a {color: #88e;text-shadow: 0 0 0.3em rgba(200, 200, 255, 0.3), 0.04em 0.04em 0 #112,0.045em 0.045em 0 #88e, 0.09em 0.09em 0 #112, 0.095em 0.095em 0 #66c,0.14em 0.14em 0 #112, 0.145em 0.145em 0 #44a;animation: pula 300ms ea infinite alternate;}.b {color: #f99;text-shadow: 0 0 0.3em rgba(255, 100, 200, 0.3), 0.04em 0.04em 0 #112,0.045em 0.045em 0 #f99, 0.09em 0.09em 0 #112, 0.095em 0.095em 0 #b66,0.14em 0.14em 0 #112, 0.145em 0.145em 0 #a44;animation: pulb 300ms ea infinite alternate;}@keyframes pula {// ... 阴影颜色变化}@keyframes pulb {// ... 阴影颜色变化}
可以得到如下效果:
完整的代码,你可以猛击这里 css 灵感 — 使用阴影实现文字的 3d 氖灯效果
当然,上述第一种技巧其实没有运用 css 3d。下面我们使用 css 3d 配合 translatez 再进一步。
假设有如下结构:
<div> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> <h1>glowing 3d text</h1> </div>
我们通过给父元素 div
设置 transform-style: prerve-3d
,给每个 <h1>
设定不同的 translatez()
来达到文字的 3d 效果:
div { transform-style: prerve-3d;}h1:nth-child(2) { transform: translatez(5px);}h1:nth-child(3) { transform: translatez(10px);}h1:nth-child(4) { transform: translat基数词变序数词的口诀ez(15px);}h1:nth-child(5) { transform: translatez(20px);}h1:nth-child(6) { transform: translatez(25px);}h1:nth-child(7) { transform: translatez(30px);}h1:nth-child(8) { transform: translatez(35px);}h1:nth-child(9) { transform: translatez(40px);}h1:nth-child(10) { transform: translatez(45px);}
当然,辅助一些旋转,色彩变化,就可以得到更纯粹一些 3d 文字效果:
完整的代码,你可以猛击这里 css 灵感 — 3d 光影变换文字效果
还有一种很有意思的技巧,制作的过程需要比较多的调试。
合理的利用距离、角度及光影构建出不一样的 3d 效果。看看下面这个例子,只是简单是设置了三层字符,让它们在 z 轴上相距一定的距离。
简单的伪代码如下:
<div> <span class='c'>c</span> <span class='s'>s</span> <span class='s'>s</span> <span></span> <span class='3'>3</span> <span class='d'>d</span></div>
$bright : #afa695;$gold : #867862;$dark : #746853;$duration : 10s;div {perspective: 2000px;transform-style: prerve-3d;animation: fade $duration柳州铁道 infinite;}span {transform-style: prerve-3d;transform: rotatey(25deg);animation: rotate $duration infinite ea-in;&:after, &:before {content: attr(class);color: $gold;z-index: -1;animation: shadow $duration infinite;}&:after{transform: translatez(-16px);}&:before {transform: translatez(-8px);}}@keyframes fade {// 透明度变化}@keyframes rotate {// 字体旋转}@keyframes shadow { // 字体颜色变化}
简单捋一下,上述代码的核心就是:
1.父元素、子元素设置transform-style: prerve-3d
2.用span
元素的两个伪元素复制两个相同的字,利用 translatez()
让它们在 z 轴间隔一定距离3.添加简单的旋转、透明度、字体颜色变化可以得到这样一种类似电影开片的标题 3d 动画,其实只有 3 层元素,但是由于角度恰当,视觉上的衔接比较完美,看上去就非常的 3d。
为什么上面说需要合理的利用距离、角度及光影呢?
还是同一个动画效果,如果动画的初始旋转角度设置的稍微大一点,整个效果就会穿帮:
可以看到,在前几帧,能看出来简单的分层结构。又或者,简单调整一下 perspective
,设置父容器的 perspective
由 2000px
改为 500px
,穿帮效果更为明显:
也就是说,在恰当的距离,合适的角度,我们仅仅通过很少的元素,就能在视觉上形成比较不错的 3d 效果。
上述的完整代码,你可以猛击这里:css 灵感 — 3d 文字出场动画
当然,发挥想象,我们还可以利用 3d 文字效果,制作出非常多有意思的效果。
譬如这个,我之前运用在我们业务的可视化看板项目中的 3d 计数器:
代码比较长,就不贴出来了,但是也是使用纯 css 可以实现的效果。
完整的代码,你可以猛击这里 css 灵感 — 3d 数字计数动画
嗯,上述章节主要是关于文字的 3d 效果,下面我们继续探寻 3d 在营造空间效果上的神奇之处。
优秀的 3d 效果,能让人有一种身临其境的感觉,都说 css 3d 其实作用有限,能做的不多,但是不代表它不能实现酷炫逼真的效果。
要营造逼真的 3d 效果,关键是恰当好处的运用 perspective
属性。
简单掌握原理,我们也可以很轻松的利用 css 3d 绘制一些非常有空间美感的效果。
这里我带领大家快速绘制一副具有空间美感的 css 3d 作品。
首先,我们借助 grid/flex 等布局,在屏幕上布满格子(item),随意点就好:
<ul class="g-container"> <li></li> <li></li> // ... 很多子 li <li></li></ul>
初始背景色为黑色,每个 item 填充为白色
接着,改变下每个 item 的形状,让他变成长条形的,可以改变通过改变 item 宽度,使用渐变填充部分等等方式:
接下来,父容器设置 transform-style: prerve-3d
和 perspective
,子元素设置 transform: rotatex(45deg)
,神奇的事情就发生了:
wow,仅仅 3 步,我们就初步得到了一副具有空间美感的图形,让我们再回到每个子 item 的颜色设置,给它们随机填充不同的颜色,并且加上一个 transform: translate3d()
的动画,一个简单的 css 3d 作品就绘制完成了:
基于这个技巧的变形和延伸,我们就可以绘制非常多类似的效果。
在这里,我再次推荐 css-doodle 这个工具,它可以帮助我们快速的创造复杂 css 效果。
css-doodle 是一个基于 web-component 的库。允许我们快速的创建基于 css grid 布局的页面,以实现各种 css 效果(或许可以称之为 css 艺术)。
我们可以把上述的线条切换成圆弧:
完整的代码可以戳这里,利用 css-doodle 也就几十行:codepen demo – css-doodle random circle
又譬如袁川老师创作的 eding:
当然,基于上述技巧,有的时候会认为利用 css 绘制一些线条、圆弧、方块比较麻烦。可以进一步尝试利用现有的素材基于 css 3d 进行二次创作,这里有一个非常有意思的技巧。
假设我们有这样一张图形:
这张图先放着备用。在使用这张图之前,我们会先绘制这样一个图形:
<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: prerve-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-mi学美发的最佳年龄ddle
。
我将 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: prerve-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: prerve-3d; animation: move 12s infinite linear;}// 设置负的 animation-delay,让第二组动画提前进行.g-group:nth-child(2){ animation: move 12s infinite linear; animation-delay: -6s;}.item { background: url(/d/file/titlepic/imgchr.404.png 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 宇宙时空穿梭效果
ok,当掌握了上述技巧之后,我们可以很容易的对其继续变形发散,实现各种各样的无限延伸的 3d 视角动画。
这里还有一个非常有意思的运用了类似技巧的动画:
原理与上述的星空穿梭大致相同,4 面墙的背景图使用 css 渐变可以很轻松的绘制出来,接下来就只是需要考虑如何让动画能无限循环下去,控制好首尾的衔接。
该效果最早见于 jkantner 的 codepen,在此基础上我对其进行了完善和丰富,完整代码,你可以猛击这里:css 灵感 — 3d 无限延伸视角动画
由于 css 3d 的特性,它天生就非常适合拿来制作一些视差效果。
本章节的内容之前在我的另外一篇文章,也有过一些讨论 — css 实现视差效果
原理就是:
我们给容器设置上transform-style: prerve-3d
和 perspective: [x]px
,那么处于这个容器的子元素就将位于3d空间中,再给子元素设置不同的 transform: translatez()
,这个时候,不同元素在 3d z轴方向距离屏幕(我们的眼睛)的距离也就不一样滚动滚动条,由于子元素设置了不同的 transform: translatez()
,那么他们滚动的上下距离 translatey
相对屏幕(我们的眼睛),也是不一样的,这就达到了滚动视差的效果。核心代码表示就是:
<div class="g-container"> <div class="ction-one">translatez(-1)</div> <div class="ction-two">translatez(-2)</div> <div class="ction-three">translatez(-3)</div></div>
html { height: 100%; overflow: hidden;}body { perspective: 1px; transform-style: prerve-3d; height: 100%; overflow-y: scroll; overflow-x: hidden;}.g-container { height: 150%; .ction-one { transform: translatez(-1px); } .ction-two { transform: translatez(-2px); } .ction-three { transform: translatez(-3px); }}
总结就是父元素设置 transform-style: prerve-3d
和 perspective: 1px
,子元素设置不同的 transform: translatez
,滚动滚动条,效果如下:
codepen demo — css 3d parallax
很明显,当滚动滚动条时,不同子元素的位移程度从视觉上看是不一样的,也就达到了所谓的滚动视差效果。
那么,运用 translate3d 的视差效果,又能有一些什么好玩的效果呢?下面这个滚动视差文字阴影/虚影效果很有意思:
codepen demo — css translate3d parallax
另外一种就是我们可以把这个技巧运用到类似个人主页,图片展示等一些大屏场景下。
核心就是给每张图片设置不同的 translatez
,给父元素设置一个 perpective
即可,这样,在上下滚动的过程中,就能出现简单的视差效果:
codepen demo — css scroll parallax effect
同理,这个滚动视差不仅仅可以作用于上下的滚动,对于左右方向的滚动也是同样生效的:
codepen demo — css-only horizontal parallax gallery by paulina hetman
在这一章节,会介绍一些有趣的,可以落地的 3d 效果或者动画。
在我自己的个人网站的 404 页面,就使用 css 3d 实现的立方体制作的一个 404 效果:
其核心就在于在一个 css 3d 立方体的基础上:
添加立方体的滚动动画
控制下落的缓动函数,及落地的震荡动画(为了效果更为逼真,运用了设计动画中的预备动作、跟随和重叠动画等技巧)
控制立方体及地面数字画面的平移
控制动画的无限循环
整体制作还是非常有难度的,但是用在自己的 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>
我们可以把这个立方体想象成一个立体的进度条容器,通过控制 6 面的颜色,我们可以巧妙的得到一种 3d 进度条效果。
当然,其实我们不需要那么多面,4 个面即可,去掉左右,然后利用渐变修改一下立方体各个面的颜色,去掉 border,核心的 css 代码如下:
.demo-cube { position: relative; .cube { position: absolute; top: 50%; left: 50%; width: 300px; height: 100px; transform-style: prerve-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 进度条效果:
利用 css property 给 3d 进度条加上动画
当然,进度条嘛,它需要一个填充动画。由于我们使用的是渐变实现的进度条的进度,需要去控制其中的颜色百分比变化。
而正常而言,css 是不支持渐变的动画的,不过这也难不倒我们,因为我们可以使用 css @property 。
简单改造一下代码:
@property --per { syntax: '<percentage>'; inherits: fal; 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 自定义属性即可,效果如下:
对于 css @property 不算很了解的,可以看看作者的这篇文章 — css @property,让不可能变可能,它的出现,让 css 极大的提升了制作各种动画的能力。
上述的完整代码,你可以猛击这里:css 灵感 — 3d 立方体进度条
感谢阅读到此,如果认真看完上述内容,相信你一定会惊叹于 css 的神奇。希望本文的内容能够让你:
1.了解 css 3d 的各种用途
2.激发你新的灵感,感受动画之美提
3.升你的 css 动画制作水平
当然,新奇有趣的 css 3d 内容还有很多,我还有非常多个有意思的 demo 没有贴出来,当然对于本文的内容,我觉得已经足够充实,剩下的下次继续分享。
仅使用 css 能制作出多惊艳的动画?我觉得这个问题没有答案,随着 css 语言不断发展,各种新特性的持续加入,虽然某些方面比不上一些更专业的语言,但是它也在便利性、易学性上有着自己的优势。
到此这篇关于利用css制作3d动画的文章就介绍到这了,更多相关css制作3d动画内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!
本文发布于:2023-04-07 20:15:52,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/dc3947b4b833df009e73ad3e36dd8f6e.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:利用CSS制作3D动画.doc
本文 PDF 下载地址:利用CSS制作3D动画.pdf
留言与评论(共有 0 条评论) |