Яндекс.Метрика

Дизайн-журнал №1. Актуальная информация для дизайнеров, веб дизайнеров, программистов и разработчиков сайтов.

Создание рекурсивного дизайна SVG, часть первая

7 июля 2017 | Опубликовано в css | 1 Комментарий »

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

 

Основы

Давайте начнем с простого узора шестиугольника, у которого все шесть углов соединены с помощью линий с противоположными углами:


Изображение 1: Простой узор SVG

Так как эта структура будет многократно использоваться в конечной конструкции, она создается группой внутри раздела <defs> SVG, и инструмент клонирования <use> используется для размещения первой итерации конструкции:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 750 750">
    <defs>
        <g id="hex">
            <polygon points="229.3,627.5 83.6,375.5 229.3,123.5 520.7,123.5 666.4,375.5 520.7,627.5" />
            <line x1="229.3" y1="123.5" x2="520.7" y2="627.5"/>
            <line x1="666" y1="375.5" x2="84" y2="375.5"/>
            <line x1="520.7" y1="123.5" x2="229.3" y2="627.5"/>
        </g>
    </defs>
    <use xlink:href="#hex" />
</svg>

Стили для SVG задаются в коде CSS:

polygon, line { fill: none; stroke: #32679D; stroke-width: 7px; }

После этого создадим копию узора, но вдвое меньшего размера, с центром, находящимся в том же месте. Вот строка кода, которая создает смасштабированный элемент <use>:

<use xlink:href="#hex" transform="scale(.5)" />

Но этот код не работает так, как можно ожидать:


Изображение 2: Результат обычного масштабируемого копирования SVG 

В отличие от элементов HTML с применением трансформаций CSS SVG по умолчанию масштабируется не относительно центра. Вместо этого узор масштабируется относительно левого верхнего угла. Чтобы решить эту проблему, можно использовать следующую формулу для записи трансформации SVG: 

translate(-centerX * (factor — 1), -centerY * (factor — 1)) scale(factor) , где  centerX – координата центра по оси X, centerY – координата центра по оси Y,  factor – значение масштабирования. 

Центр этой конструкции находится ровно в центре SVG: 375 375. Следовательно, чтобы смасштабировать вдвое уменьшенную копию конструкции относительно центра, нужно добавить следующие значения: 

translate(-375 * (0.5 — 1), -375 * (0.5 — 1)) scale(0.5) 

Что даст следующую запись:

<use xlink:href="#hex" transform="translate(187.5, 187.5) scale(.5)" />

И создаст результат ниже:


Изображение 3: Правильно трансформированный смасштабированный SVG

Остается проблема, как минимум для этой конструкции, — толщина линии масштабируется вместе с конструкцией. Это, к счастью, легко решается с помощью задания значения свойства CSS non-scaling-stroke (не изменять масштаб линии), о котором можно прочитать подробней по ссылке выше, или добавления атрибута SVG:

polygon, line {
    fill: none; stroke: #32679D; stroke-width: 7px;
    vector-effect: non-scaling-stroke;
}

И получаем результат:


Изображение 4:  Трансформированный смасштабированный SVG с неизменным масштабом линий

После этого уже довольно просто передвигать и масштабировать другие копии основного узора для создания сложной конструкции.

Варианты

Одним из преимуществ использования базового узора в SVG является то, что любые изменения в нем отразятся на всех его копиях. Так что можно повернуть исходный узор в разделе <defs> следующим образом:

<g id="hex" transform="rotate(30 375 375)">

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

Автор урока Dudley Storey

Перевод — Дежурка

Смотрите также:




Комментарии

[an error occurred while processing the directive]


[an error occurred while processing the directive]