Created
August 30, 2019 15:13
-
-
Save romanlv/0b5b1d5d942b01da9e7bd46f07d42584 to your computer and use it in GitHub Desktop.
script to generate TTF icon font from SVGs for `react-native-vector-icons`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { createIconSet } from "react-native-vector-icons"; | |
import glyphMap from "../../../assets/fonts/wmicons-map.json"; | |
const Icon = createIconSet(glyphMap, "wmicons"); | |
const SIZE = 20 | |
export const CartIcon = (props = {}) => ( | |
<Icon name="cart" size={SIZE} {...props} /> | |
); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require('fs'); | |
const { promisify } = require('util'); | |
const glob = require('glob'); | |
const xml2js = require('xml2js'); | |
const SVGIcons2SVGFontStream = require('svgicons2svgfont'); | |
const SVGIconsDirStream = require('svgicons2svgfont/src/iconsdir.js'); | |
const svg2ttf = require('svg2ttf'); | |
const readFileAsync = promisify(fs.readFile); | |
const writeFileAsync = promisify(fs.writeFile); | |
function makeSvgFont(fontName, svgs, svgFontPath) { | |
const files = glob.sync(svgs); | |
const options = { | |
// see list of all the options | |
// https://github.com/nfroidure/svgicons2svgfont#cli-interface | |
// https://github.com/nfroidure/svgicons2svgfont/blob/master/bin/svgicons2svgfont.js#L76 | |
fontHeight: 1000, | |
normalize: true | |
} | |
return new Promise((resolve, reject) => { | |
new SVGIconsDirStream(files, {}) | |
.pipe( | |
new SVGIcons2SVGFontStream({ | |
...options, | |
fontName | |
}) | |
) | |
.pipe(fs.createWriteStream(svgFontPath)) | |
.on("finish", resolve) | |
.on("error", reject); | |
}); | |
} | |
async function convertSvg2Ttf(svgFontPath, output) { | |
var ttf = svg2ttf(await readFileAsync(svgFontPath, 'utf8'), {}); | |
await writeFileAsync(output, Buffer.from(ttf.buffer)); | |
} | |
async function generateGlyphMap(svgFontPath, output) { | |
const parser = new xml2js.Parser(); | |
const glyphMap = {} | |
const data = await readFileAsync(svgFontPath) | |
return new Promise((resolve, reject) => { | |
parser.parseString(data, function (err, result) { | |
if (err!==null) { | |
reject(err); | |
} | |
if (!result) { | |
console.error(`cannot parse ${svgFontPath}`) | |
} | |
const icons = result.svg.defs[0].font[0].glyph; | |
icons.forEach(({ $: icon }) => { | |
const name = icon["glyph-name"]; | |
const code = icon.unicode.charCodeAt(0); | |
glyphMap[name] = code; | |
}) | |
fs.writeFileSync(output, JSON.stringify(glyphMap, null, 2)); | |
resolve(glyphMap) | |
}); | |
}) | |
} | |
async function main() { | |
const fontName = "myicons"; | |
// this file is temporary | |
const svgFontPath = `./ios/build/${fontName}.svg`; | |
const glyphMapPath = `./assets/fonts/${fontName}-map.json`; | |
const tffPath = `./assets/fonts/${fontName}.ttf`; | |
// create svg font from svg icons, it will use `svgicons2svgfont` to convert | |
// `rect', 'circle` etc... to `path`s that can be used for font generation | |
await makeSvgFont(fontName, "./assets/svgs/*.svg", svgFontPath) | |
await Promise.all([ | |
// create json file with map of icon name and character code in font, needed for `react-native-vector-icons` integration | |
generateGlyphMap(svgFontPath, glyphMapPath), | |
// convert svg font to ttf font | |
convertSvg2Ttf(svgFontPath, tffPath) | |
]); | |
console.log(`updated: ${tffPath} and ${glyphMapPath}`) | |
} | |
main(); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
node ./assets/make-font.js
to update the font