diff --git a/index.html b/index.html index 98ad76a..11a1c23 100644 --- a/index.html +++ b/index.html @@ -9,21 +9,24 @@ -
-

Fontsource font preview

-
-
-
-

This page shows fonts loaded from Fontsource.

-
- -
+ +
+
+

Fontsource font preview

+
+
+

This page shows fonts loaded from Fontsource.

+
+

About this font

@@ -52,6 +55,12 @@
+
+

Files

+ +
+

CSS


diff --git a/script.js b/script.js
index 6bc1f06..cdaea15 100644
--- a/script.js
+++ b/script.js
@@ -79,7 +79,8 @@ const css_template = (info,range,weight,style,variable_info) => {
     if(axes.includes('slnt')) {
       extras.push(`  font-style: oblique ${variable_info.axes.slnt.min}deg ${variable_info.axes.slnt.max}deg;`);
     }
-}
+  }
+
 
   if(info.variable) {
     return `
@@ -113,6 +114,52 @@ async function fetch_json(url) {
 }
 
 
+async function draw_font_preview(f) {
+    const d = await navigator.storage.getDirectory();
+    const filename = `${f.family}.png`;
+    let fh;
+    try {
+      fh = await d.getFileHandle(filename);
+    } catch(e) {
+      const style = document.createElement('style');
+      try {
+        document.head.append(style);
+        const info = await fetch_json(font_info_url(f.id));
+        const variable_info = info.variable ? await fetch_json(variable_info_url(info.id)) : {};
+        const css = css_template(info,info.defSubset,info.weights[0],'normal',variable_info);
+        style.textContent += css;
+        await new Promise((resolve,reject) => {
+          setTimeout(async () => {
+            const ffs = Array.from(document.fonts).filter(ff=>ff.family == `"${f.family}"`);
+            await Promise.all(ffs.map(ff => ff.load())).catch(reject)
+            resolve();
+          },1);
+        });
+      } catch(e) {
+        return;
+      }
+      const cv = new OffscreenCanvas(1,1);
+      const ctx = cv.getContext('2d');
+      const font_style = `100px "${f.family}"`;
+      ctx.font = font_style;
+      const {width, fontBoundingBoxAscent, fontBoundingBoxDescent} = ctx.measureText(f.family);
+      cv.width = width;
+      cv.height = fontBoundingBoxAscent + fontBoundingBoxDescent;
+      ctx.font = font_style;
+      ctx.fillText(f.family,0,fontBoundingBoxAscent);
+      const blob = await cv.toBlob();
+      fh = await d.getFileHandle(filename,{create:true});
+      const w = await fh.createWritable();
+      await w.write(blob);
+      await w.close();
+      window.blob = blob;
+      style.parentElement.removeChild(style);
+    }
+    const file = await fh.getFile();
+    return URL.createObjectURL(file);
+
+}
+
 
 async function go() {
   let [fonts, axes_info] = await Promise.all([
@@ -120,14 +167,20 @@ async function go() {
     fetch_json('https://api.fontsource.org/v1/axis-registry')
   ]);
 
+  window.available_fonts = fonts;
+
   axes_info = Object.fromEntries(Object.entries(axes_info).map(([k,v]) => [k.toLowerCase(), v]));
 
   async function use_font() {
     const name = select.value;
-    console.log(name);
     const info = await fetch_json(font_info_url(name));
     const variable_info = info.variable ? await fetch_json(variable_info_url(info.id)) : {};
-    console.log(info);
+
+    const preview = document.querySelector(`[data-font="${name}"]`);
+    if(preview) {
+      preview.scrollIntoView({block: 'center'});
+      document.body.scrollTop = 0;
+    }
   
     document.body.style.setProperty('--family',info.family);
   
@@ -153,7 +206,6 @@ async function go() {
     if(info.variable) {
       const variable_axes = document.getElementById('variable-axes');
       variable_axes.innerHTML = '';
-      console.log(variable_info);
   
       const ranges = {};
   
@@ -208,7 +260,6 @@ async function go() {
         document.body.style['font-variation-settings'] = settings;
       }
       update_variables();
-      
     }
   
     const css_declarations = [];
@@ -240,7 +291,7 @@ async function go() {
   }
   
   
-  fonts = fonts.filter(f=>!f.id.includes('noto'));
+  fonts = fonts.filter(f=>!f.id.match(/noto|playwrite/i));
   select.innerHTML = '';
   for(let font of fonts) {
     const option = document.createElement('option');
@@ -260,6 +311,27 @@ async function go() {
   document.getElementById('random-font').addEventListener('click', random_font);
   
   random_font();
+
+  const fl = document.getElementById('font-list');
+  const step = 10;
+  for(let i=0;i {
+      const li = document.createElement('li');
+      fl.append(li);
+      const a = document.createElement('a');
+      li.append(a);
+      a.addEventListener('click', () => {
+        select.value = f.id;
+        use_font();
+      })
+      const img = document.createElement('img');
+      img.dataset.font = f.id;
+      a.append(img);
+      img.src = await draw_font_preview(f);
+      img.style.height = '1em';
+      img.alt = f.family;
+    }));
+  }
 }
 
 go();
\ No newline at end of file
diff --git a/style.css b/style.css
index 125118f..8947921 100644
--- a/style.css
+++ b/style.css
@@ -2,10 +2,59 @@
   --spacing: 1em;
   --family: sans-serif;
 
+  --background: white;
+  --color: black;
+
   color-scheme: light dark;
+  height: 100svh;
+  overflow: hidden;
 }
+
+@media (prefers-color-scheme: dark) {
+  body {
+    --background: black;
+    --color: white;
+  }
+
+  #font-list img {
+    filter: invert(100%);
+  }
+}
+
 body {
+  display: grid;
+  grid-template-columns: 15em 1fr;
+  gap: var(--spacing);
+  width: 100svw;
+  height: 100svh;
+  margin: 0;
+  overflow: hidden;
+  
+  color: var(--color);
+  background: var(--background);
+}
+
+
+nav {
+    height: 100svh;
+    display: flex;
+    flex-direction: column;
+}
+
+#controls {
+    position: sticky;
+    top: 0;
+    background: var(--background);
+    padding: var(--spacing);
+
+    & select {
+      width: 100%;
+    }
+}
+
+main {
   font-family: var(--family);
+  overflow: auto;
 }
 
 .fixed-font {
@@ -29,4 +78,24 @@ dt {
   max-width: 100%;
   max-height: 3em;
   overflow: auto;
+}
+
+
+#font-list {
+  margin: 0;
+  overflow: auto;
+  width:100%;
+  height:100%;
+  
+  font-size: 2rem;
+  padding: 0;
+  list-style: none;
+  
+  & li {
+    overflow: hidden;
+  }
+}
+
+#css-display {
+  margin: 0;
 }
\ No newline at end of file