SVG viewBox и координаты в Python

Краткий ответ: Чтобы управлять координатами SVG в Python, загрузите или создайте SVGDocument и задайте width, height и viewBox на корневом SVG-элементе с set_attribute(). width и height задают видимый размер вывода. viewBox выбирает, какой координатный прямоугольник показывать, а SVG масштабирует эту систему координат вверх или вниз, чтобы заполнить область просмотра.

1from aspose.svg import SVGDocument
2
3with SVGDocument() as document:
4    svg = document.root_element
5    svg.set_attribute("width", "300")
6    svg.set_attribute("height", "150")
7    svg.set_attribute("viewBox", "0 0 100 50")
8    document.save("viewbox.svg")

В этой статье вы узнаете, как:

Проще всего думать о viewBox, отделяя рисунок от места, где он показывается. SVG-холст – это координатное пространство, где размещаются фигуры. Область просмотра – это видимая область вывода, обычно заданная width и height. viewBox говорит: «покажи этот прямоугольник SVG-холста внутри области просмотра, затем масштабируй его так, чтобы он заполнил эту область».

Атрибут viewBox имеет четыре значения: min-x, min-y, width и height. Например, viewBox="0 0 100 50" означает: начать просмотр с координаты (0, 0), показать 100 координатных единиц по горизонтали и 50 координатных единиц по вертикали. Если область просмотра равна 300x150, эта система координат 100x50 увеличивается в три раза, чтобы заполнить видимую область. Отрисованный размер также может быть 600x300 или любым другим пропорциональным размером, и те же координаты снова будут масштабированы под него.

Основы viewBox

АтрибутПримерЗначение
width300Видимая ширина вывода, например 300 экранных пикселей или CSS-единиц
height150Видимая высота вывода
viewBox0 0 100 50Координатный прямоугольник, который масштабируется для заполнения области просмотра
preserveAspectRatioxMidYMid meetКак графика выравнивается и масштабируется, когда пропорции не совпадают

Пользовательская система координат – это просто система координат, которую используют фигуры после применения viewBox. Если у прямоугольника x="10" и width="80", эти значения измеряются в единицах viewBox, а не напрямую в экранных пикселях. При width="300" height="150" viewBox="0 0 100 50" SVG увеличивает пользовательскую систему координат: одна единица viewBox становится 3 отрисованными единицами в обоих направлениях. Если бы viewBox был больше области просмотра, тот же механизм уменьшал бы рисунок.

Как задать SVG viewBox в Python

Используйте этот рабочий процесс, когда генерируемой SVG-графике нужны предсказуемые координаты и понятная видимая область:

  1. Создайте или загрузите SVGDocument.
  2. Получите корневой SVG-элемент из document.root_element.
  3. Задайте корневые атрибуты, такие как width, height и viewBox, с set_attribute().
  4. Добавьте или обновите фигуры, используя координаты, которые попадают внутрь прямоугольника viewBox.
  5. Сохраните SVG с document.save() и проверьте, что графика не обрезана.

Увеличить SVG-графику с помощью меньшего viewBox

