SVG — рисунки кодом

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена готовому коду фигур с подробным разбором каждой строки: квадрат, треугольник, домик, цветок, снежинка, звезда, градиенты, фракталы и анимация; для школьников, студентов и веба.

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.


Основы рисования в SVG

SVG (Scalable Vector Graphics) — язык разметки для векторных картинок. Фигура описывается текстом: координаты, цвета, дуги. Браузер масштабирует рисунок без «лесенки» на Retina и на больших экранах. SVG встраивают прямо в HTML, сохраняют в файл .svg, стилизуют через CSS и оживляют анимацией.

С чего начать

Теория по тегу `<svg>` — справочник HTML, раздел SVG.

Обзор формата — основные языки разметки.

Тот же стиль «черепашки», но на Python — примеры Turtle; на JavaScript с холстом — p5.js.

Каркас страницы — HTML + CSS — готовые макеты.

Движение и плавные переходы — CSS-анимации.

Вставьте любой пример из статьи в редактор — предпросмотр обновится через пару секунд. Так быстрее, чем каждый раз сохранять файл на диск.


Как запустить пример за 30 секунд

  1. Скопируйте весь блок (от <!DOCTYPE html> до </html>).
  2. Вставьте в Блокнот / VS Code / Notepad++.
  3. Сохраните как figure.html (расширение .html, не .txt).
  4. Откройте двойным щелчком или перетащите в Chrome / Edge / Firefox.
  5. Пустой экран — проверьте, что скопировали закрывающий </svg> и </html>.
Где Плюсы
Файл .html на диске Работает офлайн после сохранения
Inline в HTML Один файл, CSS и JS рядом с рисунком
Отдельный icon.svg Иконка для сайта, <img src="icon.svg" alt="…">
Редактор выше Быстро править без сохранения на диск

Базовые термины

Термин Простыми словами
viewBox Внутренняя система координат: «логический» холст, который браузер масштабирует под width/height
width, height Размер картинки на экране (px, %, em)
fill Цвет заливки (none — прозрачная внутренность)
stroke Цвет контура
stroke-width Толщина линии
<rect> Прямоугольник
<circle> Круг (cx, cy — центр, r — радиус)
<polygon> Многоугольник по списку точек points="x1,y1 x2,y2 …"
<line> Отрезок от (x1,y1) до (x2,y2)
<path d="…"> Произвольная линия, дуга, кривая Безье
<g> Группа элементов (удобно двигать и вращать вместе)
transform Сдвиг, поворот, масштаб (translate, rotate, scale)

Какую фигуру выбрать

Вы ищете… Пример ниже Идея
Квадрат, прямоугольник Квадрат <rect> или <polygon> из 4 точек
Треугольник Треугольник <polygon> с 3 вершинами
Дом, крыша Домик <rect> + треугольник
Цветок Цветок Круги по окружности или цикл в JS
Снежинка Снежинка Лучи <line> + rotate
Сердце Сердце <path> с кривыми Безье
Звезда, n-угольник Многоугольники Формула углов или готовые points
Шахматная доска Сетка Двойной цикл for
Дерево, фрактал Дерево, Кох Рекурсия в JavaScript
Движение Анимация CSS @keyframes или SMIL

Система координат

В SVG точка (0, 0)левый верхний угол viewBox. Ось X растёт вправо, Y — вниз (как на экране Turtle и в Canvas). Центр холста 200×200: cx="100" cy="100" для круга или transform="translate(100 100)" для группы.

Связь с Turtle: в Python Y часто «вверх», на экране черепашки — как в SVG. В SVG вы сразу задаёте координаты точек, без команд forward и left.

Как работать с примерами

  1. Сначала запустите код как есть — убедитесь, что в браузере появилась картинка.
  2. Меняйте одно значение за раз (width, цвет, координату).
  3. Сломали — верните исходник из статьи.
  4. Готовый SVG вставьте в макет страницы — блок <svg> внутри <body>.
