搜索
首页web前端css教程CSS观点如何工作

How CSS Perspective Works

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。当原点设置为侧面时,就像您从该侧面“观察”对象一样。值越大,看起来越偏离中心。

变换

虽然perspectiveperspective-origin都设置在元素的父容器上,并确定消失点的位置(即从您“观察”对象的位置到对象平面的距离),但对象的位移和旋转是使用transform属性设置的,该属性在对象本身上声明。

如果您查看前面示例的代码,我将正方形从一侧移动到另一侧,您会看到我使用了translateX()函数——这是有道理的,因为我想让它沿X轴移动。但是请注意,它被分配给transform属性。该函数是一种直接应用于我们要转换的元素的变换类型,但其行为符合分配给父元素的透视规则。

我们可以将多个函数“链接”到transform属性。但是当使用多个变换时,需要考虑三件非常重要的事情:

  1. 旋转对象时,其坐标系会随着对象一起变换。
  2. 平移对象时,它相对于自身的坐标系移动(而不是其父坐标)。
  3. 这些值的书写顺序会(并且会)改变最终结果。

为了获得我在前面演示中想要的效果,我首先需要在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立方体!

随意尝试不同的perspectiveperspective-origin选项,看看它们如何影响立方体。没有一个“正确”的值,这些值因项目而异,因为它们取决于动画、对象的大小以及您想要实现的效果。

让我们谈谈transform-style

我们将向立方体添加一些精美的动画,但是让我们首先讨论transform-style属性。我之前在通用CSS中添加了它,但并没有真正解释它是什么或它做什么。

transform-style属性有两个值:

  • flat(默认值)
  • preserve-3d

当我们将属性设置为preserve-3d时,它会做两件重要的事情:

  1. 它告诉立方体的面(子元素)与立方体位于相同的3D空间中。如果未将其设置为preserve-3d,则默认值为flat,并且面在立方体的平面上被展平。preserve-3d将立方体的透视“复制”到其子元素(面),并允许我们仅旋转立方体,因此我们不需要分别为每个面设置动画。
  2. 它根据子元素在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中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
将框阴影添加到WordPress块和元素将框阴影添加到WordPress块和元素Mar 09, 2025 pm 12:53 PM

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

使用GraphQL缓存使用GraphQL缓存Mar 19, 2025 am 09:36 AM

如果您最近开始使用GraphQL或审查了其优点和缺点,那么您毫无疑问听到了诸如“ GraphQl不支持缓存”或

优雅且酷的自定义CSS卷轴:展示柜优雅且酷的自定义CSS卷轴:展示柜Mar 10, 2025 am 11:37 AM

在本文中,我们将深入研究滚动条。我知道,这听起来并不魅力,但请相信我,一个精心设计的页面是齐头并进的

使您的第一个自定义苗条过渡使您的第一个自定义苗条过渡Mar 15, 2025 am 11:08 AM

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

展示,不要说展示,不要说Mar 16, 2025 am 11:49 AM

您花多少时间为网站设计内容演示文稿?当您撰写新的博客文章或创建新页面时,您是在考虑

使用Redwood.js和Fauna构建以太坊应用使用Redwood.js和Fauna构建以太坊应用Mar 28, 2025 am 09:18 AM

随着最近比特币价格超过20k美元的攀升,最近打破了3万美元,我认为值得深入研究创建以太坊

NPM命令是什么?NPM命令是什么?Mar 15, 2025 am 11:36 AM

NPM命令为您运行各种任务,无论是一次性或连续运行的过程,例如启动服务器或编译代码。

让我们使用(x,x,x,x)来谈论特殊性让我们使用(x,x,x,x)来谈论特殊性Mar 24, 2025 am 10:37 AM

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

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

mPDF

mPDF

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

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

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