Что делает CSS-функция scaleZ ()? - PullRequest
16 голосов
/ 19 октября 2011

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

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

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

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

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

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

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

Ответы [ 4 ]

18 голосов
/ 21 февраля 2013

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

Это связано с матрицами преобразования и умножением матрицы на вектор. По сути, преобразование не будет работать, если математика не сработает для создания продукта, координата 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-координатой. Преобразование имеет заметный эффект.

4 голосов
/ 29 июня 2012

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

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

3 голосов
/ 19 октября 2011

есть three views на веб-странице 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 ().

0 голосов
/ 19 октября 2011

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

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

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

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

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

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

...