diff --git a/packages/core/src/index.js b/packages/core/src/index.js index 79a44f7..3e68d4b 100644 --- a/packages/core/src/index.js +++ b/packages/core/src/index.js @@ -6,7 +6,7 @@ export { Editor, TOOLS } from './editor.js' export { Store, newId, isDiffEmpty, invertDiff, composeDiff, packDiff, unpackDiff, streamDiffs } from './store.js' export { buildUI } from './ui.js' export { - themeOf, THEMES, COLOR_IDS, SIZE_IDS, DASH_IDS, FILL_IDS, GEO_IDS, GRID_IDS, + themeOf, THEMES, COLOR_IDS, SIZE_IDS, DASH_IDS, FILL_IDS, FONT_IDS, GEO_IDS, GRID_IDS, SIZES, FONT_SIZES, FONTS, } from './palette.js' export { pageBounds, localBounds, drawShape, hitShape } from './shapes.js' diff --git a/packages/core/src/palette.js b/packages/core/src/palette.js index 98e3b6c..07f9744 100644 --- a/packages/core/src/palette.js +++ b/packages/core/src/palette.js @@ -105,6 +105,7 @@ export const NOTE_FONT_SIZES = { s: 16, m: 20, l: 26, xl: 32 } export const DASH_IDS = ['draw', 'solid', 'dashed', 'dotted'] export const FILL_IDS = ['none', 'semi', 'solid', 'pattern'] +export const FONT_IDS = ['draw', 'sans', 'serif', 'mono'] export const FONTS = { // 'Quickdraw Hand' is Libre Baskerville, bundled via quickdraw.css; the rest are diff --git a/packages/core/src/quickdraw.css b/packages/core/src/quickdraw.css index c99f40c..9a9019a 100644 --- a/packages/core/src/quickdraw.css +++ b/packages/core/src/quickdraw.css @@ -292,6 +292,7 @@ .qd-opt svg { width: 20px; height: 20px; } .qd-opt:hover { background: var(--qd-hover); } .qd-opt.on { background: var(--qd-on-bg); color: var(--qd-on-ink); } +.qd-fonts .qd-opt { width: auto; min-width: 44px; padding: 0 8px; font-size: 15px; } .qd-opacity { gap: 10px; padding: 2px 4px 0; } .qd-opacity-label { font: 500 12px/1 -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; color: var(--qd-ink-soft); } .qd-opacity-val { diff --git a/packages/core/src/ui.js b/packages/core/src/ui.js index ed92596..582968c 100644 --- a/packages/core/src/ui.js +++ b/packages/core/src/ui.js @@ -6,7 +6,7 @@ // the standard set users already know. // Dependency-free ESM (see palette.js). -import { COLOR_IDS, SIZE_IDS, DASH_IDS, FILL_IDS, GEO_IDS, GRID_IDS, THEMES } from './palette.js' +import { COLOR_IDS, SIZE_IDS, DASH_IDS, FILL_IDS, FONT_IDS, GEO_IDS, GRID_IDS, THEMES, FONTS } from './palette.js' const SVG = (inner) => `${inner}` @@ -281,6 +281,15 @@ export function buildUI(editor, { hidden = false, onSave, themeToggle = true, gr b.addEventListener('click', (e) => { e.stopPropagation(); editor.setStyle('fill', f); restyle() }) fills.appendChild(b) } + const fonts = row('qd-fonts') + const FONT_LABELS = { draw: 'Hand', sans: 'Sans', serif: 'Serif', mono: 'Mono' } + for (const f of FONT_IDS) { + const b = el('button', 'qd-opt' + (cur.font === f ? ' on' : '')) + b.title = 'font: ' + (FONT_LABELS[f] || f) + b.innerHTML = `Ag` + b.addEventListener('click', (e) => { e.stopPropagation(); editor.setStyle('font', f); restyle() }) + fonts.appendChild(b) + } // opacity: one slider, 10–100%. A drag is a single undo step. const opac = row('qd-opacity') opac.innerHTML = 'Opacity' @@ -310,6 +319,7 @@ export function buildUI(editor, { hidden = false, onSave, themeToggle = true, gr sizes.querySelectorAll('.qd-opt').forEach((b, i) => b.classList.toggle('on', SIZE_IDS[i] === c2.size)) dashes.querySelectorAll('.qd-opt').forEach((b, i) => b.classList.toggle('on', DASH_IDS[i] === c2.dash)) fills.querySelectorAll('.qd-opt').forEach((b, i) => b.classList.toggle('on', FILL_IDS[i] === c2.fill)) + fonts.querySelectorAll('.qd-opt').forEach((b, i) => b.classList.toggle('on', FONT_IDS[i] === c2.font)) showOpacity(c2.opacity) refresh() } diff --git a/packages/core/types/index.d.ts b/packages/core/types/index.d.ts index f283c44..870b90a 100644 --- a/packages/core/types/index.d.ts +++ b/packages/core/types/index.d.ts @@ -99,6 +99,7 @@ export const COLOR_IDS: ColorId[] export const SIZE_IDS: SizeId[] export const DASH_IDS: DashId[] export const FILL_IDS: FillId[] +export const FONT_IDS: FontId[] export const GEO_IDS: GeoId[] export const GRID_IDS: GridId[] export const THEMES: Record