SVG: руководство по написанию кода изображений (с примерами)

0
311
views
verstka logo

Хочешь знать больше про веб?

Подпишись на наш телеграм-канал TechRocks WEB-разработка?

×

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

Что ж, хорошие новости: вы можете сделать все это и даже больше, даже не покидая любимый редактор кода и не используя какие-либо сторонние инструменты или библиотеки.

После выхода HTML5 мы можем включать код SVG-изображения в документ HTML. Для этого даже не нужно использовать тег изображения, ссылающийся на отдельный файл. Мы можем встроить код картинки прямо в HTML, потому что синтаксис SVG очень похож на HTML.

Это открывает множество интересных возможностей. Внезапно оказывается, что мы можем получить доступ к частям изображения из JavaScript или установить стиль из CSS. Мы можем анимировать части изображения с помощью JavaScript или сделать его интерактивным. А можно и наоборот — сгенерировать графику из кода.

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

Так как же SVG выглядят изнутри? В этом руководстве мы рассмотрим исходный код нескольких SVG-изображений, чтобы охватить основы.

Тег SVG

Во-первых, мы должны поговорить о самом теге svg. Этот тег содержит элементы изображения и определяет рамку нашей картинки. Он устанавливает внутренний и внешний размер изображения.

Свойства width и height определяют, сколько места изображение занимает в браузере. Также часто применяется свойство viewBox. Оно определяет систему координат для элементов внутри изображения.

Поскольку все эти свойства определяют размер, это может сбивать с толку. Но вы можете считать, что width и height SVG — это внешний размер, а viewBox — внутренний.

Размер, определяемый при помощи width и height, — это то, как остальной HTML представляет изображение и насколько большим оно отображается в браузере. Размер, определяемый viewBox, — это то, как элементы изображения представляют это изображение в целом, когда позиционируют себя внутри него.

В следующем примере у нас есть три SVG с одинаковым содержанием. Элементы circle имеют одинаковые координаты центра и радиус. Но вид их совершенно разный.

В центральном примере размер, определенный при помощи width и height, совпадает с размером, определенным viewBox.

В первом примере мы видим, что происходит, когда width и height меньше. Изображение попросту сжимается, поскольку все координаты и размеры, определенные внутри изображения, все равно равняются по viewBox.

В последнем примере мы видим, что происходит, если viewBox фокусируется только на части изображения. В этом случае объект на картинке становится больше, но размер самого изображения по-прежнему определяется свойствами width и height.

Свойство viewBox также определяет центр системы координат, в которой располагаются элементы изображения.

Первые два числа определяют координаты верхнего левого угла изображения. Значения координат растут вправо и вниз. В этой статье мы будем центрировать системы координат. Значение координат 0,0 всегда будет в центре изображения.

И еще одно. Хотя мы можем встраивать SVG-изображения в HTML-файл, это не означает, что мы можем свободно комбинировать любые теги SVG с любыми тегами HTML.

Тег SVG представляет фрейм изображения. Каждый SVG-элемент должен находиться внутри тега SVG. И наоборот: HTML-теги не могут находиться внутри тега SVG, так что мы не можем взять и вставить в SVG тег div или header. Но не волнуйтесь: вам будут доступны похожие теги.

Создаем елочную игрушку при помощи SVG

Начнем с простенького: с елочного шарика. Мы будем использовать только простые формы: прямоугольник и два круга.

Размещать и стилизовать эти элементы мы будем при помощи атрибутов. Для круга мы определяем позицию центра, и для прямоугольника — верхний левый угол. Эти позиции всегда относительны, они привязываются к системе координат, определенной viewBox.

<html>
  <svg width="200" height="200" viewBox="-100 -100 200 200”>
    <circle cx="0" cy="20" r="70" fill="#D1495B" />

    <circle
      cx="0"
      cy="-75"
      r="12"
      fill="none"
      stroke="#F79257"
      stroke-width="2"
    />

    <rect x="-17.5" y="-65" width="35" height="20" fill="#F79257" />
  </svg>
</html>

Не забывайте: мы сдвинули центр системы координат к середине изображения, при этом значения по оси X растут вправо, а по оси Y — вниз.

У нас также есть атрибуты для стилизации наших форм. В отличие от HTML, для установки цвета фигуры мы не используем свойство background-color. Вместо него применяется атрибут fill («заливка»).

А чтобы задать контур фигуры, у нас есть обводка — stroke и stroke-width. Обратите внимание, что мы используем элемент circle как для отрисовки кольца, так и для отрисовки шарика, только применяем разные атрибуты.

Создаем новогоднюю елочку

