Редактируемая система SVG-иконок | Vue.js
Простой пример
Есть множество способов создания системы SVG-иконок (SVG Icon System), но один из способов, который использует возможности Vue — создание редактируемых встроенных иконок в виде компонентов. Некоторые преимущества подобного подхода:
- Их легко редактировать «на лету»
- Они анимируются
- Можно использовать обычные входные параметры, со значениями по умолчанию, для сохранения стандартного размера или изменения по необходимости
- Они встраиваемые, поэтому HTTP-запросы не требуются
- Они могут быть доступны динамически
Создадим сначала каталог для всех иконок и назовём каждую в едином стиле, чтобы облегчить их поиск:
components/icons/IconBox.vuecomponents/icons/IconCalendar.vuecomponents/icons/IconEnvelope.vue
Вот репозиторий с примером для начала работы, где можно увидеть готовую настройку: https://github.
com/sdras/vue-sample-svg-icons/ (opens new window)
Теперь создадим компонент базовой иконки (IconBase.vue), который использует слот:
<template>
<svg xmlns="http://www.w3.org/2000/svg"
:width="width"
:height="height"
viewBox="0 0 18 18"
:aria-labelledby="iconName"
role="presentation"
>
<title
:id="iconName"
lang="en"
>
{{ iconName }} icon
</title>
<g :fill="iconColor">
<slot />
</g>
</svg>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Можно использовать эту базовую иконку «как есть», но необходимо обновлять в зависимости от viewBox показываемой иконки. В базовом компоненте определяем входными параметрами width, height, iconColor и имя иконки, чтобы динамически их обновлять.
Имя используем для содержимого <title> и для id для лучшей доступности.
Секция script станет выглядеть следующим образом: некоторые значения останутся по умолчанию, поэтому иконка будет отрисовываться всегда одинаково, пока не изменим её:
export default {
props: {
iconName: {
type: String,
default: 'box'
},
width: {
type: [Number, String],
default: 18
},
height: {
type: [Number, String],
default: 18
},
iconColor: {
type: String,
default: 'currentColor'
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Заданное по умолчанию свойство currentColor используется для цвета иконки и заставит её наследовать цвет текста. Но можно передать и другой цвет входным параметром, если захотим.
Компонент можно использовать следующим образом, передавая в слот единственным содержимым , содержащим пути внутри иконок:
vue
<icon-base icon-name="write"> <icon-write /> </icon-base>
1
2
3
Теперь если потребуется несколько иконок с разными размерами — всё очень просто:
<p>
<!-- можно передавать меньшую `width` и `height` -->
<icon-base
icon-name="write"
>
<icon-write />
</icon-base>
<!-- или использовать значение по умолчанию, равное 18 -->
<icon-base icon-name="write"><icon-write /></icon-base>
<!-- или сделать её немного больше :) -->
<icon-base
icon-name="write"
>
<icon-write />
</icon-base>
</p>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Анимируемые иконки
Хранение иконок в компонентах очень удобно если потребуется их анимировать, особенно при взаимодействиях.
Встроенные SVG-иконки имеют самую высокую поддержку для какого-либо взаимодействия. Вот простой пример иконки, которая анимируется при клике:
<template>
<svg
@click="startScissors"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
aria-labelledby="scissors"
role="presentation"
>
<title
lang="en"
>
Анимированная иконка с ножницами
</title>
<path
fill="#fff"
d="M0 0h200v100H0z"
/>
<g ref="leftscissor">
<path d="M..."/>
...
</g>
<g ref="rightscissor">
<path d="M..."/>
...
</g>
</svg>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
31
import { TweenMax, Sine } from 'gsap'
export default {
methods: {
startScissors() {
this.
scissorAnim(this.$refs.rightscissor, 30)
this.scissorAnim(this.$refs.leftscissor, -30)
},
scissorAnim(el, rot) {
TweenMax.to(el, 0.25, {
rotation: rot,
repeat: 3,
yoyo: true,
svgOrigin: '50 45',
ease: Sine.easeInOut
})
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Используем refs для групп элементов, которые будем перемещать. Также, так как обе стороны ножницы должны перемещаться вместе, создаём функцию, которую повторно используем при обращении к . Использование библиотеки GreenSock помогает разрешить поддержку анимации и проблемы с transform-origin во всех браузерах.
See the Pen Editable SVG Icon System: Animated icon
by Vue (@Vue)
on CodePen.
Довольно легко сделано! И легко обновлять «на лету».
Больше анимационных примеров можно посмотреть в репозитории (opens new window)
Дополнительные замечания
Дизайнеры могут поменять своё мнение, требования к продукту измениться. Сохранение всей логики системы иконок в одном базовом компоненте обеспечит возможность быстрого обновления всех иконок по всему приложению. Даже при использовании загрузчика для иконок, некоторые ситуации могут потребовать пересоздания или редактирования каждой SVG-иконки при глобальных изменениях. Этот метод поможет сэкономить время и уменьшить боль.
Когда не следует этого делать
Подобная система SVG-иконок действительно полезна, когда есть несколько иконок, которые используются по-разному на всём сайте. Но если дублируете одну и ту же иконку много раз на одной странице (например иконку удаления во всех строках гигантской таблицы), может имеет больше смысла сделать спрайты, скомпилированные в лист, а затем использовать теги <use> для их загрузки.
Альтернативные варианты
Другие инструменты для помощи в управлении SVG-иконками включают:
- svg-sprite-loader (opens new window)
- svgo-loader (opens new window)
Эти инструменты собирают SVG-иконки на этапе компиляции, что добавляет сложности для редактирования во время выполнения, потому что теги <use> могут иметь странные баги с кроссбраузерностью при выполнении чего-то сложного. Они также оставляют с двумя вложенными свойствами viewBox, а значит и двумя системами координат. Это делает реализацию несколько сложнее.
Нативный способ покрасить SVG-иконки / Хабр
Когда вам нужна возможность менять цвет иконок через CSS, что вы делаете? Вариантов не так много.
Обычно используются либо шрифты иконок, либо исходный код SVG скачивается и вставляется в HTML вручную. Шрифт нужно оптимизировать, иначе пользователь загрузит разом все иконки без надобности. Работа с исходным кодом требует тяжелых DOM-операций и потенциально опасна.
Чтобы защититься от вредоносного кода SVG нужно «почистить». Встроенный в Angular санитайзер, к примеру, не работает с SVG и превращает их в пустую строку. Можно воспользоваться проверенным инструментомDOMPurify и подключить его с помощью нашей библиотеки ng-dompurify, о чем я подробно рассказывал.
Давайте посмотрим на еще один способ, доступный в современных браузерах, — тэг USE.
Чем нам полезен USE?
Этот тэг задуман для переиспользования символов и целых SVG-блоков на странице. Но в современных браузерах (прости, IE) он может даже доставать внешние ресурсы!
Внешние SVG должны быть на том же домене, так что CDN не подойдет. Пока.
Это позволяет нативным образом вставить SVG в Shadow DOM, почти как тэг с атрибутом src, только с возможностью использовать CSS.
И оно даже само работает с кэшем! Но нужно слегка подготовить иконки. Вот что надо сделать:
Сначала в каждой иконке нужно сделать символ с уникальным id и переместить viewBox в него.
Затем надо назначить fill (или stroke) на currentColor, чтобы потом использовать CSS-правило color для задания цвета. Можно также задать эти атрибуты в inherit
Когда наши иконки подготовлены, остается только скинуть их в папку assets и использовать:
Компонент именованных иконок для Angular
Писать путь и обращаться к символу каждый раз утомительно. Давайте сделаем Angular-компонент, который будет находить иконки по имени. С помощью Dependency Injection это сделать очень просто.
Нам понадобится токен для предоставления пути до всех наших иконок и простой компонент.
Он будет формировать href исходя из имени и заданного пути. Мы даже можем повесить его на нативный SVG с помощью селектора: так мы вынесем наружу заботу о размере.
Надо иметь в виду, что Safari до 12.1 поддерживает только устаревший синтаксис xlink:href. Так что лучше использовать оба варианта.
Сделаем stroke и fill прозрачными для использования нескольких цветов в CSS:
Живой пример: stackblitz.com/edit/angular-colored-svg
Заключение
У этого подхода есть ограничения — отсутствие поддержки IE и кросс-доменности. Однако, если они для вас не критичны, данное решение может стать хорошей альтернативой другим способам.
Вам не придется включать иконки в бандл приложения или скачивать их запросами. Вы можете положиться на кэш для ускорения загрузки, а отсутствие DOM-операций делает этот подход быстрее и безопаснее ручной вставки исходников.
Всем ярких решений!
Страница подписки FreeIcons
ЗНАЧКИ В ВЕКТОРНОМ ФОРМАТЕ
Коммуникабельные, презентабельные и сделанные на заказ значки предоставляются в векторном формате, который бросается в глаза зрителю как в SVG, так и в Al.
ПРОФЕССИОНАЛЬНЫЙ
ЛИЦЕНЗИОННЫЙПраво собственности на значок должно быть передано вам на законных основаниях через стандартную договорную лицензию. Он позволяет использовать иконки в коммерческих целях.
ПЕРЕНОС НЕИСПОЛЬЗУЕМЫХ ЗАГРУЗОК
Все ваши неиспользованные загрузки значков переносятся на следующий месяц подписки, что позволяет избежать потерь.
Права
ЗарезервированоВсе права принадлежат исключительно вам, и они могут использоваться в соответствии с вашими требованиями, будь то для личного или коммерческого использования.
Часто задаваемые вопросы
Обязательна ли подписка или я могу выбрать Pay as you go?
В зависимости от ваших требований доступны как подписка, так и оплата по мере использования, вы можете выбрать оплату по мере использования и начать с минимального баланса в 10 долларов, начать загрузку значков и продолжить, добавляя в кредит по мере необходимости, или вы можете пойти за подписку.
Могу ли я изменить или отменить свой план подписки Pro в любое время?
Да, вы можете обновить, понизить или отменить план подписки Pro в любое время в настройках своей учетной записи. Обновление вступит в силу сразу, а переход на более раннюю версию вступит в силу со следующего расчетного периода. При отмене подписки вы можете загружать значки до последнего дня цикла платной подписки. Когда подписка заканчивается, вы теряете пролонгированные загрузки и больше не имеете доступа к загрузке каких-либо премиальных значков.
Что происходит с моими неиспользованными загрузками?
Неиспользованные загрузки из вашей подписки всегда переносятся на следующий месяц. ProMicro помогает вам пролонгировать более 60 загрузок, а ProStarter помогает пролонгировать более 300 загрузок.
В чем разница между учетной записью Premium и бесплатной учетной записью?
Член бесплатной учетной записи имеет ограниченный доступ, и каждый раз, когда он загружает иконку, он должен указывать дизайнера иконки.
Премиум-участники получают неограниченные лицензии без лицензионных отчислений (не нужно беспокоиться об атрибуции). Член премиум-аккаунта имеет доступ к премиальным значкам, неограниченному количеству значков, а также имеет доступ к загрузке значков в соответствии с их выбором цвета и стиля.
Возможно ли автоматическое продление плана подписки?
Да, автоматическое продление плана подписки происходит автоматически каждый месяц, пока вы не перейдете на страницу плана и не отмените подписку на автоматическое продление плана.
Что говорят о нас наши Премиум-пользователи
Мне было трудно преодолеть языковой барьер, и именно тогда мой друг порекомендовал бесплатные иконки. Это не только помогло мне преодолеть языковой барьер, но и сделало общение более плавным.
Джеффри Джонсон
Использование бесплатных иконок помогло мне сделать мою веб-страницу не требующей пояснений даже без добавления текста или дополнительной информации.

Сара Пулос
Броский веб-сайт — это то, что я пытался создать, но слова как таковые не помогли, именно здесь я услышал об этих удивительных бесплатных иконках, и когда я использовал их для своего веб-сайта, они действительно сделали замечательную работу для моего веб-сайта.
Адитья Дингре
Я изо всех сил пытался получить больше места на своих веб-страницах, и бесплатные значки помогли мне в этом, добавив вместо этого правильные значки на мою страницу. Я очень благодарен этой команде за то, что они помогли мне справиться с огромным бременем с такой простотой и легкостью.
Бибин, генеральный директор DotFix
Значки SVG для документов и приложений R • значки
библиотека (значки) #> ── Установленные иконки ────────────────────────────────────────── ─ ─── значок 0.2.0 ── #> ✓ ionicons 5.2.3 ✓feather_icons v4.28.0 #> ✓ академики 1.9.1 ✓ октиконы 11.2.0 #> ✓ simple_icons 4.4.0 ✓ fontawesome 5.15.2 #> ✓ google_material 4.0.0
Иконки можно вставлять в строку, используя встроенный код `r icons::fontawesome("rocket", style = "solid")` или `r icons::fontawesome$solid$rocket` .
```{r icon-chunk}
fontawesome("rocket", style = "solid") # эквивалентно icons::fontawesome$solid$rocket
``` Если имя значка содержит несинтаксические символы имени, такие как - или + , вам нужно будет заключить имя в обратные, одинарные или двойные кавычки:
fontawesome$brands$`r-project` # или 'r-project' или "r-project"
` ``{r icon-style}
icon_style(fontawesome("ракета", стиль = "твердый"), масштаб = 2, заливка = "красный")
``` Пользовательские наборы значков могут быть созданы с помощью функции icon_set() , которая принимает каталог файлов SVG и позволяет использовать их в качестве значков.
```{r icon-custom}
пользовательские <- icons::icon_set("hex")
пользовательские $иконки
``` icon_find("ракета")
#> $`ionicons$ракета`
#> w3.org/2000/svg">
#> <название>название> #> #> #> <путь d="M161.93,386,44а16,16,0,0,0-11,2,67в-6,39,4,37-12,81,8,69-19,29,12,9-13,11,8,52-28,79-6,44-21-20л12,15-21а16,16,0,0, 0-15.16-24.91A61.25,61.25,0,0,0,72,353.56c-3.66,3.
67-14.79,14.81-20.78,57.26A357.94,357.94,0,0,0,48,447.59,16,16,0,0 ,0,64,464h.4a359,87,359,87,0,0,0,36,8-3,2c42,47-6,53,61-17,14,57,27-20,8a60,49,60,49,0,0,0,17,39-35,74A16,16 ,0,0,0,161,93,386,44Z">путь> #> #>
#> $`octicons$rocket`
#> 
scissorAnim(this.$refs.rightscissor, 30)
this.scissorAnim(this.$refs.leftscissor, -30)
},
scissorAnim(el, rot) {
TweenMax.to(el, 0.25, {
rotation: rot,
repeat: 3,
yoyo: true,
svgOrigin: '50 45',
ease: Sine.easeInOut
})
}
}
}
67-14.79,14.81-20.78,57.26A357.94,357.94,0,0,0,48,447.59,16,16,0,0 ,0,64,464h.4a359,87,359,87,0,0,0,36,8-3,2c42,47-6,53,61-17,14,57,27-20,8a60,49,60,49,0,0,0,17,39-35,74A16,16 ,0,0,0,161,93,386,44Z">путь> #> #>
#> $`octicons$rocket`
#>