Как мне легче всего сначала масштабировать объект, скажем, в 2 раза больше текущего размера, а затем перевернуть его по вертикали и горизонтали или и то, и другое?
На данный момент я могу либо установить масштаб (2,2), чтобы он стал в 2 раза больше, чем его ширина и высота, но я не могу перевернуть его одновременно с масштабом (-1, 1) для вертикального переворота. .
Я создаю объекты SVG программно в качестве формата для экспорта.
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)" />
# scale is 1 by default
if mirror or scale isnt 1
[minx, miny, width, height] = svg.attributes.viewBox |> split-by ',' |> cast-each-as (Number)
s = scale
# container is the root `g` node
container.attributes.transform = if mirror
"translate(#{s * (width + minx) + minx}, #{-miny * (s-1)}) scale(#{-s},#{s})"
else
"translate(#{-minx * (s-1)}, #{-miny * (s-1)}) scale(#{s},#{s})"
if scale isnt 1
svg.attributes
..viewBox = "#{minx},#{miny},#{width * scale},#{height * scale}"
..width = "#{width * scale}"
..height = "#{height * scale}"
Просто добавьте атрибуты ниже в тег пути в svg
transform="scale (-1, 1)" transform-origin="center"
Например: <path transform="scale (-1, 1)" transform-origin="center" ......./>
translate
сложности
Познакомьтесь с пингвином Туксом. Ради этого упражнения я нарисовал на его ступнях буквы «L» и «R».
Для начала нарисуем смокинг в центре нашего холста. Если размер холста 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>
Теперь, если мы хотим отразить наш пингвин по горизонтали (переключение влево и вправо), возникает соблазн просто использовать преобразование с scale(-1 1)
. Однако наш пингвин просто исчезает, когда мы пытаемся это сделать.
<svg width="500" height="500">
...
<image ... transform="scale(-1 1)"></image>
</svg>
Причина в том, что точка отражения по умолчанию (так называемая «исходная точка преобразования») для нашего преобразования находится не в центре изображения, а на самом деле все еще в точке (0,0)
.
Наиболее очевидное решение - переместить точку отражения в центральную точку изображения (250,250)
. (в данном случае центр нашего холста).
<svg width="500" height="500">
...
<image ... transform="scale(-1 1)" transform-origin="250 250"></image>
</svg>
И изменение размера работает точно так же. Вы можете сделать это в 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>
Похожие вопросы
Связанные вопросы
Новые вопросы
svg
Масштабируемая векторная графика (SVG) — это основанный на XML формат двумерной векторной графики, который также можно использовать в HTML. Не добавляйте этот тег только потому, что ваш проект использует SVG. Вместо этого добавьте тег, если ваш вопрос касается SVG или тесно связан с ним, например, как добиться чего-либо с помощью SVG.
transform: scale (-1, 1); transform-origin: center;
- это все, что сейчас нужно.scale
есть ненужный пробел.