Переходим к елке. Всегда пользоваться только простыми фигурами для составления изображений не получится. Самый простой способ нарисовать фигуру произвольной формы — использовать polygon (многоугольник). Здесь мы устанавливаем список точек, связанных прямыми линиями.

<html>
  <svg width="200" height="200" viewBox="-100 -100 200 200">
    <polygon points="0,0 80,120 -80,120" fill="#234236" />
    <polygon points="0,-40 60,60 -60,60" fill="#0C5C4C" />
    <polygon points="0,-80 40,0 -40,0" fill="#38755B" />
    <rect x="-20" y="120" width="40" height="30" fill="brown" />
  </svg>
</html>

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

Честно говоря, это требует толики воображения. Для начала можете попробовать сделать набросок на бумаге, чтобы прикинуть, где что будет. Или можете сделать выстрел наугад и затем подгонять значения, пока не добьетесь желаемого вида.

Создаем пряничного человечка

Переходим к пряникам. Поскольку наш SVG теперь живет внутри HTML-файла, мы можем назначить CSS-классы для каждого тега и переместить некоторые атрибуты в CSS.

Но это касается только атрибутов, связанных с внешним видом. Позиционные атрибуты и атрибуты, определяющие форму, должны остаться в HTML. А вот цвета, контуры и шрифты можно сбросить в CSS.

<svg class="gingerbread" width="200" height="200" viewBox="-100 -100 200 200">
  <circle class="body" cx="0" cy="-50" r="30" />

  <circle class="eye" cx="-12" cy="-55" r="3" />
  <circle class="eye" cx="12" cy="-55" r="3" />
  <rect class="mouth" x="-10" y="-40" width="20" height="5" rx="2" />

  <line class="limb" x1="-40" y1="-10" x2="40" y2="-10" />
  <line class="limb" x1="-25" y1="50" x2="0" y2="-15" />
  <line class="limb" x1="25" y1="50" x2="0" y2="-15" />

  <circle class="button" cx="0" cy="-10" r="5" />
  <circle class="button" cx="0" cy="10" r="5" />
</svg>
.gingerbread .body {
  fill: #cd803d;
}

.gingerbread .eye {
  fill: white;
}

.gingerbread .mouth {
  fill: none;
  stroke: white;
  stroke-width: 2px;
}

.gingerbread .limb {
  stroke: #cd803d;
  stroke-width: 35px;
  stroke-linecap: round;
}

Мы уже знакомы с fill и некоторыми свойствами stroke. Давайте познакомимся с еще одним — stroke-linecap. Этот атрибут управляет способом обводки. С его помощью можно сделать концы линий закругленными.

Обратите внимание, что руки и ноги человека — простые линии. Если мы удалим закругление концов и установим меньшее значение stroke-width, мы это заметим. За счет толщины линии и скругления концов мы придаем линиям вид рук и ног нашей фигурки.

Еще обратите внимание на свойство rx в прямоугольнике. Оно определяет рот человечка. С помощью этого свойства задается радиус x углов прямоугольника и создаются округлые углы. Если вам так привычнее, можете считать, что это border-radius.

Создаем звезду

Переходим к звездочке. Звезда — простая форма, так что мы можем определить ее при помощи нескольких многоугольников (polygon), задавая каждую точку отдельно. Но для этого нам нужно знать все координаты.

Вместо этого мы можем просто определить один луч звезды как группу, а затем повторить ее пять раз с поворотом, чтобы получить форму звезды. Для установки поворота используется атрибут transform.

<svg width="200" height="200" viewBox="-100 -100 200 200">      
  <g transform="translate(0 5)">
    <g>
      <polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
      <polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
    </g>
    <g transform="rotate(72)">
      <polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
      <polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
    </g>
    <g transform="rotate(-72)">
      <polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
      <polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
    </g>
    <g transform="rotate(144)">
      <polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
      <polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
    </g>
    <g transform="rotate(-144)">
      <polygon points="0,0 36,-50 0,-100" fill="#EDD8B7" />
      <polygon points="0,0 -36,-50 0,-100" fill="#E5C39C" />
    </g>
  </g>
</svg>

В этом примере каждый луч состоит из двух многоугольников. Они должны вращаться вместе, поэтому мы группируем их при помощи тега g, а затем применяем rotate к обоим сразу.

Можете считать, что тег g — что-то вроде div в HTML. Сам по себе он ничего не представляет. Но он может содержать другие элементы и атрибуты, определенные для группы и применяемые для всех его потомков.

Группы могут быть встроенными. При помощи внешней группы мы translate (перемещаем) всю звезду на 5 юнитов вниз.

Создаем снежинку

