本文运用「署名 4.0 国际 (CC BY 4.0)」 许可协议,欢迎转载、或从头修正运用,但需求注明来历。

作者: 百应前端团队 凌伊

常用的 3D 改换函数

CSS 位移改换函数包含 translateX()translateY()translateZ(),其间 translateX()translateY()归于 2D 改换,translateZ()归于 3D 改换。

CSS 缩放改换函数包含scaleX()scaleY()scaleZ(),其间 scaleX()scaleY()归于 2D 改换,scaleZ()归于 3D 改换。

与此不同,CSS 旋转函数rotateX()rotateY()rotateZ()均归于 3D 改换。

除此之外, matrix3d() 也是 3D 改换的函数, 可是其参数众多(16 个参数),过于杂乱并且运用场景很少,本篇文章不做介绍。

结合以上各种改换的 3D 语法,能够得到下面这些归于 3D 改换的 CSS 函数

translateZ(0);
translate3d(0, 0, 0);
rotateX(0deg) rotateY(0deg) rotateZ(0deg);
rotate3d(1, 1, 1, 45deg);
scaleZ(1);
scale3d(1, 1, 1);
matrix3d(
    1, 0, 0, 0,
    0, 1, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1 
);

rotate3d()

在展开介绍 rotate3d()函数之前,咱们有必要先了解一下 CSS 中的 3D 坐标。CSS 中的 3D 坐标中,横向为 x 轴,笔直为 y 轴,纵向为 z 轴,箭头所指的方向为偏移正值对应的方向,如下图所示:

CSS 3D 改动的那些事

rotate3d()函数的语法为:rotate3d(x, y, z, angle)

其间,参数 x、y、z 别离表明旋转向量的 x 轴、y 轴、z 轴的坐标。参数 angle 表明围绕该旋转向量旋转的视点值,假如为正,则顺时针方向旋转;假如为负,则逆时针方向旋转。

transform:rotate3d(1, 1, 1, 45deg);表明元素绕着坐标(0, 0, 0)和坐标(1, 1, 1)连成的向量线旋转 45 度,参阅下图:

CSS 3D 改动的那些事

rotate3d()运用的场景其实不多,主要还是rotateX()rotateY()rotateZ()

  • rotateX(angle);
  • rotateY(angle);
  • rotateZ(angle);

它们别离表明绕着三维坐标的 x 轴、y 轴和 z 轴旋转。其间,rotateX()函数的体现反映在实际国际中, 体操运动员的单杠旋转;rotateY()函数的体现反映在实际国际中,旋转木马围绕中心柱旋转;rotateZ()函数的体现反映在实际国际中,正面观察摩天轮的旋转。

CSS 3D 改动的那些事

perspective

perspective 的中文意思是透视、视角。perspective 特点的存在与否决议了你所看到的画面是二维的还是三维的。

CSS 3D 改动的那些事

CSS 3D 改换的透视点与上图所示的有所不同,CSS 3D 改换的透视点在显现器的前方。例如, 显现器宽度是 1680px,浏览器中有一个<img />元素设置了下面的 CSS 代码:

img {
    perspective: 2000px;
}

这就意味着这张图片的 3D 视觉作用和本人在间隔 1.2 个显现器宽度远的当地(16801.2≈2000)所看到的实在作用是共同的

CSS 3D 改动的那些事

translateZ()

咱们都知道“近大远小”的道理,translateZ()函数的功用便是控制元素在视觉上的远近距 离。例如,假如咱们设置容器元素的 perspective 特点值为 201px:

.container {
    perspective: 201px;
}

那么就会有以下几种情况:

  1. 子元素设置的 translateZ()函数值越小,则子元素看起来越小,由于子元素在视觉上远去,咱们眼睛看到的子元素的视觉尺度就会变小。
  2. 子元素设置的 translateZ()函数值越大,该元素看起来也会越大,由于元素在视觉上越近,看上去也就越大。
  3. 当子元素设置的 translateZ()函数值十分挨近 201 像素,可是不超过 201 像素的时分(如 200 像素), 该元素就会撑满整个屏幕(假如父元素没有相似 overflow:hidden 的约束)。由于这个时分,子元素相关于正好移到了你的眼睛前面,看起来十分大,能够参阅链接

translateZ()函数的作用原理如图所示:

CSS 3D 改动的那些事

perspective 透视点

有两种书写形式能够指定元素的透视点,一种设置在舞台元素上,也便是设置在 3D 烘托元素的共同父元素上;第二种是设置在当前 3D 烘托元素上,与 transform 其他改换特点值写在一同,代码示例如下:

.stage .box {
    transform: perspective(600px) rotateY(45deg);
}
.stage {
    perspective: 600px;
}
.box {
    transform: rotateY(45deg);
}

示例作用可点击:codepen.io/pikahan-the…

上面一排元素中的每个子元素都有一个自己独立的透视点,加上旋转的视点又是相同的,因而每个元素看上去也就如出一辙了。

下面一排元素把整个舞台作为透视元素,也便是咱们看到的每个子元素都共用同一个透视点,因而每一个子元素的视觉形状都不相同,这个作用比较契合实际国际的 3D 透视作用。

perspective-origin

perspective-origin 特点表明咱们的眼睛相对 3D 改换元素的方位,你能够经过改动眼睛的方位来改动元素的 3D 烘托作用。

CSS 3D 改动的那些事

语法为:perspective-origin: <position>;

perspective-origin: top left;
perspective-origin: right 20px bottom 40%;
perspective-origin: 50% 50%;
perspective-origin: -200% 200%;
perspective-origin: 20cm 100ch;

