В данной статье мы покажем как создать свой 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 , для просмотра всех иконок в данном пакете.
Исходные коды пакета а так же собранный пакет доступны в репозитории