scaleZ() CSS变换函数是什么?

16

我正在努力理解3D CSS转换,但我很难理解scaleZ()函数的作用。

scale()scaleX()scaleY()是有意义的:它们沿着指定的轴拉伸元素,在该轴上乘以您提供的数字来改变其尺寸。

但是scaleZ()似乎不同:

  1. 它适用于该元素的子代
  2. 它不影响子元素的尺寸,因为HTML元素沿z轴没有任何尺寸(即您无法使<div>“更厚”)。

WebKit博客说:

[scaleZ()] 影响转换后的子代在z轴上的缩放。

我无法理解这在实践中实际意味着什么。是否有人能提供一些示例代码,并对其进行解释?


乍一看,它似乎与已转换为三维空间而不是平面上的元素有关...但实际上,我同意你的观点——即使在这种情况下,逻辑上X和Y仍然应该适用于元素自身的2D形状,在这种情况下,即使它已被转换到页面的Z轴上,元素本身仍然是平面的,并没有自己的Z轴。所以...我不确定scaleZ是做什么的。 - Spudley
4个回答

20

看起来在问题被提出两年后回答问题有点愚蠢,但为了保存记录还是发布一下。

与变换矩阵和矩阵向量乘法有关。基本上,除非数学计算得出的乘积中Z坐标大于零,否则变换看起来不会生效。

这很容易解释,但如果您没有数学背景,可能有点难理解。(但是通过一个周末的维基百科阅读和谷歌搜索,就足以教您足够的知识了。我就是这样学习的。)除了matrix()和matrix3d()之外的每个变换函数都有一个相应的矩阵值。对于scale3d,该矩阵如下:

[sx 0 0 0]
[0 sy 0 0]
[0 0 sz 0]
[0 0  0 1] 

sx,sy和sz分别是绕x轴、y轴和z轴缩放的因子。对于scaleZ,情况相同,但sx和sy均为1。

应用变换时,浏览器获取对象每个顶点的坐标(通俗地说,就是获取盒子角的坐标),并将其乘以变换矩阵。这个乘积成为对象的新坐标。例如,在从(100, 50, 0)开始的对象上应用 transform: scaleZ(3) 变换的数学计算看起来有点像这样:

[1 0 0 0]   [100]   [100]
[0 1 0 0] * [ 50] = [ 50]
[0 0 3 0]   [  0]   [  0]
[0 0 0 1]   [  1]   [  1]

当将该产品 [100 50 0 1] 转换为3D坐标系时,它变为我们最初的样子:(100,50,0)。结果看起来好像应用的转换没有生效。要使使用 scaleZ() 的变换生效,矩阵和向量的乘积的第三个数必须大于零。通常情况下,当在父元素上应用 scaleZ() 或 scale3d(),或者与另一个变换函数组合使用时,会发生这种情况。在这两种情况下,累计/当前变换矩阵的结果会产生一个 Z 坐标,其值大于零。下面是一个示例,使用 transform: rotateY(30deg) scaleZ(3)。首先需要将 rotateY(30deg) 的矩阵乘以 scaleZ(3) 的矩阵。

[0.866 0 -0.499 0]   [1 0 0 0]   [0.866 0 -1.497 0]
[0     1  0     0] * [0 1 0 0] = [0     1  0     0]
[0.499 0  0.866 0]   [0 0 3 0]   [0.499 0  2.598 0]
[0     0  0     1]   [0 0 0 1]   [0     0  0     0]

然后,我们可以将矩阵乘积(等号右侧的那一部分)与点(100,50,0)相乘。

[0.866  0 -1.497  0]   [100]   [86.6]
[0      1  0      0] * [ 50] = [50  ]
[0.499  0  2.598  0]   [  0]   [49.9]
[0      0  0      1]   [  1]   [ 1  ]

我们的产品[86.6 50 49.9 1]四舍五入成为整数后对应坐标为(87,50,50),其中第二个50是我们的Z坐标。这种转换有明显的效果。


