В данной статье мы покажем как создать свой packages с иконками, а так же процесс сборки шрифтов из svg файлов, создание preview галереи шрифтов, и использование в ExtJS приложениях. Мы создадим font package на основе Material Icons от Google.
Подготавливаем svg иконки
Для начала клонируем официальный репозиторий с иконками.
git clone https://github.com/google/material-design-icons
Перейдем в склонированный репозиторий и найдем все иконки размером 24px (возьмем их за основу), найдем все такие иконки и скопируем их в отдельную папку, а затем переименуем (уберем из их имени «_24px» и «ic_») и нормализуем имена.
result="/path/to/result/icons" find ./ -type 'f' | grep _24px.svg | xargs -n 1 -I % cp "%" $result cd $result rename.ul "_24px" "" *.svg rename.ul "ic_" "" *.svg rename.ul "_" "-" *.svg
На момент написания статьи мы получили 959 иконок. Так же нам понадобиться файл /iconfont/codepoints , он служит для однозначного сопоставления иконки и её кода при последующих обновлениях.
Создаем font-package
Вся дальнейшая инструкция соответствует сброке на Windows системах, для *nix все будет более менее аналогично (и думаю разберетесь сами, раз у вас *nix 🙂 , процесс сборки не должен сильно отличаться). Далее нам понадобится NodeJS (8.10.0) , и последний FontForge (на самом деле можно использовать node движок для grunt-webfont, но он не гарантирует полную поддержку спецификаций svg). Для начала создадим наш пакет
sencha generate package font-material
Теперь нам нужно скачать окружение для сборки (выполнять под Администратором)
npm install --global --production windows-build-tools
Создадим папку grunt в корне пакета, там мы будем хранить будущей node package, конфигурацию сборщика grunt, а так же сами иконки (будут располагаться в папке svg). Не забудьте скопировать полученные svg файлы в папку svg и положить файл codepoints в папку grunt. Так же нам необходимо нормализовать имена упомянутые в codepoints , если этого не делать то мы получим в итоге наименование классов стилей с символом «_» , а мне больше по душе «-» :). Основная проблема с codepoints в том что у него не совместимый формат с grunt-webfonts. Напишем небольшой конвертер на NodeJS и положим его в папку grunt.
var fs = require('fs');
var codepoints = fs.readFileSync('codepoints', 'utf-8');
var result = {};
codepoints.split("\n")
.map((line) => line.split(' '))
.slice(0, -1) // last line is empty
.forEach((pair) =>
// <name>: <unicode char>
result[pair[0]] = parseInt(pair[1], 16)
);
fs.writeFileSync(
'codepoints.json',
JSON.stringify(result),
'utf8'
);
Далее нормализуем имена и сконвертируем codepoints
mkdir grunt cd grunt cp /path/to/codepoints . sed -i 's/_/-/g' codepoint node convert_codepoints.js mkdir svg
Создадим node package со всеми нам необходимыми зависимостями
{
"name": "font-material",
"version": "0.0.1",
"description": "Material icons package for ExtJS",
"author": "Dmitry Kazarin",
"contributors": [
{
"name": "Dmitry Kazarin",
"email": "dikazarin@gmail.com"
}
],
"dependencies": {
"grunt": "~1.0.1",
"grunt-cli": "~1.2.0",
"grunt-contrib-less": "~1.4.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-contrib-uglify": "~2.0.0",
"grunt-webfont": "~1.6.0",
"fontforge": "~0.0.4",
"ttf2woff2": "2.0.3"
},
"devDependencies": {
"grunt": "~1.0.1",
"grunt-cli": "~1.2.0",
"grunt-contrib-less": "~1.4.0",
"grunt-contrib-watch": "~1.0.0",
"grunt-contrib-uglify": "~2.0.0",
"grunt-webfont": "~1.6.0",
"fontforge": "~0.0.4",
"ttf2woff2": "2.0.3"
},
"licenses": [
{
"type": "GPLv3",
"url": "http://www.gnu.org/licenses/gpl-3.0.html"
}
]
}
И установим их через npm install. Теперь нам необходимо создать Gruntfile.js файл для сборки шрифтов
module.exports = function (grunt) {
grunt.initConfig({
webfont: {
"Material": {
src: 'svg/*.svg',
dest: './../resources/fonts',
destCss: './../sass/etc',
options: {
font: "Material",
hashes: false,
syntax: "bem",
stylesheet: "scss",
codepointsFile: "codepoints.json",
relativeFontPath: "#{$material-font-path}/",
normalize: true,
htmlDemo: true,
destHtml: "./..",
types: 'eot,woff2,woff,ttf,svg',
templateOptions: {
baseClass: 'x-mi',
classPrefix: 'mi-'
}
}
}
}
});
grunt.loadNpmTasks('grunt-webfont');
grunt.registerTask('default', ['webfont']);
};
Добавим пару строчек в /sass/etc/all.scss для того что бы правильно определять пути к шрифтам
$material-font-path: get-resource-path('fonts', 'shared');
@import "_Material";
И добавим в /sass/src/all.scss
.#{$prefix}mi:before {
font-family: Material !important;
}
Теперь осталось отредактировать файл ExtJS пакета, для поддержки shared ресурсов
{
"name": "font-material",
"sencha": {
...
"resource": {
"paths": ""
},
"resources": [
{
"path": "${package.dir}/resources",
"output": "shared"
}
],
"slicer": null,
...
}
}
Нам осталось запустить сборку, находясь в папке с Gruntfile.js выполняем команду grunt.
Теперь в ExtJS приложении можно использовать новые иконки из созданного пакета (не забудьте добавить его использование в app.json)
{
xtype: 'button',
text: 'example',
iconCls: 'x-mi mi-person'
}
Так же в корне пакета доступна html страничка Material.html , для просмотра всех иконок в данном пакете.
Исходные коды пакета а так же собранный пакет доступны в репозитории