Группирование элементов — отличный прием, но нам приходится повторять одинаковый код для каждого луча пять раз.

Вместо многочисленных повторов кода можно создать определение для фигуры и использовать ее заново, обращаясь по id. Здесь мы определяем луч снежинки, а затем используем его шесть раз с разными поворотами.

<svg width="200" height="200" viewBox="-100 -100 200 200">
  <defs>
    <path
      id="branch"
      d="
        M 0 0 L 0 -90
        M 0 -20 L 20 -34
        M 0 -20 L -20 -34
        M 0 -40 L 20 -54
        M 0 -40 L -20 -54
        M 0 -60 L 20 -74
        M 0 -60 L -20 -74"
      stroke="#E5C39C"
      stroke-width="5"
    />
  </defs>

  <use href="#branch" />
  <use href="#branch" transform="rotate(60)" />
  <use href="#branch" transform="rotate(120)" />
  <use href="#branch" transform="rotate(180)" />
  <use href="#branch" transform="rotate(240)" />
  <use href="#branch" transform="rotate(300)" />
</svg>

Луч определен как path. Вообще, path («путь») — самый мощный тег SVG. С его помощью можно определить очень много всего, и если вы откроете любой SVG-файл, вы увидите практически одни path.

Форма path определена атрибутом d. Здесь мы определяем несколько команд рисования. Команда всегда начинается с буквы, определяющей тип команды, и заканчивается координатами.

У нас всего две простые команды: «сдвинуть к…» (move to, M) и «провести линию к…» (line to, L). Команда move to перемещает курсор к определенной точке без рисования линии, а команда line to рисует ровную линию из предыдущей точки.

Любая команда всегда продолжает предыдущую, поэтому при рисовании линии мы определяем только конечную точку. Начальной точкой будет конечная точка предыдущей команды.

Этот path немного необычен, потому что в нем есть несколько команд move to для отрисовки главного луча и такой же path для отрисовки боковых.

Создаем волнистую елочку

Элемент path проявляет свою мощь на полную силу, когда мы начинаем использовать кривые. Например, квадратичную кривую Безье, которая определяет не только конечную точку сегмента, но и контрольную точку. Контрольная точка — это невидимые координаты, в сторону которых линия искривляется. При этом искривленная линия самой контрольной точки не касается.

<svg width="200" height="400" viewBox="-100 -200 200 400">
  <path
    d="
      M 0 -80
      Q 5 -75 0 -70
      Q -10 -65 0 -60
      Q 15 -55 0 -50
      Q -20 -45 0 -40
      Q 25 -35 0 -30
      Q -30 -25 0 -20
      Q 35 -15 0 -10
      Q -40 -5 0 0
      Q 45 5 0 10
      Q -50 15 0 20
      Q 55 25 0 30
      Q -60 35 0 40
      Q 65 45 0 50
      Q -70 55 0 60
      Q 75 65 0 70
      Q -80 75 0 80
      Q 85 85 0 90
      Q -90 95 0 100
      Q 95 105 0 110
      Q -100 115 0 120
      L 0 140
      L 20 140
      L -20 140"
    fill="none"
    stroke="#0C5C4C"
    stroke-width="5"
  />
</svg>

Здесь у нас серия квадратичных кривых Безье (Q), в которых контрольная точка все удаляется и удаляется от центра дерева по мере того как path опускается вниз.

Создаем колокольчик

Хотя квадратичная кривая Безье (Q) отлично подходит для искривления линий, часто она недостаточно гибка.

А вот в кубической кривой Безье (C) у нас появляется не одна контрольная точка, а две. Первая устанавливает начальное направление кривой, а вторая определяет, с какой стороны кривая должна попасть в свою конечную точку.

Если эти направления совпадают с направлениями линии до и после искривления, мы получаем плавный переход между сегментами пути.

В следующем примере мы создаем форму колокольчика, используя и квадратичные, и кубические кривые Безье.

Низ колокольчика определяется прямыми линиями. Затем начинается квадратичная кривая Безье (формирует изгиб стенки колокольчика), которая переходит в кубическую (для формирования купола). Затем мы достигаем нижней части, где идет еще одна квадратичная кривая.

Итоги

То, что находится под капотом SVG, поначалу кажется непонятным. Куча координат, буквы и странные параметры. Но когда вы разберетесь в основах, вы сможете использовать SVG-изображения и писать код для них.

Эта статья — лишь вступление. Если добавить к SVG еще и JavaScript, мы выйдем на качественно новый уровень.

Если хотите посмотреть больше примеров создания SVG-изображений при помощи кода, вот вам видео:

Перевод статьи «SVG Tutorial – How to Code Images with 7 Examples».

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here