Что делает функция преобразования CSS scaleZ ()?


Я пытаюсь обернуть свой крошечный мозг вокруг 3D CSS-преобразований, и мне трудно понять, для чего предназначена функция scaleZ().

scale(), scaleX() и scaleY() имеют смысл: они растягивают элемент вдоль указанной оси, умножая его размер вдоль этой оси на число, которое вы предоставляете.

Но scaleZ() кажется другим:

  1. это относится к дочерним элементам элемента
  2. это не влияет на размеры дочерних элементов, так как HTML-элементы не имеют их размер вдоль оси z (то есть вы не можете сделать <div> "толще").

В блоге WebKit говорится :

[scaleZ()] влияет на масштабирование по оси z у трансформированных детей.

Я не могу понять, что это на самом деле означает на практике. Может ли кто-нибудь дать объяснение, предпочтительно с некоторым примером кода?
4 15

4 ответа:

Кажется глупым отвечать на вопрос через два года после того, как он был задан, но отправлять его для потомков.

Это связано с преобразованием матриц и умножением матриц-векторов. В принципе, преобразование не будет работать, если математика не работает, чтобы произвести продукт, где координата Z больше нуля. Это легко объяснить, но немного трудно понять, если у вас нет математического образования. (Но выходные стоят чтения Википедии и поиска в Google я научу тебя многому. Вот как я этому научился.) Каждая функция преобразования, кроме 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.

Когда вы применяете преобразование, браузер берет координаты для каждой вершины объекта (на не-Ботаническом языке: берет координаты для каждого угла коробки) и умножает их по матрице преобразования. Результатом этого становятся новые координаты объекта. Например, математика transform: scaleZ(3) для объекта, начинающегося с (100,50,0), выглядит примерно так:

[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] при переводе в трехмерную систему координат становится тем, с чего мы начали: (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. Трансформация имеет заметный эффект.

Есть three views в over webpage 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/

Теперь в моем примере скрипки вы можете 3rd digit box выглядеть как 3D means с scaleX(),scaleY() & scaleZ() & 2nd digit box выглядят как 2D, потому что масштабируются только scaleX () и scaleY ().

Я долго был в замешательстве по этому поводу, хотя, экспериментируя, я думаю, что это довольно легко понять:

Предположим, что элемент расположен на 100px по оси Z, что заставляет его двигаться к зрителю, например:

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, а затем масштабируете ось без какого-либо визуального результата.

Руководство по визуальным эффектам Safari CSS от Apple объясняет scaleZ() примерно так:

Вы можете изменить систему координат потомков элемента, масштабируя ось z так, чтобы расстояния вдоль оси z были больше или меньше. Это масштабирование влияет только на потомков элемента, имасштабирование требует включения 3D-преобразований, поэтому масштабирование по оси z требует по крайней мере двух 3D-слоев . [Курсив мой]

Итак, как я понимаю, когда:

  1. у вас есть два 3D слоя, и
  2. внутренний имеет scaleZ() приложенный к нему

Затем, когда к потомкам внутреннего слоя будут применены 3D-преобразования, их движение вдоль оси z будет умножено на значение, которое вы передали scaleZ(). Или еще что-нибудь.

Я нашел пример на JSFiddle. Если вы удалите -webkit-transform: scaleZ(3);, то синяя коробка поместится внутри серой коробки, потому что она не так сильно перемещается вдоль оси Z. (Я думаю.)