Создаем свой font-package

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

Исходные коды пакета а так же собранный пакет доступны в репозитории

 

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *