2014-09-09 5 views
0

Я хотел бы зеркально отображать произвольные элементы SVG на месте. Это означает, что они должны оставаться в своем нынешнем положении, но получить зеркальное отражение.Зеркальные элементы SVG вокруг своей оси

Я знаю, что могу отражать элементы, используя scale(1, -1), а затем переводить их. Но вопрос в следующем: как узнать сумму перевода?

Я думал, что могу рассчитать сумму, добавив высоту элемента и в два раза больше расстояния до оси 0.

Это работает, например, с этим:

<polyline id="line1" stroke="green" stroke-width="1" fill="none" 
      points=" 
        10, 10   
        20, 10 20, 20 30, 20 30, 10 
        40, 10 40, 30 50, 30 50, 10 
        60, 10 60, 40 70, 40 70, 10 
        80, 10 80, 50 90, 50 90, 10 
       100, 10 100, 60 110, 60 110, 10 
       " 
      transform="scale(1, -1) translate(0, -70)" 
/>         

Высота элемента 50, расстояние до 0 оси 10, так что расстояние 50 + 2 * 10 = 70.

Однако это означает, что расчет отличается от типа элемента (строки, полилинии, прямой, g) и является ли объект уже переведенным.

Есть ли общий способ зеркального отображения элементов SVG?

ответ

0

Очевидно, что операции преобразования, которые вы должны применить, будут зависеть от всех указанных вами факторов. Нет простого «общего» способа, который будет работать в каждом случае. Вам нужно будет разобраться в каждом конкретном случае.

Метод getBBox() дает ограничительную рамку элемента после применение любого атрибута transform. Из этого вы можете определить ось отражения (т. Е. Центральную ось) и, следовательно, требуемые операции преобразования.

0

Этот случай в другом применении задачи «Масштаб вокруг точки» (так же, как и поворот вокруг точки). Как отметил @BigBadaboom, вам нужно использовать ограничительную ячейку элемента. Оттуда вам нужно сделать три шага:

Первый ход/перевести объект так, чтобы точка Вы хотели бы масштабировать объект вокруг лежит в начале координат ((0,0)),

Второе: шкала,

третья: переместить/перевести обратно отрицательным вектором с первого шага.

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

Обратите внимание, что getBBox() предоставит вам ограничительную рамку в локальных координатах, поэтому, если элемент находится в группе, которая уже имеет преобразование, координаты относятся к этой группе.

getBoundingClientRect() будет передавать значения в абсолютных координатах.

Это важно, поскольку вам необходимо решить, выполнять ли вычисления в абсолютном или локальном пространстве. Даже если возникает соблазн использовать локальное пространство, я часто использую абсолютное пространство, поскольку он будет работать для каждого элемента, даже если он глубоко вложен в DOM с уже примененной связкой преобразований.

getTransformToElement() будет вам полезным вычислить абсолютное преобразование любого элемента.

Итак, если вы вычислили необходимое преобразование элемента в абсолютном пространстве, вам просто нужно применить «изменение базы» к этому преобразованию, чтобы вернуть его в локальное пространство.

Все эти аффинные трансформации могут выглядеть несколько сложнее с первого взгляда, но стоит получить математику за ее пределами, после того, как выучили масштаб, вращение, сдвиговые и цепные преобразования (точки аргона тоже) не будут проблемой дольше.

Удачи!

Смежные вопросы