Изучаем матрицы трансформаций в CSS
- Введение
- Что такое матрица?
- Трансформации и системы координат
- Расчет трансформации: математика матриц и векторов
- Составные трансформации с помощью матриц
Введение
Матричные функции — matrix()
and matrix3d()
— две самые головоломные в плане понимания вещи в CSS3-трансформациях. В большинстве случаев, ради простоты и ясности, вы будете пользоваться функциями вроде rotate()
и skewY()
. Но всё же за каждой трансформацией скрывается эквивалентная матрица. Полезно хоть слегка понимать, как они работают, так что давайте рассмотрим их поближе.
CSS-трансформации «растут» из линейной алгебры и геометрии. Хотя продвинутая математическая подготовка будет весьма не лишней, понять матричные функции можно и без нее. Но вы должны быть хорошо знакомы с CSS-трансформациями. Если нет, то почитайте статью «CSS3 transitions and 2D transforms».
В этой статье я охвачу как матрицы 3×3, используемые для двумерных трансформаций, так и матрицы 4×4 для трехмерных.
Заметьте, что на момент этой публикации Opera не поддерживает трехмерных трансформаций. Я включила двумерный matrix()
-эквивалент, где возможно.
В этой статье я также пользуюсь беспрефиксными версиями свойств transform
. На практике эти свойства всё еще экспериментальны и могут измениться. Пока они не утверждены окончательно, добавляйте в свой CSS-код версии с префиксом (напр., -o-transform
).
Что такое матрица?
Матрица — это прикольный математический термин для прямоугольного массива чисел, символов или выражений (см. рис. 1). У матриц множество математических и научных применений. Физики, например, используют их при изучении квантовой механики. В области компьютерной графики они используются для вещей типа — внезапно! — линейных трансформаций и проекции трехмерных изображений на двумерный экран. Это и есть то, что делают матричные функции: matrix()
позволяет нам создавать линейные трансформации, а matrix3d()
дает возможность создавать иллюзию трехмерности в двух измерениях с помощью CSS.

Мы не будем далеко забредать в глубины продвинутой алгебры. Вы должны быть знакомы с декартовой системой координат. Можете также освежить в памяти, как перемножать матрицы и векторы (либо воспользуйтесь калькулятором, типа предлагаемого Bluebit.gr).
Важный для понимания момент — то, что трансформация умножает матрицу на координаты точки (или точек), выраженные в виде вектора.
Трансформации и системы координат
Сначала поговорим о системах координат. Каждая область просмотра документа является системой координат. Левый верхний угол — ее начало, с координатами (0,0)
. Значения увеличиваются вправо по оси X и вниз по оси Y. Ось Z определяет кажущееся расстояние до зрителя в случае 3D-трансформаций. Бо́льшие значения — предметы ближе и крупнее, меньшие значения — мельче и дальше.
Когда трансформация применяется к объекту, она создает локальную систему координат. По умолчанию начало локальных координат — точка (0,0)
— лежит в центре объекта, или на 50% ширины и 50% высоты (рис. 2).

Мы можем изменить начало локальной системы координат подгонкой свойства transform-origin
(рис. 3). Задание transform-origin: 50px 70px;
, например, помещает начало координат в 50 пикселях от левого края объекта и в 70 пикселях от его верха. Трансформации каждой точки в локальной системе координат объекта рассчитываются относительно этого начала.

(50px,70px)
. Также показана точка (30px,30px)
Браузеры делают за вас эти вычисления каждый раз, когда вы применяете трансформацию. Вам нужно лишь знать, какие аргументы могут помочь достичь нужного вам эффекта.
Расчет трансформации: математика матриц и векторов
Взглянем на пример с использованием матрицы 3×3 для расчета двумерной трансформации (рис. 4). Матрица 4×4, используемая для трехмерных трансформаций, работает так же, с дополнительными числами для добавочной оси Z.

Мы можем записать это как transform: matrix(a,b,c,d,e,f)
, где буквы от a
до f
— числа, определяемые типом трансформации, которую мы хотим применить. Матрицы — это рецепты тех видов трансформации, которые мы хотим применить. Это станет чуть понятнее, когда мы рассмотрим несколько примеров.
Когда мы применяем двумерную трансформацию, браузер умножает матрицу на вектор [x, y, 1]
. Значения X и Y — координаты конкретной точки в локальном пространстве координат.
Чтобы найти координаты после трансформации, мы умножаем каждый элемент каждой строки матрицы на соответствующую ему строку вектора. Затем складываем произведения (рис. 5).