Распространенный паттерн – сохранить простые координаты рисования, но отрисовать изображение крупнее. Следующий пример использует область просмотра 300x150 и viewBox="0 0 100 50", затем рисует прямоугольник в координатах viewBox. Прямоугольник задан как 80x30 координатных единиц, но отображается как 240x90 отрисованных единиц, потому что область просмотра в три раза больше координатного прямоугольника viewBox в обоих направлениях.

 1import os
 2from aspose.svg import SVGDocument
 3
 4SVG_NS = "http://www.w3.org/2000/svg"
 5
 6output_folder = "output/"
 7output_path = os.path.join(output_folder, "svg-viewbox-fixed.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument() as document:
11    svg = document.root_element
12    svg.set_attribute("width", "300")
13    svg.set_attribute("height", "150")
14    svg.set_attribute("viewBox", "0 0 100 50")
15
16    rect = document.create_element_ns(SVG_NS, "rect")
17    rect.set_attribute("x", "10")
18    rect.set_attribute("y", "10")
19    rect.set_attribute("width", "80")
20    rect.set_attribute("height", "30")
21    rect.set_attribute("rx", "4")
22    rect.set_attribute("fill", "#2e86de")
23    svg.append_child(rect)
24
25    document.save(output_path)

Вывод сохраняет пропорции прямоугольника, потому что пропорция области просмотра 300:150 совпадает с пропорцией viewBox 100:50. SVG увеличивает пользовательскую систему координат с одинаковым коэффициентом по осям x и y, поэтому прямоугольник становится больше на экране, но сохраняет пропорции. На практике это позволяет проектировать иконку, график или диаграмму в удобных маленьких числах и выводить их в большем размере без переписывания каждой координаты.

Иллюстрация сравнивает один и тот же прямоугольник в одной и той же отрисованной области просмотра 300x150. Часть (a) использует viewBox="0 0 300 150", поэтому одна координатная единица соответствует одной отрисованной единице, и прямоугольник 80x30 остается маленьким. Часть (b) использует viewBox="0 0 100 50", поэтому SVG увеличивает меньшую систему координат в три раза, чтобы заполнить ту же область просмотра. Значения в коде для прямоугольника те же, но он выглядит намного крупнее.

Сравнение SVG viewBox, где (a) использует viewBox 0 0 300 150 и показывает маленький прямоугольник, а (b) использует viewBox 0 0 100 50 и показывает тот же прямоугольник увеличенным

Сместить видимую координатную область

Первые два значения viewBox могут быть отрицательными или ненулевыми. Они не перемещают отдельную фигуру. Они перемещают видимое координатное окно по SVG-холсту. Это полезно, когда генерируемая графика использует координаты вокруг центральной точки или когда нужно пространство вокруг фигуры, координаты которой пересекают ноль.

В следующем примере viewBox="-60 -60 120 120" помещает координату (0, 0) в середину квадратной области просмотра. Видимая область начинается с x=-60, y=-60, затем продолжается на 120 единиц вправо и 120 единиц вниз.

 1import os
 2from aspose.svg import SVGDocument
 3
 4namespace_uri = "http://www.w3.org/2000/svg"
 5
 6output_folder = "output/"
 7output_path = os.path.join(output_folder, "svg-viewbox-shifted.svg")
 8os.makedirs(output_folder, exist_ok=True)
 9
10with SVGDocument() as document:
11    svg = document.root_element
12    svg.set_attribute("width", "240")
13    svg.set_attribute("height", "240")
14    svg.set_attribute("viewBox", "-60 -60 120 120")
15
16    x_axis = document.create_element_ns(namespace_uri, "line")
17    x_axis.set_attribute("x1", "-50")
18    x_axis.set_attribute("y1", "0")
19    x_axis.set_attribute("x2", "50")
20    x_axis.set_attribute("y2", "0")
21    x_axis.set_attribute("stroke", "#0071aa")
22    x_axis.set_attribute("stroke-width", "3")
23    svg.append_child(x_axis)
24
25    marker = document.create_element_ns(namespace_uri, "circle")
26    marker.set_attribute("cx", "0")
27    marker.set_attribute("cy", "0")
28    marker.set_attribute("r", "25")
29    marker.set_attribute("fill", "#00aaaa")
30    marker.set_attribute("stroke", "#006863")
31    marker.set_attribute("stroke-width", "5")
32    svg.append_child(marker)
33
34    document.save(output_path)

Здесь центр видимой области – координата (0, 0). Горизонтальная ось проходит от x=-50 до x=50, а круг центрирован точно в начале координат. Этот паттерн полезен для иконок, маркеров, полярных диаграмм и генерируемых символов, которые удобнее рассчитывать вокруг центра.

Иллюстрация сравнивает два способа показать круг с центром в координате (0, 0). Часть (a) использует viewBox="0 0 240 240", поэтому (0, 0) находится в левом верхнем углу и большая часть круга обрезана за пределами области просмотра. Часть (b) использует viewBox="-60 -60 120 120", поэтому видимая координатная область начинается в (-60, -60) и заканчивается в (60, 60). Это помещает (0, 0) в центр области просмотра и делает круг полностью видимым.

Сравнение SVG viewBox, где (a) использует viewBox 0 0 240 240 и обрезает круг с центром 0 0, а (b) использует viewBox -60 -60 120 120 и центрирует круг

Распространенные ошибки и исправления

ПроблемаПочему это происходитИсправление
SVG выглядит пустымВсе видимые элементы находятся за пределами координатного прямоугольника, заданного viewBox. Например, круг с cx="200" не виден в viewBox="0 0 100 100".Переместите элементы внутрь диапазона viewBox или увеличьте значения width, height, min-x и min-y у viewBox так, чтобы элементы попали в видимую координатную область.
Графика обрезанаЭлемент только частично находится внутри viewBox. SVG показывает часть, попадающую в видимый координатный прямоугольник, и скрывает остальное.Расширьте viewBox или сдвиньте его через min-x и min-y, чтобы вся фигура поместилась в видимую область.
Графика выглядит больше ожидаемогоШирина и высота viewBox меньше области просмотра, что создает эффект приближения.Используйте больший viewBox или уменьшите отрисованные width и height.
Графика выглядит меньше ожидаемогоШирина и высота viewBox больше области просмотра, что создает эффект отдаления.Используйте меньший viewBox или увеличьте отрисованные width и height.
Вывод выглядит растянутымПропорции области просмотра не совпадают с пропорциями viewBox. Например, 300x150 и 100x100 имеют разные пропорции.Используйте совпадающие пропорции или осознанно задайте preserveAspectRatio.
Координатами трудно управлятьviewBox не совпадает с тем, как вы представляете рисунок.Выберите удобную систему координат, например 0 0 100 100 для иконок или координаты от отрицательных к положительным значениям для симметричных фигур.
stroke обрезается у краяСама фигура помещается, но stroke рисуется наполовину внутри и наполовину снаружи границы фигуры. Круг, касающийся края viewBox, может потерять часть контура.Оставьте дополнительный отступ внутри viewBox или сдвиньте фигуру от края минимум на половину stroke-width.

FAQ

Что означает SVG viewBox?

viewBox определяет, какую прямоугольную координатную область SVG-холста нужно показать внутри SVG-области просмотра. В viewBox="0 0 100 50" видимая область начинается в (0, 0) и включает 100 единиц по горизонтали и 50 единиц вниз. Затем SVG масштабирует эту область 100x50 вверх или вниз, чтобы заполнить отрисованную область просмотра.

В чем разница между область просмотра и viewBox?

Область просмотра – это видимая область вывода, заданная width и height. viewBox – это координатный прямоугольник, который сопоставляется с этой видимой областью. Более подробное объяснение теории SVG смотрите в SVG Coordinate Systems and Units и SVG viewBox.

Меняют ли width и height SVG-координаты?

Нет. width и height управляют размером отрисованной области просмотра. viewBox управляет координатной областью, которую используют фигуры, текст и пути. Круг с cx="50" все равно использует координату 50, даже если SVG отрисован шириной 100 или 1000 пикселей.

Почему меньший `viewBox` делает SVG-графику крупнее?

Меньший viewBox показывает меньшую координатную область и вписывает ее в ту же область просмотра. Например, вписывание viewBox="0 0 50 50" в область просмотра 200x200 заставляет каждую координатную единицу занимать больше отрисованного пространства в 4 раза, чем при viewBox="0 0 200 200" в той же области просмотра.

Почему больший `viewBox` делает SVG-графику меньше?

Больший viewBox показывает больше координатного пространства внутри той же области просмотра. Рендерер должен уместить большую область холста в тот же видимый размер, поэтому каждая координатная единица занимает меньше отрисованного пространства, и графика кажется меньше.

Могут ли значения `viewBox` быть отрицательными?

Да. Отрицательные значения min-x или min-y полезны, когда рисунок строится вокруг центральной точки или когда графике нужен видимый отступ вокруг координат около нуля.

Связанные статьи