1.2.5: text font picker + 7 bundled Google fonts + default text fill black
- New src/lib/fonts.ts: curated set (Inter, Roboto, Lora, Playfair Display, Bebas Neue, Source Code Pro, Permanent Marker) shipped as local .woff2 in public/fonts/. loadFonts() registers them via FontFace at app start; fontsReady ref re-triggers Konva text configs once fonts resolve so the first paint isn't stuck on the fallback. - TextAsset gets optional fontFamily (id; undefined = system sans). PropertiesPanel adds a font dropdown next to font size. - All five render sites read the family: CanvasStage textConfig + clipTextConfig (Konva), drawLayer + drawMaskShape (canvas2d), exportPlayer engine (uses an embedded FONT_FAMILIES map and fontFam helper; runtime version 27 → 28). - Example HTML export now lists used bundled fonts and prints the @font-face CSS the user has to paste alongside the .woff2 files — fonts themselves are NOT bundled into the export to keep it small. - Default text fill changed from yellow #f5d76e to black #000000 in both the main sidebar and the SVG-scope add-text path. - 8 new tests under "text font picker — model + render + export". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
b32b8a6a3d
commit
4c2b7c7c35
20 files changed
+339
-12
No files matched your search
@@ -20,6 +20,7 @@ import { isButtonLayerActiveAt, isLayerActiveAt, sampleLayer } from '@/lib/inter
|
||||
import { importImageFile, loadImage } from '@/lib/fileLoader'
|
||||
import { useClipartStore } from '@/stores/clipart'
|
||||
import { useDocumentDrawer } from '@/composables/useDocumentDrawer'
|
||||
import { fontCssFamily, fontsReady } from '@/lib/fonts'
|
||||
import { drawButtonFrame, drawSceneFrame, loadSceneImages } from '@/lib/render'
|
||||
import type {
|
||||
Action,
|
||||
@@ -1303,11 +1304,17 @@ function circleConfig(
|
||||
function textConfig(layer: Layer, asset: Extract<Asset, { kind: 'text' }>, props: AnimatableProps) {
|
||||
const fill = props.fill ?? asset.fill
|
||||
const base = baseNodeConfig(layer, props)
|
||||
// Read fontsReady so this config recomputes once bundled fonts
|
||||
// resolve — otherwise Konva caches a measurement made against the
|
||||
// fallback family and the text is rendered too narrow.
|
||||
void fontsReady.value
|
||||
const family = fontCssFamily(asset.fontFamily)
|
||||
if (isLayerGhostLocked(layer)) {
|
||||
return {
|
||||
...base,
|
||||
text: asset.text,
|
||||
fontSize: asset.fontSize,
|
||||
fontFamily: family,
|
||||
offsetX: layer.offsetX ?? 0,
|
||||
offsetY: layer.offsetY ?? 0,
|
||||
fill: undefined,
|
||||
@@ -1320,6 +1327,7 @@ function textConfig(layer: Layer, asset: Extract<Asset, { kind: 'text' }>, props
|
||||
...base,
|
||||
text: asset.text,
|
||||
fontSize: asset.fontSize,
|
||||
fontFamily: family,
|
||||
offsetX: layer.offsetX ?? 0,
|
||||
offsetY: layer.offsetY ?? 0,
|
||||
...(layer.isMask ? {} : strokeCfg(props, asset)),
|
||||
@@ -1611,12 +1619,14 @@ function clipCircleConfig(item: RenderedClipLayer) {
|
||||
}
|
||||
|
||||
function clipTextConfig(item: RenderedClipLayer) {
|
||||
void fontsReady.value
|
||||
const asset = item.asset as Extract<Asset, { kind: 'text' }>
|
||||
const fill = item.props.fill ?? asset.fill
|
||||
const cfg: Record<string, unknown> = {
|
||||
...clipBaseConfig(item.instanceId, item.layer, item.props),
|
||||
text: asset.text,
|
||||
fontSize: asset.fontSize,
|
||||
fontFamily: fontCssFamily(asset.fontFamily),
|
||||
offsetX: item.layer.offsetX ?? 0,
|
||||
offsetY: item.layer.offsetY ?? 0,
|
||||
...strokeCfg(item.props, asset),
|
||||
|
||||
Reference in new issue
Block a user