perspective-origin 特点初始值是 50% 50%,表明默许的透视点是舞台或元素的中心。可是有时分,需求让改换的元素不在舞台的中心,或让透视视点偏上或者偏下,此刻就能够经过设置 perspective-origin 特点值完成。

transform-style

transform-style 支持两个关键字特点值,别离是 preserve-3dflat,语法如下:

transform-style: preserve-3d;
transform-style: flat;
  • preserve-3d 表明运用 3D 改换的元素坐落三维空间中,preserve-3d 特点值的烘托体现更契合实在国际的 3D 体现。

  • flat 是默许值,表明运用 3D 改换的元素坐落舞台或元素的平面中,把三维空间压缩在舞台元素的二维空间中。

经过一个比如直观地了解一下 preserve-3d 和 flat 这两个特点值的区别。

运用了transform-style:preserve-3d声明的 3D 改换元素有部分区域藏到了舞台元素的后边,由于此刻整个舞台依照实在的三维空间烘托,自然看不到旋转到后边的图形区域,如图形所示。而默许情况下,元素无论怎样改换,其 3D 作用都会被烘托在舞台元素地点的二维平面之上,因而没有视觉上的穿透作用。

backface-visibility

在 CSS 中,一个元素的反面体现为其正面图像的镜像,因而,当咱们运用翻转作用使其反面展现在用户面前的时分,显现的是该元素正面图像的镜像。这一特性和实际中的 3D 作用并不共同。

例如咱们要完成扑克牌翻转的 3D 作用,扑克牌的反面是斑纹。因而,当咱们对扑克牌进行翻转使其反面展现在用户面前的时分,显现扑克牌的正面镜像显然是不合理的。咱们需求躲藏扑克牌元素的反面,而扑克牌反面斑纹的作用,能够运用其他元素进行模仿,然后让前后两个元素互相配合来完成 3D 扑克牌翻转作用。这个控制扑克牌的反面不显现的 CSS 特点便是backface-visibility

/* 语法 */
backface-visibility: visible; /* 默许值 */
backface-visibility: hidden;

CSS 3D 改动的那些事
作用展现请点击这儿

3D 轮播图事例

CSS 3D 改动的那些事

这个事例运用到的 CSS 特点便是上述说到的几个常用 CSS 特点,包含透视、3D 改换和三维空间设置等。

下面跟着小编一步一步来看看这个轮播作用是怎样完成的。

首先需求完成 html 代码, 刺进 9 张图片排列:

<div class="stage">
  <div class="container">
    <img src="1.jpg" style="--index:0;">
    <img src="2.jpg" style="--index:1;">
    <img src="3.jpg" style="--index:2;">
    <img src="4.jpg" style="--index:3;">
    <img src="5.jpg" style="--index:4;">
    <img src="6.jpg" style="--index:5;">
    <img src="7.jpg" style="--index:6;">
    <img src="8.jpg" style="--index:7;">
    <img src="9.jpg" style="--index:8;">
  </div>
</div>

为了有 3D 透视的作用,咱们需求给舞台设置视距:

.stage {
    perspective: 800px;
}

关于容器,咱们要对其进行 3D 视图的声明,否则图片只会像 2D 相同的堆叠在一同:

.container {
    transform-style: preserve-3d;
 }

之后便是对图片的处理了,首先要完成像旋转木马相同的轮播作用,很明显要用到 rotateY() 函数,又由于有 9 张图片, 360 / 90 = 40,每个图片占 40 的旋转角。

img {
    position: absolute;
    top: 0;
    left: 0;
    transform: rotateY(calc(var(--index) * 40deg));
}

但现在还没有完美完成,由于图片还挤成一团, 如图:

CSS 3D 改动的那些事

尽管 9 张图片的方位都不相同,但由于它们共用一个 3D 改换中心点,因而一定会挤成一团,咱们需求摆开图片之间的间隔。

咱们能够把 9 张图片幻想成 9 个人,现在这 9 个人站在一同别离面朝不同方位,这 9 个人只需每个人向前走 4~5 步,彼此之间的间隔就摆开了,这儿的向前走 4~5 步的行为,就相当于运用translateZ()函数的行为,当translateZ()函数值为正值的时分,元素会向其面对的方向走去。

这个间隔也是很好核算的,咱们假定图片是 128px, 图片要首尾相接的话能够画出如下的图:

CSS 3D 改动的那些事

其间 r 的长度便是咱们要的间隔

CSS 3D 改动的那些事

function getAdjacent(x, angle) {
  const radians = angle * (Math.PI / 180); // 视点转弧度
  return x / Math.tan(radians);
}

getAdjacent(64,20)算出 r 的长度约等于 175.84

为了作用更调和,图片左右两边能够留点间距,例如 30px,经过三角函数算出 r 需求再加 20.52, 也便是终究需求 175.84 + 20.52 = 196.36 px 的间隔。

所以,终究图片元素设置的 transform 特点值是:

img {
    transform: rotateY(calc(var(--index) * 40deg)) translateZ(196.36px);
}

终究,要让图片旋转起来,只需点击让容器每次旋转 40 度就能够了。

container.onclick = function () {
    const index = (this.index || 0) + 1;
    this.style.transform = 'rotateY('+ index * 40 +'deg)';
    this.index = index;
};

结束语

本文主要是介绍了 CSS 3D 中一些常用的特点和函数,阅读到这儿,咱们已然领悟到了 CSS 3D 的强大,它能创造出十分酷炫、令人惊叹的作用和动画,相信随着咱们关于 CSS 3D 方面的学习探索,定能得心应手。