CSS动画爱好者经常会用到透视(perspective)这个强大的工具。虽然透视属性本身无法实现3D效果(因为基本形状没有深度),但您可以使用transform
属性在3D空间(X、Y和Z轴)移动和旋转对象,然后使用透视来控制深度。
本文将从基础知识开始,逐步讲解透视的概念,最终创建一个完整的3D旋转立方体动画。
透视基础
我们从一个简单的绿色正方形开始,并在三个轴上移动它。
在X和Y轴上移动对象非常简单,但如果在Z轴上移动它,看起来正方形保持不变。这是因为当对象在Z轴上移动时,动画使它靠近我们,然后远离我们,但正方形的大小(和位置)保持不变。这就是CSS perspective
属性发挥作用的地方。
虽然透视在对象在X或Y轴上移动时没有影响,但当对象在Z轴上移动时,透视使正方形在靠近我们时看起来更大,在远离我们时看起来更小。是的,就像在现实生活中一样。
同样的效果也发生在我们旋转对象时:
在Z轴上旋转正方形看起来像是我们都熟悉和喜爱的常规旋转,但是当我们在X或Y轴上旋转正方形(不使用透视)时,它看起来只是正方形变小(或变窄)而不是旋转。但是当我们添加透视时,我们可以看到当正方形旋转时,正方形的近侧看起来更大,远侧看起来更小,旋转看起来符合预期。
请注意,当对象在X或Y轴上的旋转角度为90°(或270°、450°、630°等)时,它将“消失”在视野之外。同样,这是因为我们无法向对象添加深度,在这个位置,正方形的宽度(或高度)实际上将为0。
透视值
我们需要使用一个值来设置perspective
属性。此值设置对象平面的距离,或者换句话说,透视的强度。值越大,您离对象越远;值越小,透视效果越明显。
透视原点
perspective-origin
属性确定您“观察”对象的方位。如果原点居中(这是默认值)并且对象向右移动,则看起来您是从左侧观察它(反之亦然)。
或者,您可以将对象居中并移动perspective-origin
。当原点设置为侧面时,就像您从该侧面“观察”对象一样。值越大,看起来越偏离中心。
变换
虽然perspective
和perspective-origin
都设置在元素的父容器上,并确定消失点的位置(即从您“观察”对象的位置到对象平面的距离),但对象的位移和旋转是使用transform
属性设置的,该属性在对象本身上声明。
如果您查看前面示例的代码,我将正方形从一侧移动到另一侧,您会看到我使用了translateX()
函数——这是有道理的,因为我想让它沿X轴移动。但是请注意,它被分配给transform
属性。该函数是一种直接应用于我们要转换的元素的变换类型,但其行为符合分配给父元素的透视规则。
我们可以将多个函数“链接”到transform
属性。但是当使用多个变换时,需要考虑三件非常重要的事情:
- 旋转对象时,其坐标系会随着对象一起变换。
- 平移对象时,它相对于自身的坐标系移动(而不是其父坐标)。
- 这些值的书写顺序会(并且会)改变最终结果。
为了获得我在前面演示中想要的效果,我首先需要在X轴上平移正方形。只有这样我才能旋转它。如果这样做顺序颠倒(先旋转,然后平移),则结果将完全不同。
为了强调值顺序对transform
属性的重要性,让我们来看几个简单的例子。首先,是对两个正方形的简单二维(2D)变换,这两个正方形都具有相同的变换值,但声明顺序不同:
即使我们在Y轴上旋转正方形,情况也是一样的:
需要注意的是,虽然值的顺序很重要,但我们可以简单地更改值本身来获得所需的结果,而不是更改值的顺序。例如……
<code>transform: translateX(100px) rotateY(90deg);</code>
……与以下效果相同:
<code>transform: rotateY(90deg) translateZ(100px);</code>
这是因为在第一行中,我们在旋转对象之前在X轴上移动了对象,但在第二行中,我们旋转了对象,更改了其坐标,然后在Z轴上移动了它。相同的结果,不同的值。
让我们看看更有趣的东西
当然,正方形是解释透视一般概念的好方法,但是当我们分解成三维(3D)形状时,我们才能真正看到透视是如何工作的。
让我们使用到目前为止我们已经介绍的所有内容来构建一个3D立方体。
HTML
我们将创建一个.container
元素,它围绕一个.cube
元素,而.cube
元素又包含六个元素,代表立方体的六个面。
<div class="container"> <div class="cube"> <div class="side front"></div> <div class="side back"></div> <div class="side left"></div> <div class="side right"></div> <div class="side top"></div> <div class="side bottom"></div> </div> </div>
通用CSS
首先,我们将向父.container
元素添加一些透视。然后,我们将确保.cube
元素具有200px的边长并遵守3D变换。我在这里添加了一些表现性样式,但关键属性已突出显示。
/* 父容器,具有透视 */ .container { width: 400px; height: 400px; border: 2px solid white; border-radius: 4px; display: flex; justify-content: center; align-items: center; perspective: 800px; perspective-origin: top right; } /* 子元素,保留3D变换 */ .cube { position: relative; width: 200px; height: 200px; transform-style: preserve-3d; } /* 立方体的面,绝对定位 */ .side { position: absolute; width: 100%; height: 100%; opacity: 0.9; border: 2px solid white; } /* 立方体面的背景颜色,有助于可视化工作 */ .front { background-color: #d50000; } .back { background-color: #aa00ff; } .left { background-color: #304ffe; } .right { background-color: #0091ea; } .top { background-color: #00bfa5; } .bottom { background-color: #64dd17; }
变换面
正面是最简单的。我们将它向前移动100px:
.front { background-color: #d50000; transform: translateZ(100px); }
我们可以通过添加translateZ(-100px)
将立方体的背面向后移动。另一种方法是旋转侧面180deg,然后向前移动:
.back { background-color: #aa00ff; transform: translateZ(-100px); /* or */ /* transform: rotateY(180deg) translateZ(100px); */ }
像背面一样,我们可以通过几种方法来变换左右侧:
.left { background-color: #304ffe; transform: rotateY(90deg) translateZ(100px); /* or */ /* transform: translateX(100px) rotateY(90deg); */ } .right { background-color: #0091ea; transform: rotateY(-90deg) translateZ(100px); /* or */ /* transform: translateX(-100px) rotateY(90deg); */ }
顶部和底部略有不同。我们不需要在Y轴上旋转它们,而需要在X轴上旋转它们。同样,它可以通过几种不同的方式完成:
.top { background-color: #00Bfa5; transform: rotateX(90deg) translateZ(100px); /* or */ /* transform: translateY(-100px) rotateX(90deg); */ } .bottom { background-color: #64dd17; transform: rotateX(-90deg) translateZ(100px); /* or */ /* transform: translateY(100px) rotateX(90deg); */ }
这就得到了一个3D立方体!
随意尝试不同的perspective
和perspective-origin
选项,看看它们如何影响立方体。没有一个“正确”的值,这些值因项目而异,因为它们取决于动画、对象的大小以及您想要实现的效果。
让我们谈谈transform-style
我们将向立方体添加一些精美的动画,但是让我们首先讨论transform-style
属性。我之前在通用CSS中添加了它,但并没有真正解释它是什么或它做什么。
transform-style
属性有两个值:
-
flat
(默认值) preserve-3d
当我们将属性设置为preserve-3d
时,它会做两件重要的事情:
- 它告诉立方体的面(子元素)与立方体位于相同的3D空间中。如果未将其设置为
preserve-3d
,则默认值为flat
,并且面在立方体的平面上被展平。preserve-3d
将立方体的透视“复制”到其子元素(面),并允许我们仅旋转立方体,因此我们不需要分别为每个面设置动画。 - 它根据子元素在3D空间中的位置显示它们,而不管它们在DOM中的位置如何。
此示例中有三个正方形——绿色、红色和蓝色。绿色正方形的translateZ
值为100px,这意味着它位于其他正方形的前面。蓝色正方形的translateZ
值为-100px,这意味着它位于其他正方形的后面。
但在DOM中,正方形的顺序是:绿色、红色、蓝色。因此,当transform-style
设置为flat
(或根本未设置)时,蓝色正方形将显示在顶部,绿色正方形将在后面,因为这是DOM的顺序。但是,如果我们将transform-style
设置为preserve-3d
,它将根据其在3D空间中的位置进行渲染。结果,绿色正方形将在前面,蓝色正方形将在后面。
动画
现在,让我们为立方体设置动画!为了使事情更有趣,我们将动画添加到所有三个轴。首先,我们将animation
属性添加到.cube
。它现在还不会做任何事情,因为我们还没有定义动画关键帧,但是当我们这样做时,它已经到位了。
animation: cubeRotate 10s linear infinite;
现在是关键帧。我们基本上要沿每个轴旋转立方体,使其看起来像在空间中滚动。
@keyframes cubeRotate { from { transform: rotateY(0deg) rotateX(720deg) rotateZ(0deg); } to { transform: rotateY(360deg) rotateX(0deg) rotateZ(360deg); } }
perspective
属性实际上是赋予动画深度的属性,就像我们看到立方体向左和向右滚动,以及向前和向后滚动一样。
但是在此之前,perspective
属性的值是一致的,perspective-origin
也是如此。让我们看看更改这些值如何影响立方体的外观。
我已在此示例中添加了三个滑块,以帮助查看不同的值如何影响立方体的透视:
-
左侧滑块设置
perspective
属性的值。记住,此值设置对象平面的距离,因此值越小,透视效果越明显。 -
另外两个滑块指的是
perspective-origin
属性。右侧滑块在垂直轴上设置原点,从上到下,底部滑块在水平轴上设置原点,从右到左。
请注意,在动画运行时,这些变化可能不太明显,因为立方体本身在旋转,但是您可以通过单击“运行动画”按钮轻松关闭动画。
随意尝试这些值,并了解它们如何影响立方体的外观。没有一个“正确”的值,这些值因项目而异,因为它们取决于动画、对象的大小以及您想要实现的效果。
接下来的步骤?
既然您已经掌握了CSS中perspective
属性的基础知识,您可以发挥您的想象力和创造力,在您自己的项目中创建3D对象,为您的按钮、菜单、输入和其他任何您想要“赋予生命”的东西添加深度和趣味。
同时,您可以尝试创建一些复杂的结构和基于透视的动画来练习和提高您的技能,例如这个、这个、这个,甚至这个。
我希望您喜欢阅读这篇文章并在过程中学习到一些新东西!随意留下评论,让我知道您的想法,或者如果您对本文中的透视或任何其他主题有任何疑问,请在Twitter上给我留言。
以上是CSS观点如何工作的详细内容。更多信息请关注PHP中文网其他相关文章!

CSS盒子阴影和轮廓属性获得了主题。让我们查看一些在真实主题中起作用的示例,以及我们必须将这些样式应用于WordPress块和元素的选项。

Svelte Transition API提供了一种使组件输入或离开文档(包括自定义Svelte Transitions)时动画组件的方法。

前几天我只是和埃里克·迈耶(Eric Meyer)聊天,我想起了我成长时代的埃里克·迈耶(Eric Meyer)的故事。我写了一篇有关CSS特异性的博客文章,以及


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

WebStorm Mac版
好用的JavaScript开发工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Dreamweaver CS6
视觉化网页开发工具

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

MinGW - 适用于 Windows 的极简 GNU
这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。