实际上,我的答案只是部分回答了这个问题。答案是scaleZ()通过指定的因子移动对象的Z坐标。这个答案解释了为什么它有时只能部分起作用。 - webinista
4
两年后回答一个问题似乎有些愚蠢 - 绝对不是!这样做可以让您获得“复兴者”和“死灵法师”徽章! - Paul D. Waite

4

虽然经过一番实验,但我对这个问题感到困惑已久,现在我相信这很容易理解:

假设一个元素在Z轴上定位100像素,让它向观察者移动,就像这样:

div {
    transform: translateZ(100px);
}

然后你将 Z 轴放大了两倍:

div {
    transform: scaleZ(2) translateZ(100px);
}

它的尺寸不会受到你所说的影响,但它现在的大小将与translateZ(200px)相同。scaleZ(2)translateZ(400px)等效于translateZ(800px)等等。
你可以在JSFiddle上看到演示
不要认为scaleZ()会影响元素,而是Z轴上的元素。
最后一点说明:浏览器应该将多个变换函数视为分别应用,这意味着它们的顺序很重要。为了使scaleZ()起作用,它必须放在translateZ()之前,否则你只是在Z轴上移动元素,然后缩放轴而没有任何视觉效果。

3

我们的网页中有三个视图:X,Y和Z ,例如 z-index 就像是 scaleZ() 中的同样东西。

请查看 W3C 的相关说明。

scale(<number>[, <number>])
specifies a 2D scale operation by the [sx,sy] scaling vector described by the 2 parameters. If the second parameter is not provided, it is takes a value equal to the first.
scale3d(<number>, <number>, <number>)
specifies a 3D scale operation by the [sx,sy,sz] scaling vector described by the 3 parameters.
scaleX(<number>)
specifies a scale operation using the [sx,1,1] scaling vector, where sx is given as the parameter.
scaleY(<number>)
specifies a scale operation using the [1,sy,1] scaling vector, where sy is given as the parameter.
scaleZ(<number>)
specifies a scale operation using the [1,1,sz] scaling vector, where sz is given as the parameter. 

检查您的链接动画:http://www.webkit.org/blog-files/3d-transforms/morphing-cubes.html 编辑:
您的代码示例仍未解释什么是scaleZ(),因为我们也可以从scaleY()获得该效果。
请查看此代码示例:http://jsfiddle.net/sandeep/dppNn/ 现在,在我的代码示例中,您可以看到第三个数字框看起来像3D,因为它们使用了scaleX(),scaleY()和scaleZ(),而第二个数字框只使用了scaleX()和scaleY(),因此看起来像2D。

2
scaleZ()并不等同于z-indextranslateZ()更接近于z-index(因为它沿着z轴移动元素)。scaleZ()似乎做了与此不同的事情。 - Paul D. Waite
你从W3C规范中引用的内容并不是特别有帮助,因为scaleZ()的解释使用了与scaleX()scaleY()相同的措辞,尽管它执行的操作是不同的。你能解释一下它的含义吗? - Paul D. Waite
2
啊,好的,我现在更明白你的意思了。我稍微修改了你的Fiddle:http://jsfiddle.net/pauldwaite/dppNn/3/ 我只对.cube > .two.cube > .three应用了scaleZ()。据我理解,立方体2不受影响(因为它的尺寸沿着x和y轴),但立方体3会变宽,因为它被旋转了,这意味着它的宽度沿着z轴而不是x轴。 - Paul D. Waite

0

苹果公司的Safari CSS视觉效果指南像这样解释了scaleZ()

您可以通过缩放z轴来修改元素后代的坐标系,以便沿z轴的距离变大或变小。此缩放仅影响元素的后代,并且缩放需要启用3D变换,因此z轴缩放至少需要两个3D层。[我强调]

所以,我的理解是:

  1. 您有两个3D层,且
  2. 内部层应用了scaleZ()

那么,当内部层的后代应用3D变换时,它们沿z轴的移动将乘以您传递给scaleZ()的值。或者什么的。

我已经在JSFiddle上弹出了一个示例。如果您删除-webkit-transform: scaleZ(3);,那么蓝色框将适合灰色框内,因为它不会沿z轴移动太多。(我想。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接