Как мне легче всего сначала масштабировать объект, скажем, в 2 раза больше текущего размера, а затем перевернуть его по вертикали и горизонтали или и то, и другое?

На данный момент я могу либо установить масштаб (2,2), чтобы он стал в 2 раза больше, чем его ширина и высота, но я не могу перевернуть его одновременно с масштабом (-1, 1) для вертикального переворота. .

Я создаю объекты SVG программно в качестве формата для экспорта.

77
Deukalion 28 Май 2014 в 02:03
6
transform: scale (-1, 1); transform-origin: center; - это все, что сейчас нужно.
 – 
brandito
27 Май 2019 в 03:16
После scale есть ненужный пробел.
 – 
Ian Y.
11 Дек 2021 в 11:30

4 ответа

Лучший ответ

Чтобы применить и масштабирование, и отражение, просто перечислите и то, и другое в вашем преобразовании:

transform="scale(2,2) scale(-1,1)"

Или просто объедините значения:

transform="scale(-2,2)"

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

Так, например, представьте, что у нас есть документ размером 100 × 100.

<svg width="100" height="100">
    <polygon points="100,0,100,100,0,100"/>
</svg>

Чтобы перевернуть это по вертикали, вы делаете:

<polygon points="100,0,100,100,0,100" transform="scale(2,-2)"/>

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

(вариант 1) Сдвиньте его в минус перед переворотом (чтобы он снова отображался на экране):

<polygon points="100,0,100,100,0,100" transform="scale(2,-2) translate(0,-100)"/>

(Перевод указан вторым здесь, потому что списки преобразований эффективно применяются справа налево)

(вариант 2) Или вы можете сдвинуть его в положительную сторону (на масштабированный размер) после этого:

<polygon points="100,0,100,100,0,100" transform="translate(0,200) scale(-2,2)"/>

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

Обновить

Чтобы перевернуть (по месту) уже существующий объект, который находится где-то на экране. Сначала определите его ограничивающую рамку (minX, minY, maxX, maxY) или centreX, centreY , если вы это уже знаете.

Затем добавьте к его преобразованию следующее:

translate(<minX+maxX>,0) scale(-1, 1)   // for flip X
translate(0,<minY+maxY>) scale(1, -1)   // for flip Y

Или если у вас есть центр, вы можете использовать

translate(<2 * centreX>,0) scale(-1, 1)   // for flip X

Итак, в вашем примере:

<rect x="75" y="75" width="50" height="50"  transform="translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

minX + maxX составляет 200. Итак, чтобы перевернуть по горизонтали, мы добавляем:

translate(200,0) scale(-1, 1)

Таким образом, конечный объект становится:

<rect x="75" y="75" width="50" height="50"  transform="translate(200,0) scale(-1, 1) translate(-100, -100) scale(2, 2) scale(1, 1) rotate(45, 100, 100)" />

Демо здесь

135
johannchopin 13 Окт 2020 в 23:15
Это очень помогает. Но мне все еще сложно понять, как их правильно сохранить в формате SVG. На каждом объекте вы можете: Вертикальное зеркало или Горизонтальное зеркало. Где как Вертикальная линия составляет половину ширины, а Горизонтальная - на половину высоты. Что-то нарисованное слева, должно появиться справа. Достаточно просто, до тех пор, пока каждый объект не будет масштабирован или не масштабирован, перемещен от его исходного «x» и «y» = Translate или Rotated. Я не уверен, что нужно использовать атрибут преобразования SVG. Я знаю центр объектов, размер документа и т. Д., А также значения Transform, Scale, Rotate + V или H зеркало.
 – 
Deukalion
29 Май 2014 в 13:12
Вы, конечно, ответили на вопрос, это просто расширенный вопрос, чтобы все это изложить. Мне кажется, я не могу поместить все другие значения в уравнение сейчас, когда это выяснено.
 – 
Deukalion
29 Май 2014 в 13:14
Это попытка показать, что я имею в виду, и включить в микс такие вещи, как поворот, масштабирование: jsfiddle.net/ kj78D / 59 - как видно, градиент также обратный, что указывает на зеркальное отображение ... теперь я не уверен, где я предполагаю поместить "преобразование" - скажем, если объект был помещен в x = 75, y = 75, но переместились на 25 в каждом направлении. Куда это идет, и я не совсем уверен, зачем зеркально отраженному прямоугольнику нужно «транслировать (-300, -100), поскольку они не указывают ни на что конкретное, в то время как первые объекты переводят по крайней мере точки в отрицательный центр объектов? Или может быть, они оба знают.
 – 
