diff --git a/_tools/generateFontData.js b/_tools/generateFontData.js index 400f220..42fe8b5 100644 --- a/_tools/generateFontData.js +++ b/_tools/generateFontData.js @@ -18,14 +18,15 @@ const path = require("path"); const { parseFontFile, buildStylesheet, - buildFontJs + buildFontJs, + getSelector } = require("specimen-skeleton-support"); const srcDirectory = path.resolve(__dirname, "../", "src"); const fontsDirectory = path.resolve(srcDirectory, "fonts"); -const dataDirectory = path.resolve(srcDirectory, "_data"); -const fontsStylesheetPath = path.resolve(srcDirectory, "css", "font.css"); -const fontJsPath = path.resolve(srcDirectory, "js", "font.js"); +const dataDirectory = path.resolve(srcDirectory, "_data/fonts"); +const fontsStylesheetPath = path.resolve(srcDirectory, "css", "fonts.css"); +const fontJsPath = path.resolve(srcDirectory, "js", "fonts.js"); const assert = (condition, message) => { if (!condition) { @@ -33,22 +34,27 @@ const assert = (condition, message) => { } }; +const _appendFile = util.promisify(fs.appendFile); const _writeFile = util.promisify(fs.writeFile); -const writeFile = (path, contents) => { +const writeFile = (path, contents, append) => { console.info("Writing", path); + if (append) { + return _appendFile(path, contents); + } return _writeFile(path, contents); }; -const writeDataFile = async (filename, data) => { - const dataFilePath = path.join(dataDirectory, filename); - const fileContents = JSON.stringify(data, null, 4); - - return writeFile(dataFilePath, fileContents); +const writeDataFile = async (filename, fontName, data) => { + fs.mkdir(path.join(dataDirectory, fontName), { recursive: true }, () => { + const dataFilePath = path.join(dataDirectory, fontName, filename); + const fileContents = JSON.stringify(data, null, 4); + return writeFile(dataFilePath, fileContents); + }); }; const writeDataFiles = async fontData => { - const promises = Object.entries(fontData).map(([type, data]) => { - return writeDataFile(`${type}.json`, data); + const promises = Object.entries(fontData.data).map(([type, data]) => { + return writeDataFile(`${type}.json`, getSelector(fontData, true), data); }); return Promise.all(promises); @@ -59,46 +65,58 @@ const writeStylesheet = async (fontData, fontFilePath) => { path.dirname(fontsStylesheetPath), fontFilePath ); - const stylesheet = buildStylesheet(fontData, fontUrl).toString(); - return writeFile(fontsStylesheetPath, stylesheet); + let stylesheet = buildStylesheet(fontData, fontUrl).toString(); + stylesheet += "\n\n"; + return writeFile(fontsStylesheetPath, stylesheet, true); }; const writeFontJs = async fontData => { const js = buildFontJs(fontData); - return writeFile(fontJsPath, js); + return writeFile(fontJsPath, js, true); }; -const findFirstFontFile = async directory => { +const findFontFile = async directory => { const fontFiles = (await util.promisify(fs.readdir)(directory)).filter( f => path.extname(f) == ".woff2" ); assert( fontFiles.length > 0, - `No font file found. Place your font in ${path.relative( + `No WOFF2 font files found. Place your WOFF2 fonts in ${path.relative( process.cwd(), directory )}.` ); - assert( - fontFiles.length == 1, - "Multiple font files found. Please specify the path to your font file explicitly." - ); + const paths = fontFiles.map(fontFile => ({ + name: path.basename(fontFile, path.extname(fontFile)), + path: path.resolve(fontsDirectory, fontFile) + })); - return path.resolve(fontsDirectory, fontFiles[0]); + return paths; }; const main = async () => { - const fontFilePath = - process.argv[2] || (await findFirstFontFile(fontsDirectory)); - const fontData = await parseFontFile(fontFilePath); - - await Promise.all([ - writeDataFiles(fontData.data), - writeStylesheet(fontData, fontFilePath), - writeFontJs(fontData) - ]); + const fontFiles = process.argv[2] || (await findFontFile(fontsDirectory)); + + // Initialise files + writeFile( + fontsStylesheetPath, + `/* Generated by the Specimen Skeleton */\n` + ); + writeFile( + fontJsPath, + `/* Generated by the Specimen Skeleton */\nexport const fontNames = [];\n` + ); + + for (const fontFile of fontFiles) { + const fontData = await parseFontFile(fontFile.path); + await Promise.all([ + writeDataFiles(fontData, fontFile.name), + writeStylesheet(fontData, fontFile.path), + writeFontJs(fontData, fontFile.name) + ]); + } }; main().catch(e => { diff --git a/src/_includes/character-grid.html b/src/_includes/character-grid.html index 394cfc4..a081b6d 100644 --- a/src/_includes/character-grid.html +++ b/src/_includes/character-grid.html @@ -1,5 +1,7 @@ -
    - {% for char in charset %} +

    Charset for {{ font[0] }}

    + +
      + {% for char in font[1].charset %}
    1. {{ char }}
    2. {% endfor %}
    diff --git a/src/_includes/interactive-controls.html b/src/_includes/interactive-controls.html index 40f4aa9..2d445a2 100644 --- a/src/_includes/interactive-controls.html +++ b/src/_includes/interactive-controls.html @@ -1,5 +1,5 @@ -
    -

    Axes & Instances

    +
    +

    Axes & Instances for {{ font[0] }}

    • @@ -14,7 +14,7 @@

      Axes & Instances

      class="interactive-controls-slider" />
    • - {% for axis in axes %} + {% for axis in font[1].axes %}
    • Axes & Instances id="interactive-controls-instances-select" class="interactive-controls-instances" > - {% for instance in instances %} + {% for instance in font[1].instances %} diff --git a/src/css/font.css b/src/css/fonts.css similarity index 100% rename from src/css/font.css rename to src/css/fonts.css diff --git a/src/css/main.css b/src/css/main.css index dc76e5f..9a3a2e2 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -18,7 +18,7 @@ limitations under the License. @import "./animation.css"; @import "./character-grid.css"; -@import "./font.css"; +@import "./fonts.css"; @import "./generic.css"; @import "./interactive-controls.css"; @import "./layout.css"; diff --git a/src/fonts/README.md b/src/fonts/README.md new file mode 100644 index 0000000..0082153 --- /dev/null +++ b/src/fonts/README.md @@ -0,0 +1 @@ +Put your WOFF2 font files here! \ No newline at end of file diff --git a/src/index.html b/src/index.html index d277ff6..0a271d1 100644 --- a/src/index.html +++ b/src/index.html @@ -12,13 +12,11 @@
    - {% include interactive-controls.html %} - + {% for font in fonts %} {% if font[1].axes.length != 0 %} {% include + interactive-controls.html %}
    - - {% include character-grid.html %} - + {% endif %} {% endfor %} {% for font in fonts %} {% include + character-grid.html %}
    - - {% include animation.html %} + {% endfor %} {% include animation.html %}
    diff --git a/src/js/font.js b/src/js/fonts.js similarity index 100% rename from src/js/font.js rename to src/js/fonts.js diff --git a/src/js/main.js b/src/js/main.js index d764c96..03afac2 100644 --- a/src/js/main.js +++ b/src/js/main.js @@ -13,7 +13,7 @@ // limitations under the License. import "./assets.js"; -import { fontName } from "./font"; +import { fontNames } from "./fonts.js"; import FontFaceObserver from "fontfaceobserver"; const fontTimeOut = 5000; // In milliseconds @@ -36,14 +36,19 @@ const throttle = (fn, wait) => { }; // Set up FontFaceObserver -const font = new FontFaceObserver(fontName); -font.load(null, fontTimeOut).then( +let observers = []; +for (const fontName of fontNames) { + const font = new FontFaceObserver(fontName); + observers.push(font.load(null, fontTimeOut)); +} + +Promise.all(observers).then( () => { - // Font has loaded + // All fonts have loaded document.documentElement.classList.add("fonts-loaded"); }, () => { - // Font didn't load + // One or more fonts didn't load document.documentElement.classList.add("fonts-failed"); } );