SVG — рисунки кодом
Готовые одностраничные примеры: скопировали HTML в файл, открыли в браузере — картинка уже на экране. Ищете «нарисовать квадрат svg», «svg треугольник код», «svg домик», «svg цветок», «снежинка svg», «svg звезда», «svg анимация» — ниже код с разбором каждой важной строки, как в примерах Turtle и p5.js.
Под каждым блоком — зачем атрибут, как браузер рисует фигуру, типичные ошибки новичков и что поменять для эксперимента.
Основы рисования в SVG
SVG (Scalable Vector Graphics) — язык разметки для векторных картинок. Фигура описывается текстом: координаты, цвета, дуги. Браузер масштабирует рисунок без «лесенки» на Retina и на больших экранах. SVG встраивают прямо в HTML, сохраняют в файл .svg, стилизуют через CSS и оживляют анимацией.
Теория по тегу <svg> — справочник HTML, раздел SVG. Обзор формата — основные языки разметки. Тот же стиль «черепашки», но на Python — примеры Turtle; на JavaScript с холстом — p5.js. Каркас страницы — HTML + CSS — готовые макеты. Движение и плавные переходы — CSS-анимации.
Школьникам — квадрат, домик, снежинка для урока информатики или проекта.
Студентам — иконки, диаграммы, инфографика для лабораторной и портфолио.
Самоучкам — первый векторный рисунок в браузере без Photoshop и без установки Python.
Кто гуглит перед контрольной — короткий рабочий код вместо десяти вкладок с обрывками без пояснений.
Вставьте любой пример из статьи в редактор — предпросмотр обновится через пару секунд. Так быстрее, чем каждый раз сохранять файл на диск.
Как запустить пример за 30 секунд
- Скопируйте весь блок (от
<!DOCTYPE html>до</html>). - Вставьте в Блокнот / VS Code / Notepad++.
- Сохраните как
figure.html(расширение.html, не.txt). - Откройте двойным щелчком или перетащите в Chrome / Edge / Firefox.
- Пустой экран — проверьте, что скопировали закрывающий
</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.
Как работать с примерами
- Сначала запустите код как есть — убедитесь, что в браузере появилась картинка.
- Меняйте одно значение за раз (
width, цвет, координату). - Сломали — верните исходник из статьи.
- Готовый 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>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SVG — рисунок</title>
<style>
body {
margin: 0;
min-height: 100dvh;
display: grid;
place-items: center;
background: #f8fafc;
font-family: system-ui, sans-serif;
}
svg {
background: #fff;
border-radius: 12px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
}
</style>
</head>
<body>
<svg width="320" height="320" viewBox="0 0 320 320" role="img" aria-label="Мой рисунок">
<!-- здесь фигуры -->
</svg>
</body>
</html>
Разбор по строкам.
| Фрагмент | Смысл |
|---|---|
<!DOCTYPE html> | Режим HTML5 — браузер рисует страницу предсказуемо |
<meta charset="UTF-8"> | Кириллица в <title> и aria-label |
viewport | На телефоне страница не «уменьшенный десктоп» |
body { margin: 0 } | Убирает белую полоску у края окна |
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 в таких координатах».
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Квадрат SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #f1f5f9; }
</style>
</head>
<body>
<svg width="240" height="240" viewBox="0 0 240 240" role="img" aria-label="Квадрат">
<rect x="70" y="70" width="100" height="100"
fill="none" stroke="#1e293b" stroke-width="3"/>
</svg>
</body>
</html>
Разбор:
<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).
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Треугольник SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #f1f5f9; }
</style>
</head>
<body>
<svg width="240" height="240" viewBox="0 0 240 240" role="img" aria-label="Равносторонний треугольник">
<polygon points="120,50 190,170 50,170"
fill="#fef08a" stroke="#ca8a04" stroke-width="3"
stroke-linejoin="round"/>
</svg>
</body>
</html>
Разбор:
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 вы рисуете стены, потом крышу.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Домик SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #e0f2fe; }
</style>
</head>
<body>
<svg width="260" height="260" viewBox="0 0 260 260" role="img" aria-label="Домик">
<!-- стены -->
<rect x="80" y="120" width="100" height="90" fill="#fde68a" stroke="#92400e" stroke-width="2"/>
<!-- крыша -->
<polygon points="60,120 130,60 200,120" fill="#ef4444" stroke="#991b1b" stroke-width="2"/>
<!-- дверь -->
<rect x="115" y="155" width="30" height="55" fill="#78350f" stroke="#451a03" stroke-width="1"/>
</svg>
</body>
</html>
Разбор:
| Элемент | Тег | Что задаёт |
|---|---|---|
| Стены | <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) шесть раз.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Цветок SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #fdf2f8; }
</style>
</head>
<body>
<svg width="260" height="260" viewBox="0 0 260 260" role="img" aria-label="Цветок из кругов">
<g transform="translate(130 130)">
<!-- 6 лепестков по кругу радиуса 50 -->
<circle cx="50" cy="0" r="22" fill="#f472b6"/>
<circle cx="25" cy="43" r="22" fill="#f472b6"/>
<circle cx="-25" cy="43" r="22" fill="#f472b6"/>
<circle cx="-50" cy="0" r="22" fill="#f472b6"/>
<circle cx="-25" cy="-43" r="22" fill="#f472b6"/>
<circle cx="25" cy="-43" r="22" fill="#f472b6"/>
<!-- серединка -->
<circle cx="0" cy="0" r="18" fill="#facc15"/>
</g>
</svg>
</body>
</html>
Разбор:
<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.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Цветок SVG + JS</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #fdf2f8; }
</style>
</head>
<body>
<svg width="260" height="260" viewBox="0 0 260 260">
<g transform="translate(130 130)" id="flower"></g>
</svg>
<script>
const g = document.getElementById('flower');
const petals = 6;
const orbit = 50;
const petalR = 22;
for (let i = 0; i < petals; i++) {
const deg = i * (360 / petals);
const rad = (deg * Math.PI) / 180;
const cx = orbit * Math.cos(rad);
const cy = orbit * Math.sin(rad);
const c = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
c.setAttribute('cx', cx);
c.setAttribute('cy', cy);
c.setAttribute('r', petalR);
c.setAttribute('fill', '#f472b6');
g.appendChild(c);
}
const center = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
center.setAttribute('r', 18);
center.setAttribute('fill', '#facc15');
g.appendChild(center);
</script>
</body>
</html>
Разбор по строкам 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) в цикле.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Снежинка SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #0f172a; }
</style>
</head>
<body>
<svg width="260" height="260" viewBox="0 0 260 260" role="img" aria-label="Снежинка">
<g transform="translate(130 130)" stroke="#67e8f9" stroke-width="3" stroke-linecap="round">
<line x1="0" y1="-70" x2="0" y2="70"/>
<line x1="-70" y1="0" x2="70" y2="0"/>
<line x1="-49" y1="-49" x2="49" y2="49"/>
<line x1="49" y1="-49" x2="-49" y2="49"/>
<line x1="0" y1="-70" x2="0" y2="70" transform="rotate(22.5)"/>
<line x1="0" y1="-70" x2="0" y2="70" transform="rotate(45)"/>
<line x1="0" y1="-70" x2="0" y2="70" transform="rotate(67.5)"/>
<line x1="0" y1="-70" x2="0" y2="70" transform="rotate(90)"/>
</g>
</svg>
</body>
</html>
Разбор:
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 читаются как «язык чертежника».
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Сердце SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #fff1f2; }
</style>
</head>
<body>
<svg width="240" height="240" viewBox="0 0 240 240" role="img" aria-label="Сердце">
<path d="M 120 200
C 120 160, 70 130, 70 90
C 70 60, 95 45, 120 65
C 145 45, 170 60, 170 90
C 170 130, 120 160, 120 200 Z"
fill="#ef4444" stroke="#991b1b" stroke-width="2"/>
</svg>
</body>
</html>
Команды 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-угольник
Формула вершин на окружности — обобщение треугольника и шестиугольника.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>n-угольник SVG</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #f8fafc; }
</style>
</head>
<body>
<svg width="300" height="300" viewBox="0 0 300 300" id="stage"></svg>
<script>
function regularPolygon(n, cx, cy, radius) {
const pts = [];
for (let i = 0; i < n; i++) {
const angle = (i / n) * 2 * Math.PI - Math.PI / 2;
pts.push(`${cx + radius * Math.cos(angle)},${cy + radius * Math.sin(angle)}`);
}
return pts.join(' ');
}
const svg = document.getElementById('stage');
const poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
poly.setAttribute('points', regularPolygon(8, 150, 150, 100));
poly.setAttribute('fill', '#c4b5fd');
poly.setAttribute('stroke', '#5b21b6');
poly.setAttribute('stroke-width', '2');
svg.appendChild(poly);
</script>
</body>
</html>
Разбор функции 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.35 → 0.15 — более плотная спираль; 720 → 1080 — три оборота.
2.2. Полярная «роза»
Уравнение r = a·cos(k·θ) в декартовых координатах.
<svg width="320" height="320" viewBox="-160 -160 320 320">
<path id="rose" fill="none" stroke="#db2777" stroke-width="2"/>
</svg>
<script>
const k = 5;
let d = '';
for (let deg = 0; deg <= 360; deg += 1) {
const rad = (deg * Math.PI) / 180;
const r = 100 * Math.cos(k * rad);
const x = r * Math.cos(rad);
const y = r * Math.sin(rad);
d += (deg === 0 ? 'M' : 'L') + ` ${x} ${y}`;
}
document.getElementById('rose').setAttribute('d', d + ' Z');
</script>
Разбор:
k = 5— пять лепестков (при нечётном k).Math.cos(k * rad)— радиус «пульсирует» — то ноль, то максимум → лепестки.deg === 0 ? 'M' : 'L'— первая точка Move, остальные Line.' Z'в конце — замкнуть контур (для заливки можно добавитьfill="#fce7f3").
3. Заливки и градиенты
Небо и солнце — типичный учебный пример «как сделать градиент svg».
<svg width="280" height="200" viewBox="0 0 280 200" role="img" aria-label="Небо и солнце">
<defs>
<linearGradient id="sky" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#38bdf8"/>
<stop offset="100%" stop-color="#1e3a8a"/>
</linearGradient>
<radialGradient id="sun" cx="50%" cy="50%" r="50%">
<stop offset="0%" stop-color="#fef08a"/>
<stop offset="100%" stop-color="#f97316"/>
</radialGradient>
</defs>
<rect width="280" height="200" fill="url(#sky)"/>
<circle cx="220" cy="50" r="35" fill="url(#sun)"/>
</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 — сетка квадратов)
Двойной цикл — классика урока «вложенные циклы».
<svg width="240" height="240" viewBox="0 0 240 240" role="img" aria-label="Шахматная доска">
<g id="board"></g>
<script>
const g = document.getElementById('board');
const size = 30;
for (let row = 0; row < 8; row++) {
for (let col = 0; col < 8; col++) {
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
rect.setAttribute('x', col * size);
rect.setAttribute('y', row * size);
rect.setAttribute('width', size);
rect.setAttribute('height', size);
rect.setAttribute('fill', (row + col) % 2 === 0 ? '#1e293b' : '#f8fafc');
g.appendChild(rect);
}
}
</script>
</svg>
Разбор:
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. Соты (шестиугольная сетка)
<svg width="320" height="280" viewBox="0 0 320 280">
<g id="hex" fill="#fde68a" stroke="#92400e" stroke-width="1"></g>
<script>
function hexPoints(cx, cy, r) {
return Array.from({length: 6}, (_, i) => {
const a = (Math.PI / 3) * i - Math.PI / 6;
return `${cx + r * Math.cos(a)},${cy + r * Math.sin(a)}`;
}).join(' ');
}
const g = document.getElementById('hex');
const r = 28;
const dx = r * 3;
const dy = r * Math.sqrt(3);
for (let row = 0; row < 4; row++) {
for (let col = 0; col < 5; col++) {
const cx = 40 + col * dx + (row % 2 ? dx / 2 : 0);
const cy = 40 + row * dy;
const poly = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
poly.setAttribute('points', hexPoints(cx, cy, r));
g.appendChild(poly);
}
}
</script>
</svg>
Разбор:
hexPoints— 6 вершин шестиугольника;- Math.PI / 6— «плоская» грань сверху.dx = r * 3— горизонтальный шаг между центрами сот.row % 2 ? dx / 2 : 0— смещение каждого второго ряда (классическая ульевая сетка).
5. Фракталы
5.1. Дерево с рекурсией
Функция branch вызывает саму себя — как дерево в Turtle.
<svg width="400" height="400" viewBox="0 0 400 400">
<g transform="translate(200 360)" stroke="#78350f" stroke-width="2" fill="none" id="tree"></g>
<script>
const NS = 'http://www.w3.org/2000/svg';
const g = document.getElementById('tree');
function branch(x1, y1, len, angle, depth) {
if (depth <= 0 || len < 4) return;
const rad = (angle * Math.PI) / 180;
const x2 = x1 + len * Math.sin(rad);
const y2 = y1 - len * Math.cos(rad);
const line = document.createElementNS(NS, 'line');
line.setAttribute('x1', x1);
line.setAttribute('y1', y1);
line.setAttribute('x2', x2);
line.setAttribute('y2', y2);
g.appendChild(line);
branch(x2, y2, len * 0.72, angle - 28, depth - 1);
branch(x2, y2, len * 0.72, angle + 28, depth - 1);
}
branch(0, 0, 90, 0, 8);
</script>
</svg>
Разбор:
| Строка | Смысл |
|---|---|
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 8 → 6 — проще и быстрее; 28 → 35 — более «раскидистое» дерево.
5.2. Снежинка Коха
Рекурсивное замещение отрезка — классический фрактал для школьной олимпиады.
<svg width="320" height="320" viewBox="-160 -140 320 280">
<path id="koch" fill="none" stroke="#0284c7" stroke-width="2"/>
</svg>
<script>
function kochSegment(x1, y1, x2, y2, depth) {
if (depth === 0) return `M ${x1} ${y1} L ${x2} ${y2}`;
const dx = x2 - x1, dy = y2 - y1;
const ax = x1 + dx / 3, ay = y1 + dy / 3;
const bx = x1 + 2 * dx / 3, by = y1 + 2 * dy / 3;
const len = Math.hypot(dx, dy) / 3;
const ang = Math.atan2(dy, dx) - Math.PI / 2;
const px = ax + len * Math.cos(ang + Math.PI / 3);
const py = ay + len * Math.sin(ang + Math.PI / 3);
return [
kochSegment(x1, y1, ax, ay, depth - 1),
kochSegment(ax, ay, px, py, depth - 1),
kochSegment(px, py, bx, by, depth - 1),
kochSegment(bx, by, x2, y2, depth - 1),
].join(' ');
}
const h = 120;
const d = [
kochSegment(-h, 0, h, 0, 4),
kochSegment(h, 0, 0, -h * Math.sqrt(3) / 2, 4),
kochSegment(0, -h * Math.sqrt(3) / 2, -h, 0, 4),
].join(' ');
document.getElementById('koch').setAttribute('d', d);
</script>
Разбор:
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-анимация работает в Firefox и Safari; в Chrome для SVG она отключена. Для сайта в продакшене используйте CSS-анимации. Для урока и быстрого эксперимента SMIL всё ещё нагляден.
6.2. CSS-анимация inline-SVG (работает в Chrome)
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>SVG + CSS</title>
<style>
body { margin: 0; display: grid; place-items: center; min-height: 100dvh; background: #0f172a; }
.pulse { animation: pulse 2s ease-in-out infinite; transform-origin: center; }
@keyframes pulse {
0%, 100% { transform: scale(1); opacity: 1; }
50% { transform: scale(1.15); opacity: 0.85; }
}
@media (prefers-reduced-motion: reduce) {
.pulse { animation: none; }
}
</style>
</head>
<body>
<svg width="200" height="200" viewBox="0 0 200 200" class="pulse" role="img" aria-label="Пульсирующий круг">
<circle cx="100" cy="100" r="60" fill="#22d3ee"/>
</svg>
</body>
</html>
Разбор:
class="pulse"на<svg>— CSS анимирует весь SVG как один блок.transform-origin: center— масштаб от центра, а не от угла.@keyframes pulse— 0% и 100% нормальный размер; 50% — чуть больше и прозрачнее.prefers-reduced-motion— уважение настройки «уменьшить движение» в системе.
Что изменить: 2s → 0.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"— цвет берётся из CSScolorродителя.<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 — что выбрать
| Инструмент | Где рисуете | Лучше для |
|---|---|---|
| Turtle | Окно Python на компьютере | Урок информатики, первые циклы, ЕГЭ-стиль |
| 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', …) |
Что дальше
- Встроить SVG в готовый макет страницы — блок
<svg>внутри<main>. - Оживить UI — CSS-анимации и Tailwind-блоки.
- Те же идеи на Canvas — Canvas 2D и p5.js.
- Черепашья графика на Python — Turtle и глава Turtle в энциклопедии.
См. также
Другие статьи этого же раздела в боковом меню (как на странице "О разделе"). Практическая карта типовых IT-задач: термины, пошаговое внедрение, проверка качества и типичные ошибки. Простой консольный чат на C# — учебное приложение с сокетами: TCP между клиентом и сервером, многопоточность и обмен сообщениями в консоли. Примеры вёрстки на HTML и CSS с разбором: центрирование, Flexbox, Grid, формы, шапка, подвал и адаптив для учебы и портфолио. Перед началом работы обязательно изучите главу Turtle . Галерея 3D-фигур на Panda3D — карточки, куб, пирамида, сфера, сетки и составные сцены; код для локального запуска. Готовые docker-compose.yml с разбором каждой строки — nginx, PostgreSQL, Redis, WordPress, MongoDB. Примеры для школьников и студентов: postgres example, поднять базу локально, app + db. Примеры nginx.conf для статики, reverse proxy, React/Vue SPA, PHP, SSL и балансировки — построчный разбор директив, проверка curl и типичные ошибки для лабораторных и VPS. dockerfile example — 10 готовых Dockerfile с построчным разбором: node, python, golang, react nginx, spring boot, php, dotnet. Для студентов, лабораторных и docker build с нуля. PromQL example — готовые запросы Prometheus и Grafana с построчным разбором: up, rate, node_exporter cpu, memory, disk, http_requests_total, histogram_quantile p99, алерты. Для студентов, лабораторных и devops docker compose. Готовые манифесты Kubernetes с разбором каждой строки — Pod, Deployment, Service, ConfigMap, Secret, Ingress. Примеры для Minikube, kind и kubectl apply. Примеры графиков Matplotlib на Python для школьников и студентов — sin, cos, парабола, столбцы, scatter, гистограмма, подграфики; код с подробным разбором. Примеры pandas на Python для школьников и студентов — DataFrame, фильтрация, groupby, очистка, merge, сводные таблицы и экспорт; код с подробным разбором каждой строки.Готовые решения
Простой консольный чат на CSharp
HTML + CSS — готовые макеты
Примеры фигур Turtle на Python
Примеры фигур Panda3D на Python
Docker Compose — готовые стеки
Nginx — конфиги под задачу
Dockerfile — 10 типовых образов
Prometheus + Grafana — запросы
Kubernetes YAML — минимальные манифесты
Matplotlib — графики
Pandas — типовые операции