Deukalion
29 Май 2014 в 13:54
Мой эксперимент, вероятно, не сработает, если я поставлю первый «перевернутый» прямоугольник на противоположной стороне (там, где сейчас находится зеркальный) и сохраню значения. Наверное, не буду выглядеть так же, так что я, наверное, просто зря трачу время на понимание этого. Я пробовал реализовать некоторые из них, но это не срабатывает каждый раз, поэтому мне нужен хороший шаблон, в который я могу поместить все, что угодно, и поменять местами, независимо от того, какие значения вводятся. Матрицы всегда были проблемой жопа.
 – 
Deukalion
29 Май 2014 в 14:48
Перевести Масштаб Отразить Повернуть Перевести? В произвольном порядке. Создайте прямоугольник с заданной координатой в документе, поверните его на несколько градусов, переместите на некоторые координаты, масштабируйте его до чего-то другого, кроме исходного размера, и, наконец, переверните все это так, чтобы оно было перевернуто по вертикали или по горизонтали, или и то, и другое. Единственная проблема - преобразовать мои значения в формат SVG. Конечно, как я, вероятно, уже говорил ранее, нет необходимости включать одно из этих значений, и, возможно, для каждого из них существует свой сценарий. Скажем, я исключаю поворот или масштабирование; вероятно, в формате SVG тоже будет выглядеть по-другому.
 – 
Deukalion
29 Май 2014 в 15:54

Просто добавьте атрибуты ниже в тег пути в svg

transform="scale (-1, 1)" transform-origin="center"

Например: <path transform="scale (-1, 1)" transform-origin="center" ......./>

27
Rayees Pk 23 Фев 2020 в 10:44
1
Почему это не набирает больше голосов? Кажется, чтобы избежать ненужной translate сложности
 – 
Tunn
23 Ноя 2020 в 21:42
У меня это отлично сработало при редактировании файла SVG. Отличный быстрый ответ.
 – 
Chris - Jr
30 Янв 2021 в 00:08
Это можно применить непосредственно к <svg, если кто-то пытается применить к каждому пути, который у него есть.
 – 
titusfx
22 Сен 2021 в 16:22

Познакомьтесь с пингвином Туксом. Ради этого упражнения я нарисовал на его ступнях буквы «L» и «R».

Tux the pinguin

Для начала нарисуем смокинг в центре нашего холста. Если размер холста 500x500, а у Тукса размер 100x100, мы должны разместить его в (200,200). (т. е. центр минус половина его размера.)

  <svg width="500" height="500">
    <!-- marking our border and a cross through the center -->
    <rect x="0" y="0" width="500" height="500" stroke-width="2" stroke="red" fill="none"></rect>
    <line x1="0" y1="0" x2="500" y2="500" stroke="red" stroke-width="2"></line>
    <line x1="500" y1="0" x2="0" y2="500" stroke="red" stroke-width="2"></line>

    <!-- our pinguin in the center -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"></image>
  </svg>

The result

Теперь, если мы хотим отразить наш пингвин по горизонтали (переключение влево и вправо), возникает соблазн просто использовать преобразование с scale(-1 1). Однако наш пингвин просто исчезает, когда мы пытаемся это сделать.

  <svg width="500" height="500">
    ...
    <image ... transform="scale(-1 1)"></image>
  </svg>

pinguin is gone

Причина в том, что точка отражения по умолчанию (так называемая «исходная точка преобразования») для нашего преобразования находится не в центре изображения, а на самом деле все еще в точке (0,0).

Наиболее очевидное решение - переместить точку отражения в центральную точку изображения (250,250). (в данном случае центр нашего холста).

  <svg width="500" height="500">
    ...
    <image ... transform="scale(-1 1)" transform-origin="250 250"></image>
  </svg>

Change the transform origin

И изменение размера работает точно так же. Вы можете сделать это в 2 шкалах или объединить их в 1 шкалу.

  <svg width="500" height="500">
    <!-- use 2 scales -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"
           transform="scale(-1 1) scale(2 2)" transform-origin="250 250">
    </image>    
    <!-- or just multiply the values of both scales -->
    <image x="200" y="200" width="100" height="100" href="assets/pinguin.png"
           transform="scale(-2 2)" transform-origin="250 250">
    </image>
  </svg>

still 2 options

4
bvdb 28 Окт 2021 в 10:39