Типичные ошибки новичков
  • Белый экран — забыли закрыть тег </svg> или сохранили файл как .txt.
  • Фигура не видна — fill="none" и нет stroke; или координаты за пределами viewBox.
  • «Квадрат стал прямоугольником» — разные width и height у <rect>.
  • Градиент не работает — url(#id) ссылается на id из другого SVG; <defs> должны быть в том же <svg>.
  • JS не рисует — скрипт выполняется до того, как DOM готов; ставьте <script> в конец <body> или используйте DOMContentLoaded.

Обязательный каркас

Любой статичный рисунок строится по схеме: HTML-страница → тег <svg> → фигуры внутри.

Разбор по строкам.

Фрагмент Смысл
<!DOCTYPE html> Режим HTML5 — браузер рисует страницу предсказуемо
<meta charset="UTF-8"> Кириллица в <title> и aria-label
viewport На телефоне страница не «уменьшенный десктоп»
body &#123; margin: 0 &#125; Убирает белую полоску у края окна
display: grid; place-items: center SVG по центру экрана
min-height: 100dvh Минимум на всю высоту; dvh учитывает панель браузера на телефоне
width="320" height="320" Размер картинки на странице в пикселях
viewBox="0 0 320 320" Логический холст: от (0,0) до (320,320); при равных width и viewBox — 1 unit = 1 px
role="img" + aria-label Скринридер озвучит подпись вместо «пустого» SVG
<!-- здесь фигуры --> Комментарий; браузер его не рисует

Минимальный фрагмент — только SVG без HTML-обёртки (для вставки в готовую страницу):

<svg width="200" height="200" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
  <!-- фигуры -->
</svg>
Атрибут Зачем
xmlns="http://www.w3.org/2000/svg" Обязателен в отдельном файле .svg; в HTML можно опустить
viewBox="0 0 200 200" Если потом увеличите width="400", картинка масштабируется без потери чёткости

Стартовые фигуры

Пять типов, которые чаще всего ищут вместе с Turtle и p5.js: квадрат, треугольник, домик, цветок, снежинка. Дальше — сердце, сетки, фракталы и анимация.


Квадрат на SVG (аналог forward + left в Turtle)

Четыре стороны одинаковой длины. В Turtle вы четыре раза forward(100) и left(90). В SVG проще сказать браузеру: «нарисуй прямоугольник 100×100 в таких координатах».

Разбор:

  • <rect> — один тег вместо четырёх отрезков; браузер сам замыкает контур.
  • x="70" y="70"левый верхний угол квадрата (не центр!).
  • width="100" height="100" — сторона 100 px; для квадрата оба числа одинаковые.
  • fill="none" — внутри прозрачно; виден только контур.
  • stroke="#1e293b" — цвет линии (тёмно-серый).
  • stroke-width="3" — толщина контура 3 px.

Почему x=70, y=70? Холст 240×240. Квадрат 100×100. Чтобы центрировать: (240 − 100) / 2 = 70.

Что изменить: width="150" height="150" и x="45" y="45" — больший квадрат по центру; fill="#93c5fd" — голубая заливка вместо пустоты.

Аналог в Turtle: квадрат forward/left — там четыре команды; здесь одна строка <rect>.

Вариант через <polygon> — удобно, если потом нужно повернуть фигуру через transform="rotate(..)":

<polygon points="70,70 170,70 170,170 70,170"
         fill="none" stroke="#1e293b" stroke-width="3"/>
points Угол квадрата
70,70 левый верхний
170,70 правый верхний
170,170 правый нижний
70,170 левый нижний

Точки перечисляют по порядку обхода — браузер соединяет их линиями и замыкает контур.


Равносторонний треугольник

Три вершины — три пары координат в points. В Turtle: цикл for i in range(3) с left(120).

Разбор:

  • 120,50верхняя вершина по центру холста (x=120 — середина 240).
  • 190,170 и 50,170 — нижние углы; обе на y=170, симметрично относительно центра.
  • fill="#fef08a" — жёлтая заливка.
  • stroke="#ca8a04" — контур темнее заливки — фигура читается на любом фоне.
  • stroke-linejoin="round" — углы слегка скруглены (без «острых иголок» на стыках линий).

Связь с математикой: у равностороннего треугольника все стороны равны; в Turtle поворот между сторонами — 120° (внешний угол).

Что изменить: поднять вершину — 120,30 вместо 120,50 (треугольник выше); fill="none" — только контур, как у квадрата выше.

Аналог в Turtle: треугольник for + left(120).


Домик (стены + крыша + дверь)

Три простые фигуры слоями. Сначала «дальние» части, потом ближние — как в Turtle вы рисуете стены, потом крышу.

Разбор:

Элемент Тег Что задаёт
Стены <rect x="80" y="120" width="100" height="90"> Прямоугольник: левый верх (80,120), ширина 100, высота 90
Крыша <polygon points="60,120 130,60 200,120"> Треугольник: основание на y=120, вершина на y=60
Дверь <rect x="115" y="155" width="30" height="55"> Узкий прямоугольник поверх стен
  • Порядок в файле важен: то, что написано ниже, рисуется поверх (дверь перекрывает стены).
  • Крыша шире стен (60…200 против 80…180) — классический «свес».
  • <!-- стены --> — комментарий для себя; в браузере не виден.

Что изменить: fill="#ef4444" у стен — красный дом; добавьте <circle cx="200" cy="80" r="25" fill="#fef08a"/> — солнце в углу.

Аналог в Turtle: домик left + forward.


Простой цветок из кругов

Шесть лепестков — шесть <circle> вокруг центра. В Turtle: t.circle(30) и t.right(60) шесть раз.

Разбор:

  • <g transform="translate(130 130)">группа с переносом начала координат в центр холста (130 = половина 260). Все cx/cy внутри считаются от центра цветка.
  • cx="50" cy="0" — центр лепестка на расстоянии 50 px вправо от середины.
  • r="22" — радиус лепестка (не диаметр! В SVG у <circle> именно радиус).
  • Остальные лепестки — те же точки на окружности: углы 60°, 120°, 180°, 240°, 300°.
  • Жёлтый <circle cx="0" cy="0" r="18"> рисуется последним — поверх лепестков.

Откуда числа 25 и 43? Для угла 60°: x = 50·cos(60°) ≈ 25, y = 50·sin(60°) ≈ 43. Можно не запоминать — см. вариант с циклом ниже.

Что изменить: r="30" у лепестков — крупнее; добавьте седьмой <circle> с другим cx,cy — эксперимент с числом лепестков.

Аналог в Turtle: красный цветок circle + right(60).


Цветок через цикл JavaScript (без копипаста координат)

Тот же рисунок, но координаты считает цикл — как for i in range(6) в Python.

Разбор по строкам JavaScript:

Строка Смысл
document.getElementById('flower') Находим группу <g id="flower">, куда добавим круги
createElementNS('…svg', 'circle') SVG живёт в своём namespace — обычный createElement может не сработать
deg = i * (360 / petals) Угол i-го лепестка: 0°, 60°, 120°…
Math.cos(rad) / Math.sin(rad) Координаты точки на окружности радиуса orbit
setAttribute('cx', cx) Записываем атрибут так же, как в HTML-разметке
g.appendChild(c) Добавляем круг в SVG-дерево — браузер сразу рисует

Что изменить: petals = 8 и orbit = 55 — цветок с восемью лепестками; fill на #a855f7' — фиолетовый.


Простая снежинка

Восемь лучей из центра. В Turtle: forward(50), backward(50), right(45) в цикле.

Разбор:

  • translate(130 130) — центр снежинки в середине холста.
  • stroke и stroke-width на <g>наследуются всеми <line> внутри (DRY: не повторяем на каждой линии).
  • stroke-linecap="round" — концы лучей скруглены.
  • <line x1="0" y1="-70" x2="0" y2="70"/> — вертикальный луч длиной 140 px через центр; отрицательный Y — вверх от центра.
  • Диагонали: -49 и 49 — это 70 / √2 ≈ 49 (концы на окружности радиуса 70).
  • transform="rotate(45)" — тот же шаблон луча, повёрнутый на 45° вокруг начала группы (центра).

Что изменить: -70-100 — длиннее лучи; только 4 луча — оставьте первые две строки <line>.

Через цикл (8 лучей, как for i in range(8)):

<g transform="translate(130 130)" stroke="#67e8f9" stroke-width="3" id="flakes"></g>
<script>
  const box = document.getElementById('flakes');
  for (let i = 0; i < 8; i++) {
    const line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
    line.setAttribute('x1', 0);
    line.setAttribute('y1', -70);
    line.setAttribute('x2', 0);
    line.setAttribute('y2', 70);
    line.setAttribute('transform', `rotate(${i * 45})`);
    box.appendChild(line);
  }
</script>

i * 45 — поворот 0°, 45°, 90°… — ровно 360° / 8.

Аналог в Turtle: снежинка forward/backward/right.


Сердце

Сложная форма из одного <path>. Команды в атрибуте d читаются как «язык чертежника».

Команды path (мини-шпаргалка):

Буква Название Действие
M x y Move Переместить «перо», не рисуя
C x1 y1, x2 y2, x y Cubic Bezier Кривая к (x,y) с двумя контрольными точками
L x y Line Прямая (в этом примере не используется)
Z Close Замкнуть контур до первой точки

Разбор контура:

  • M 120 200 — старт в нижней точке сердца (острие).
  • Первая C — левая дуга вверх.
  • Вторая C — левый «бугор».
  • Третья C — правый «бугор» (симметрия).
  • Четвёртая C — спуск к острию.
  • Z — линия обратно к M.

Что изменить: fill="#ec4899" — розовое сердце; уберите stroke — только заливка.

Аналог в Turtle: сердце circle + left.


Примеры фигур

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


1. Базовые многоугольники

1.1. Правильный n-угольник

Формула вершин на окружности — обобщение треугольника и шестиугольника.

Разбор функции regularPolygon:

Параметр Смысл
n Число сторон (3 — треугольник, 6 — шестиугольник, 8 — восьмиугольник)
cx, cy Центр фигуры
radius Расстояние от центра до вершины
(i / n) * 2 * Math.PI Угол i-й вершины в радианах (полный оборот 2π)
- Math.PI / 2 Поворот на −90° — чтобы первая вершина была сверху, а не справа
pts.join(' ') Строка для атрибута points: "x1,y1 x2,y2 …"

Что изменить: regularPolygon(5, 150, 150, 100) — пятиугольник; regularPolygon(3, …) — снова треугольник, но через формулу.


1.2. Звезда

Десять точек — чередование «внешнего» и «внутреннего» радиуса.

<svg width="280" height="280" viewBox="0 0 280 280" role="img" aria-label="Звезда">
  <polygon points="140,30 165,110 250,110 182,160 207,240 140,195 73,240 98,160 30,110 115,110"
           fill="#fde047" stroke="#a16207" stroke-width="2"/>
</svg>

Генерация координат (удобно менять число лучей):

function starPoints(cx, cy, outerR, innerR, spikes) {
  const pts = [];
  const step = Math.PI / spikes;
  for (let i = 0; i < 2 * spikes; i++) {
    const r = i % 2 === 0 ? outerR : innerR;
    const a = i * step - Math.PI / 2;
    pts.push(`${cx + r * Math.cos(a)},${cy + r * Math.sin(a)}`);
  }
  return pts.join(' ');
}
// starPoints(140, 140, 110, 45, 5) — пятиконечная звезда

Разбор:

  • i % 2 === 0 ? outerR : innerR — чётные шаги дальше от центра, нечётные ближе — «зубцы» звезды.
  • 2 * spikes итераций — по две точки на каждый луч.

Что изменить: spikes = 6 — шестиконечная звезда; innerR ближе к outerR — «толстая» звезда.


2. Кривые и path

2.1. Спираль Архимеда

Точки по формуле r = a + b·θ; соединяются отрезками <path>.

<svg width="320" height="320" viewBox="-160 -160 320 320">
  <path id="spiral" fill="none" stroke="#2563eb" stroke-width="2"/>
</svg>
<script>
  let d = 'M 0 0';
  for (let deg = 0; deg <= 720; deg += 2) {
    const rad = (deg * Math.PI) / 180;
    const r = 4 + 0.35 * deg;
    d += ` L ${r * Math.cos(rad)} ${r * Math.sin(rad)}`;
  }
  document.getElementById('spiral').setAttribute('d', d);
</script>

Разбор:

  • viewBox="-160 -160 320 320" — центр (0,0) в середине картинки (отрицательные координаты слева и сверху).
  • M 0 0 — старт в центре.
  • L x y — линия к следующей точке спирали.
  • deg <= 720 — два полных оборота (360° × 2).
  • r = 4 + 0.35 * deg — чем больше угол, тем дальше от центра (спираль расширяется).

Что изменить: 0.350.15 — более плотная спираль; 7201080 — три оборота.


2.2. Полярная «роза»

Уравнение r = a·cos(k·θ) в декартовых координатах.

Разбор:

  • k = 5пять лепестков (при нечётном k).
  • Math.cos(k * rad) — радиус «пульсирует» — то ноль, то максимум → лепестки.
  • deg === 0 ? 'M' : 'L' — первая точка Move, остальные Line.
  • ' Z' в конце — замкнуть контур (для заливки можно добавить fill="#fce7f3").

3. Заливки и градиенты

Небо и солнце — типичный учебный пример «как сделать градиент svg».

Разбор:

Элемент Смысл
<defs> Ресурсы «в запасе» — сами не рисуются, пока на них не сослались
linearGradient id="sky" Имя для ссылки url(#sky); id уникален внутри SVG
x1="0" y1="0" x2="0" y2="1" Градиент сверху вниз (y2=1 — нижний край)
<stop offset="0%"> Цвет в начале градиента
fill="url(#sky)" Залить прямоугольник не цветом, а градиентом
radialGradient Круговой градиент — солнце «светится» из центра

Что изменить: поменяйте stop-color — другое небо; r="50" у солнца — больше диск.


4. Сетки и орнаменты

4.1. Шахматная доска (как в Turtle — сетка квадратов)

Двойной цикл — классика урока «вложенные циклы».

Разбор:

  • row и col — номера клетки (0…7), как координаты на доске.
  • col * size — x левого края; row * size — y верхнего края.
  • (row + col) % 2 === 0 — чёрные и белые клетки шахматным порядком (сумма чётная — тёмная).

Аналог в Turtle: шахматная сетка из точек — там dot, здесь квадраты.

Что изменить: size = 20 и цикл до 12 — доска 12×12; цвета #b45309 и #fef3c7 — «деревянная» доска.


4.2. Соты (шестиугольная сетка)

Разбор:

  • hexPoints — 6 вершин шестиугольника; - Math.PI / 6 — «плоская» грань сверху.
  • dx = r * 3 — горизонтальный шаг между центрами сот.
  • row % 2 ? dx / 2 : 0смещение каждого второго ряда (классическая ульевая сетка).

5. Фракталы

5.1. Дерево с рекурсией

Функция branch вызывает саму себя .

Разбор:

Строка Смысл
translate(200 360) «Корень» внизу по центру — дерево растёт вверх
if (depth <= 0) return База рекурсии — без неё бесконечные ветки
y2 = y1 - len * Math.cos(rad) Минус перед cos — в SVG Y вниз, «вверх» это уменьшение y
len * 0.72 Каждая следующая ветка короче — дерево сужается
angle ± 28 Левая и правая ветви от текущей
depth - 1 Счётчик глубины уменьшается на каждом уровне

Что изменить: depth 86 — проще и быстрее; 2835 — более «раскидистое» дерево.


5.2. Снежинка Коха

Рекурсивное замещение отрезка — классический фрактал для школьной олимпиады.

Разбор:

  • depth === 0 — рисуем обычный отрезок M… L….
  • Иначе делим отрезок на три части и вставляем «горб» в середине (треугольник Коха).
  • Три вызова внизу — три стороны равностороннего треугольника → замкнутая снежинка.
  • depth 4 — уже детальная; 5 — тяжелее для слабого ПК.

6. Анимация

6.1. SMIL — вращение без JavaScript

<svg width="200" height="200" viewBox="0 0 200 200">
  <rect x="70" y="70" width="60" height="60" fill="#6366f1">
    <animateTransform attributeName="transform" type="rotate"
      from="0 100 100" to="360 100 100" dur="4s" repeatCount="indefinite"/>
  </rect>
</svg>

Разбор:

Атрибут Смысл
animateTransform Встроенная SVG-анимация (SMIL)
type="rotate" Вращение
from="0 100 100" Старт: 0° вокруг точки (100, 100)
to="360 100 100" Финиш: полный оборот
dur="4s" Один оборот за 4 секунды
repeatCount="indefinite" Бесконечно
SMIL и браузеры

SMIL-анимация работает в Firefox и Safari; в Chrome для SVG она отключена. Для сайта в продакшене используйте CSS-анимации. Для урока и быстрого эксперимента SMIL всё ещё нагляден.


6.2. CSS-анимация inline-SVG (работает в Chrome)

Разбор:

  • class="pulse" на <svg> — CSS анимирует весь SVG как один блок.
  • transform-origin: center — масштаб от центра, а не от угла.
  • @keyframes pulse — 0% и 100% нормальный размер; 50% — чуть больше и прозрачнее.
  • prefers-reduced-motion — уважение настройки «уменьшить движение» в системе.

Что изменить: 2s0.8s — быстрее пульс; scale(1.15)1.3 — сильнее «дыхание».


7. Иконка и символ <use>

Один раз нарисовали звезду — используете много раз (спрайт иконок на сайте).

<svg width="0" height="0" style="position:absolute" aria-hidden="true">
  <symbol id="icon-star" viewBox="0 0 24 24">
    <polygon points="12,2 15,9 22,9 16,14 18,22 12,17 6,22 8,14 2,9 9,9"
             fill="currentColor"/>
  </symbol>
</svg>

<svg width="48" height="48" viewBox="0 0 24 24" style="color:#eab308" role="img" aria-label="Звезда">
  <use href="#icon-star"/>
</svg>
<svg width="32" height="32" viewBox="0 0 24 24" style="color:#64748b" aria-hidden="true">
  <use href="#icon-star"/>
</svg>

Разбор:

  • Первый SVG width="0" height="0"склад символов, на экране не занимает место.
  • <symbol id="icon-star"> — шаблон; viewBox задаёт систему координат иконки.
  • fill="currentColor" — цвет берётся из CSS color родителя.
  • <use href="#icon-star"/> — вставка копии символа; второй SVG задаёт размер 48×48.

8. Экспорт и использование

Задача Действие
Иконка на сайте Сохранить icon.svg, подключить <img src="icon.svg" alt="…">
Стилизация CSS Inline <svg> в HTML — классы на <circle>, <path>
Сжатие файла SVGOMG — убирает лишние пробелы и точки
Визуальный редактор Figma, Inkscape — нарисовать, экспортировать SVG
Python Библиотека svgwrite — генерировать SVG из кода (аналог Turtle, но сразу в файл)

Turtle, p5.js и SVG — что выбрать

Инструмент Где рисуете Лучше для
p5.js Браузер, Canvas Анимация, игры, творческий код
SVG Браузер, файл .svg Иконки, логотипы, диаграммы, масштаб без потерь
CSS-анимации HTML + CSS Кнопки, появление блоков, UI-эффекты

SVG описывает форму, а не пиксели: один и тот же код подходит для favicon 16×16 и для баннера на 4K. На уроке часто идут параллельно: Turtle для логики циклов, SVG для результата в браузере и портфолио.


Типичные ошибки

Симптом Причина Решение
Пустой квадрат fill="none" и нет stroke Добавьте stroke="#000"
Фигура «уехала» за край Координаты вне viewBox Увеличьте viewBox или сдвиньте x/y
Градиент не виден url(#id) из другого SVG <defs> в том же <svg>
<use href="#id"> не работает Старый браузер В HTML5 — href; в XML — xlink:href
Анимация не крутится в Chrome SMIL отключён CSS @keyframesпример выше
JS не добавляет круги Неверный namespace createElementNS('http://www.w3.org/2000/svg', …)

Что дальше