Я знаю, что это выглядит как куча бессмысленных цифр и букв. Но, как отмечено выше, у каждого типа трансформаций — своя собственная матрица. Рис. 6 показывает матрицу для трансформации сдвига.

Значения tx
и ty
— значения, на которые должно быть сдвинуто начало координат. Мы также можем представить это с помощью вектора [1 0 0 1 tx ty]
. Этот вектор служит аргументом для функции matrix()
, как показано ниже.
#mydiv {
transform: matrix(1, 0, 0, 1, tx, ty);
}
Давайте трансформируем объект, левый верхний угол которого совпадает с левым верхним углом области просмотра (Рис. 7). Его глобальные координаты равны (0,0)
.

(0,0)
Мы переместим этот объект на 150 пикселей по осям X и Y, используя начало координат трансформации по умолчанию. Ниже приведен CSS для этой трансформации.
#mydiv {
transform: matrix(1, 0, 0, 1, 150, 150);
}
Кстати, это эквивалентно transform: translate(150px,150px)
. Давайте рассчитаем результат этой трансформации для точки с координатами (220px,220px)
(Рис. 8).

Трансформации задают соответствие координатам и расстояниям в локальной системе координат объекта предыдущей системе координат. То, где точка отобразится в области просмотра, зависит от примененного при трансформации сдвига от начальной точки объекта. В этом примере наша точка с координатами (220px,220px)
теперь отображается в точке (370px,370px)
. Прочие координаты в границах нашего объекта тоже сместились на 150 пикселей вправо и на 150 пикселей вниз (рис. 9).

Матрица сдвига — особый случай. Она как аддитивна, так и мультипликативна. Более простым решением было бы просто прибавить значение сдвига к значениям X- и Y-координат нашей точки.
Расчет трехмерной трансформации
Выше мы рассмотрели матрицу переноса 3×3. Давайте возьмем другой пример, с использованием матрицы 4×4 для масштабирования (рис. 10).

Здесь sx, sy и sz представляют масштабные коэффициенты по каждой оси. С функцией matrix3d
это примет такой вид: transform: matrix3d(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1)
.
Будем продолжать с тем же объектом, что раньше. Уменьшим его масштаб по осям X и Y с помощью функции matrix3d()
, как показано ниже.
#mydiv{
transform: matrix3d(.8, 0, 0, 0, 0, .5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
}
Это эквивалентно transform: scale3d(0.8, 0.5, 1)
. Поскольку мы масштабируем только по осям X и Y (получая 2D-трансформацию), мы могли бы использовать также transform: matrix(.8, 0, 0, .5, 0, 0)
либо scale(.8,.5)
. Результат трансформации виден на рис. 11.

Если умножить эту матрицу на координатный вектор [150,150,1]
, (рис. 12), мы получим такие новые координаты нашей точки: (120,75,1)
.

Где взять значения матриц
Значения матриц для каждой функции трансформации приведены как в спецификации Scalable Vector Graphics, так и в спецификации CSS Transforms.
Составные трансформации с помощью матриц
Наконец, давайте рассмотрим, как создать составную трансформацию — трансформацию, эквивалентную применению нескольких функций трансформации одновременно. Ради простоты ограничимся двумя измерениями. Это значит, что мы будем использовать матрицу трансформации 3×3 и функцию matrix(). Этой трансформацией мы повернем наш объект на 45° и увеличим его масштаб в 1,5 раза от исходного размера.
Матрица поворота, выраженная в виде вектора — [cos(a) sin(a) -sin(a) cos(a) 0 0]
, где a — угол. Для масштабирования понадобится матрица [sx 0 0 sy 0 0]
. Чтобы объединить их, умножим матрицу поворота на матрицу масштабирования, как показано на рис. 13 (синус и косинус 45° оба равны 0,7071).

В CSS это будет выглядеть так: transform: matrix(1.0606, 1.0606, -1.0606, 1.0606, 0, 1)
. Рис. 14 показывает результат после применения трансформации.

Теперь рассчитаем новые координаты в области просмотра для точки (298,110)
, как показано на рис. 15.

Новыми координатами нашей точки будут (199.393px,432.725px)
.
Узнать больше
Надеюсь, эта статья немного приподняла завесу тайны над CSS-трансформациями. Если ей это не удалось, попробуйте обратиться к ресурсам ниже.
- Матрица (математика) в Википедии
- Объяснение матрицы трансформации во Flash 8 (автор — Senocular)
- Трансформации на сайте WolframMathWorld