tegaki 0.18.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +23 -0
- package/FONTS-LICENSE.md +6 -0
- package/README.md +22 -4
- package/dist/cli.d.mts +1 -0
- package/dist/cli.mjs +233 -0
- package/dist/cli.mjs.map +1 -0
- package/dist/core/index.d.mts +3 -3
- package/dist/core/index.mjs +3 -2
- package/dist/{core-MwnsJAbN.mjs → core-VIBhSqFM.mjs} +88 -650
- package/dist/core-VIBhSqFM.mjs.map +1 -0
- package/dist/fonts/amiri/bundle.mjs.map +1 -1
- package/dist/fonts/caveat/bundle.mjs.map +1 -1
- package/dist/fonts/italianno/bundle.mjs.map +1 -1
- package/dist/fonts/klee-one/bundle.mjs.map +1 -1
- package/dist/fonts/nanum-pen-script/bundle.d.mts +7144 -0
- package/dist/fonts/nanum-pen-script/bundle.mjs +161041 -0
- package/dist/fonts/nanum-pen-script/bundle.mjs.map +1 -0
- package/dist/fonts/nanum-pen-script/nanum-pen-script-38efadb5.ttf +0 -0
- package/dist/fonts/nanum-pen-script/nanum-pen-script.ttf +0 -0
- package/dist/fonts/parisienne/bundle.mjs.map +1 -1
- package/dist/fonts/suez-one/bundle.mjs.map +1 -1
- package/dist/fonts/tangerine/bundle.mjs.map +1 -1
- package/dist/fonts/tillana/bundle.mjs.map +1 -1
- package/dist/{index-B2rqZbJt.d.mts → index-BmhPyEv9.d.mts} +4 -5
- package/dist/{index-BVYJFRMq.d.mts → index-D-lHv505.d.mts} +71 -3
- package/dist/index.d.mts +4 -4
- package/dist/index.mjs +4 -3
- package/dist/react/index.d.mts +4 -4
- package/dist/react/index.mjs +4 -3
- package/dist/{react-174En_ya.mjs → react-wE5kRPvk.mjs} +4 -2
- package/dist/{react-174En_ya.mjs.map → react-wE5kRPvk.mjs.map} +1 -1
- package/dist/shaper-harfbuzz/index.d.mts +1 -1
- package/dist/shaper-harfbuzz/index.mjs +1 -1
- package/dist/shaper-harfbuzz/index.mjs.map +1 -1
- package/dist/{shaper-registry-CrfNiB1j.d.mts → shaper-registry-DmlJGnE3.d.mts} +1 -1
- package/dist/textToSvg-GTQMM8Le.mjs +906 -0
- package/dist/textToSvg-GTQMM8Le.mjs.map +1 -0
- package/dist/wc/index.d.mts +3 -3
- package/dist/wc/index.mjs +3 -2
- package/dist/wc/index.mjs.map +1 -1
- package/fonts/nanum-pen-script/bundle.ts +20 -0
- package/fonts/nanum-pen-script/glyphData.json +1 -0
- package/fonts/nanum-pen-script/nanum-pen-script-38efadb5.ttf +0 -0
- package/fonts/nanum-pen-script/nanum-pen-script.ttf +0 -0
- package/package.json +31 -20
- package/src/cli.ts +293 -0
- package/src/core/engine.ts +95 -0
- package/src/core/index.ts +1 -0
- package/src/lib/svgExport.ts +290 -0
- package/src/lib/textToSvg.test.ts +85 -0
- package/src/lib/textToSvg.ts +162 -0
- package/dist/core-MwnsJAbN.mjs.map +0 -1
- package/dist/solid/index.d.mts +0 -20
- package/dist/solid/index.mjs +0 -91
- package/dist/solid/index.mjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
|
+
## tegaki@0.20.0
|
|
2
|
+
|
|
3
|
+
### Add `TegakiEngine.toSVG()` and a `canvas` accessor
|
|
4
|
+
|
|
5
|
+
The engine can now serialize its current text to a standalone SVG string via `toSVG({ animated, loop })` — either self-drawing (SMIL mask reveal, variable stroke width) or looping (CSS keyframes, constant width), with the viewBox cropped to the ink. The backing `<canvas>` is also exposed through a `canvas` getter so export tooling can read pixels without reaching through the DOM.
|
|
6
|
+
|
|
7
|
+
### Add a `tegaki` CLI and a `textToSvg()` export
|
|
8
|
+
|
|
9
|
+
`npx tegaki` renders text to an animated handwriting SVG straight from the command line. The same output is available programmatically through the new `textToSvg()` export, along with its `TextToSvgMode` and `TextToSvgOptions` types.
|
|
10
|
+
|
|
1
11
|
# tegaki
|
|
2
12
|
|
|
13
|
+
## 0.19.0
|
|
14
|
+
|
|
15
|
+
### Minor Changes
|
|
16
|
+
|
|
17
|
+
- 68ee58f: Support Korean (Hangul) writing system and add Nanum Pen Script as a built-in font. The bundle ships ~650 most-frequent precomposed Hangul syllables (KS X 1001 common band ∪ top-N Korean-Wikipedia-frequency, capped by the Google Fonts subsetting ceiling) plus the 40 modern compatibility jamo (19 consonants ㄱ–ㅎ + 21 vowels ㅏ–ㅣ) and the Latin baseline. Hangul is precomposed in Unicode, so no shaper is required.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- 29e111e: Fix Next.js App Router / Turbopack compatibility. Two build/packaging issues prevented `tegaki` from being used in a Next.js (App Router) app:
|
|
22
|
+
|
|
23
|
+
- The bundler dropped the `'use client'` directive from the React adapter's output chunk, so importing `TegakiRenderer` into a Server Component failed with "You're importing a module that depends on `useState` into a React Server Component". The directive is now preserved in the built output.
|
|
24
|
+
- The font subpath exports (`tegaki/fonts/*`) resolved the `node` condition to the raw TypeScript source, which uses `import ... with { type: 'url' }` import attributes that Turbopack/webpack can't process. The `node` condition now points to the pre-built `.mjs` bundle (which loads the font via `new URL('./font.ttf', import.meta.url)`), so it works in any Node-based bundler.
|
|
25
|
+
|
|
3
26
|
## 0.18.0
|
|
4
27
|
|
|
5
28
|
### Minor Changes
|
package/FONTS-LICENSE.md
CHANGED
|
@@ -51,6 +51,12 @@ All fonts are licensed under the [SIL Open Font License, Version 1.1](https://op
|
|
|
51
51
|
- **Copyright**: Copyright (c) 2014, Indian Type Foundry (info@indiantypefoundry.com)
|
|
52
52
|
- **License**: SIL Open Font License, Version 1.1
|
|
53
53
|
|
|
54
|
+
## Nanum Pen Script
|
|
55
|
+
|
|
56
|
+
- **Designer**: Sandoll Communications Inc. for NHN Corporation
|
|
57
|
+
- **Copyright**: Copyright © 2010 NHN Corporation. All rights reserved. Font designed by Sandoll Communications Inc.
|
|
58
|
+
- **License**: SIL Open Font License, Version 1.1
|
|
59
|
+
|
|
54
60
|
---
|
|
55
61
|
|
|
56
62
|
## SIL Open Font License, Version 1.1
|
package/README.md
CHANGED
|
@@ -6,12 +6,12 @@ Tegaki (手書き) turns any font into animated handwriting.
|
|
|
6
6
|
No manual path authoring. No native dependencies. Just pick a font.
|
|
7
7
|
|
|
8
8
|
[](https://www.npmjs.com/package/tegaki)
|
|
9
|
-
[](https://github.com/
|
|
9
|
+
[](https://github.com/gkurt/tegaki/blob/main/LICENSE)
|
|
10
10
|
|
|
11
11
|
<br clear="both" />
|
|
12
12
|
|
|
13
13
|
<p align="center">
|
|
14
|
-
<img src="media/hello-world.svg" alt="
|
|
14
|
+
<img src="media/hello-world.svg" alt="Tegaki is awesome handwriting animation" width="560" />
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
17
|
---
|
|
@@ -41,6 +41,23 @@ function App() {
|
|
|
41
41
|
|
|
42
42
|
That's it. The text draws itself stroke by stroke with natural timing.
|
|
43
43
|
|
|
44
|
+
## Command Line
|
|
45
|
+
|
|
46
|
+
Don't want to wire up a component? Generate an animated handwriting SVG straight from your terminal — nothing to install:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx tegaki "Tegaki is awesome"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
This writes a self-drawing, looping `tegaki-is-awesome.svg` — drop it into a README, a slide, or any page. Pick a font, mode, size, or color:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx tegaki "Hello World" --font tangerine --mode once -o hello.svg
|
|
56
|
+
npx tegaki "ABC" --stagger 80% --size 140 --color "#222"
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
`--mode` is `loop` (repeats forever, the default), `once` (draws itself a single time), or `static` (finished artwork). Run `npx tegaki --help` for every option and `--list-fonts` for the bundled fonts. The CLI emits SVG only — for PNG, GIF, or WebM use the [interactive studio](https://gkurt.com/tegaki/studio/).
|
|
60
|
+
|
|
44
61
|
## Framework Support
|
|
45
62
|
|
|
46
63
|
Tegaki works with all major frameworks:
|
|
@@ -75,8 +92,9 @@ Several handwriting fonts are bundled and ready to use:
|
|
|
75
92
|
- **Amiri** — `tegaki/fonts/amiri` _(Arabic + Latin)_
|
|
76
93
|
- **Tillana** — `tegaki/fonts/tillana` _(Devanagari + Latin)_
|
|
77
94
|
- **Klee One** — `tegaki/fonts/klee-one` _(Japanese: kana + Kyōiku grade 1–2 kanji + Latin)_
|
|
95
|
+
- **Nanum Pen Script** — `tegaki/fonts/nanum-pen-script` _(Korean: Hangul syllables + jamo + Latin)_
|
|
78
96
|
|
|
79
|
-
For other fonts, use the [interactive
|
|
97
|
+
For other fonts, use the [interactive studio](https://gkurt.com/tegaki/studio/) to create a custom bundle.
|
|
80
98
|
|
|
81
99
|
## Documentation
|
|
82
100
|
|
|
@@ -90,7 +108,7 @@ Visit **[gkurt.com/tegaki](https://gkurt.com/tegaki)** for full documentation:
|
|
|
90
108
|
## Integrations
|
|
91
109
|
|
|
92
110
|
- [Sli.dev](https://sli.dev/) - Create presentations using markdown. [See Tegaki integration example](https://andreas-taranetz.github.io/slidev-addon-animated-text/)
|
|
93
|
-
- [Remotion](https://www.remotion.dev/) - Create videos programmatically with React. [See Tegaki integration example](https://github.com/
|
|
111
|
+
- [Remotion](https://www.remotion.dev/) - Create videos programmatically with React. [See Tegaki integration example](https://github.com/gkurt/tegaki/blob/gokhan/support-font-features/examples/remotion/src/Root.tsx)
|
|
94
112
|
|
|
95
113
|
## License
|
|
96
114
|
|
package/dist/cli.d.mts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
package/dist/cli.mjs
ADDED
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { t as textToSvg } from "./textToSvg-GTQMM8Le.mjs";
|
|
3
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
//#region src/cli.ts
|
|
5
|
+
/**
|
|
6
|
+
* `tegaki` — turn text into an animated handwriting SVG from the command line.
|
|
7
|
+
*
|
|
8
|
+
* npx tegaki "Tegaki is awesome" # → tegaki-is-awesome.svg (looping)
|
|
9
|
+
* npx tegaki "Hello" -f tangerine -o hi.svg
|
|
10
|
+
*
|
|
11
|
+
* SVG is the only format emitted: it's the one the renderer can produce with
|
|
12
|
+
* zero native dependencies (no canvas, no headless browser). Raster/video
|
|
13
|
+
* export (PNG/GIF/WebM) lives in the browser studio at gkurt.com/tegaki/studio.
|
|
14
|
+
*/
|
|
15
|
+
/** Bundled fonts the CLI can load, keyed by `--font` name. */
|
|
16
|
+
const FONTS = {
|
|
17
|
+
caveat: "Caveat (Latin)",
|
|
18
|
+
italianno: "Italianno (Latin)",
|
|
19
|
+
tangerine: "Tangerine (Latin)",
|
|
20
|
+
parisienne: "Parisienne (Latin)",
|
|
21
|
+
"suez-one": "Suez One (Hebrew + Latin)",
|
|
22
|
+
amiri: "Amiri (Arabic + Latin)",
|
|
23
|
+
tillana: "Tillana (Devanagari + Latin)",
|
|
24
|
+
"klee-one": "Klee One (Japanese + Latin)",
|
|
25
|
+
"nanum-pen-script": "Nanum Pen Script (Korean + Latin)"
|
|
26
|
+
};
|
|
27
|
+
/** Fonts whose scripts need shaping the headless CLI does not apply (RTL / complex GPOS). */
|
|
28
|
+
const NEEDS_SHAPING = /* @__PURE__ */ new Set([
|
|
29
|
+
"suez-one",
|
|
30
|
+
"amiri",
|
|
31
|
+
"tillana"
|
|
32
|
+
]);
|
|
33
|
+
const MODES = [
|
|
34
|
+
"loop",
|
|
35
|
+
"once",
|
|
36
|
+
"static"
|
|
37
|
+
];
|
|
38
|
+
const HELP = `tegaki — animated handwriting SVG generator
|
|
39
|
+
|
|
40
|
+
Usage:
|
|
41
|
+
tegaki <text...> [options]
|
|
42
|
+
|
|
43
|
+
Options:
|
|
44
|
+
-o, --output <file> Output path (default: <slug>.svg; "-" writes to stdout)
|
|
45
|
+
-f, --font <name> Bundled font (default: caveat). See --list-fonts.
|
|
46
|
+
-m, --mode <mode> loop | once | static (default: loop)
|
|
47
|
+
loop self-drawing, repeats forever (README hero)
|
|
48
|
+
once draws itself once, then stays complete
|
|
49
|
+
static finished artwork, no animation
|
|
50
|
+
--size <px> Font size in px (default: 100)
|
|
51
|
+
--color <css> Stroke color (default: #1a1a1a)
|
|
52
|
+
--line-height <px> Line height in px (default: from font metrics)
|
|
53
|
+
--stagger <advance> Overlap glyphs instead of drawing them in sequence.
|
|
54
|
+
e.g. "80%" (of the previous glyph) or "0.3" (seconds)
|
|
55
|
+
--stagger-duration <s|auto> Per-glyph duration when staggering (default: auto)
|
|
56
|
+
--pressure <0-1> Variable stroke width for once/static (default: 1)
|
|
57
|
+
--smoothing Smooth strokes onto a spline
|
|
58
|
+
--segment-size <px> Stroke subdivision threshold (default: 2 when applicable)
|
|
59
|
+
-h, --help Show this help
|
|
60
|
+
-v, --version Show version
|
|
61
|
+
--list-fonts List bundled fonts
|
|
62
|
+
|
|
63
|
+
Examples:
|
|
64
|
+
tegaki "Tegaki is awesome"
|
|
65
|
+
tegaki "Hello World" --font tangerine --mode once -o hello.svg
|
|
66
|
+
tegaki "ABC" --stagger 80% --size 140 --color "#222"
|
|
67
|
+
`;
|
|
68
|
+
function fail(message) {
|
|
69
|
+
process.stderr.write(`tegaki: ${message}\n`);
|
|
70
|
+
process.exit(1);
|
|
71
|
+
}
|
|
72
|
+
/** Slugify text into a safe base filename. */
|
|
73
|
+
function slug(text) {
|
|
74
|
+
return text.trim().slice(0, 40).replace(/\s+/g, "-").replace(/[^\w-]/g, "").toLowerCase() || "tegaki";
|
|
75
|
+
}
|
|
76
|
+
function parseArgs(argv) {
|
|
77
|
+
const words = [];
|
|
78
|
+
const opts = {
|
|
79
|
+
text: "",
|
|
80
|
+
output: null,
|
|
81
|
+
font: "caveat",
|
|
82
|
+
fontSize: 100,
|
|
83
|
+
color: "#1a1a1a",
|
|
84
|
+
mode: "loop",
|
|
85
|
+
smoothing: false
|
|
86
|
+
};
|
|
87
|
+
const expectValue = (flag, inline, i) => {
|
|
88
|
+
if (inline !== void 0) return inline;
|
|
89
|
+
const next = argv[++i.v];
|
|
90
|
+
if (next === void 0) fail(`option ${flag} requires a value`);
|
|
91
|
+
return next;
|
|
92
|
+
};
|
|
93
|
+
const idx = { v: 0 };
|
|
94
|
+
for (idx.v = 0; idx.v < argv.length; idx.v++) {
|
|
95
|
+
const arg = argv[idx.v];
|
|
96
|
+
if (!arg.startsWith("-") || arg === "-") {
|
|
97
|
+
words.push(arg);
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const eq = arg.indexOf("=");
|
|
101
|
+
const flag = eq >= 0 ? arg.slice(0, eq) : arg;
|
|
102
|
+
const inline = eq >= 0 ? arg.slice(eq + 1) : void 0;
|
|
103
|
+
switch (flag) {
|
|
104
|
+
case "-h":
|
|
105
|
+
case "--help":
|
|
106
|
+
process.stdout.write(HELP);
|
|
107
|
+
process.exit(0);
|
|
108
|
+
break;
|
|
109
|
+
case "-v":
|
|
110
|
+
case "--version":
|
|
111
|
+
process.stdout.write(`${cachedVersion}\n`);
|
|
112
|
+
process.exit(0);
|
|
113
|
+
break;
|
|
114
|
+
case "--list-fonts":
|
|
115
|
+
listFonts();
|
|
116
|
+
process.exit(0);
|
|
117
|
+
break;
|
|
118
|
+
case "-o":
|
|
119
|
+
case "--output":
|
|
120
|
+
opts.output = expectValue(flag, inline, idx);
|
|
121
|
+
break;
|
|
122
|
+
case "-f":
|
|
123
|
+
case "--font":
|
|
124
|
+
opts.font = expectValue(flag, inline, idx).toLowerCase();
|
|
125
|
+
break;
|
|
126
|
+
case "-m":
|
|
127
|
+
case "--mode": {
|
|
128
|
+
const m = expectValue(flag, inline, idx);
|
|
129
|
+
if (!MODES.includes(m)) fail(`unknown mode "${m}" (expected: ${MODES.join(", ")})`);
|
|
130
|
+
opts.mode = m;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
case "--size":
|
|
134
|
+
opts.fontSize = numeric(flag, expectValue(flag, inline, idx));
|
|
135
|
+
break;
|
|
136
|
+
case "--line-height":
|
|
137
|
+
opts.lineHeight = numeric(flag, expectValue(flag, inline, idx));
|
|
138
|
+
break;
|
|
139
|
+
case "--color":
|
|
140
|
+
opts.color = expectValue(flag, inline, idx);
|
|
141
|
+
break;
|
|
142
|
+
case "--stagger":
|
|
143
|
+
opts.stagger = expectValue(flag, inline, idx);
|
|
144
|
+
break;
|
|
145
|
+
case "--stagger-duration": {
|
|
146
|
+
const v = expectValue(flag, inline, idx);
|
|
147
|
+
opts.staggerDuration = v === "auto" ? "auto" : numeric(flag, v);
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
case "--pressure":
|
|
151
|
+
opts.pressure = numeric(flag, expectValue(flag, inline, idx));
|
|
152
|
+
break;
|
|
153
|
+
case "--smoothing":
|
|
154
|
+
opts.smoothing = true;
|
|
155
|
+
break;
|
|
156
|
+
case "--segment-size":
|
|
157
|
+
opts.segmentSize = numeric(flag, expectValue(flag, inline, idx));
|
|
158
|
+
break;
|
|
159
|
+
default: fail(`unknown option "${flag}" (try --help)`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
opts.text = words.join(" ");
|
|
163
|
+
return opts;
|
|
164
|
+
}
|
|
165
|
+
function numeric(flag, value) {
|
|
166
|
+
const n = Number(value);
|
|
167
|
+
if (!Number.isFinite(n)) fail(`option ${flag} expects a number, got "${value}"`);
|
|
168
|
+
return n;
|
|
169
|
+
}
|
|
170
|
+
function listFonts() {
|
|
171
|
+
process.stdout.write("Bundled fonts:\n");
|
|
172
|
+
for (const [name, label] of Object.entries(FONTS)) process.stdout.write(` ${name.padEnd(18)} ${label}\n`);
|
|
173
|
+
}
|
|
174
|
+
let cachedVersion = "unknown";
|
|
175
|
+
async function resolveVersion() {
|
|
176
|
+
try {
|
|
177
|
+
const url = new URL("../package.json", import.meta.url);
|
|
178
|
+
const pkg = JSON.parse(await readFile(url, "utf-8"));
|
|
179
|
+
if (pkg.version) cachedVersion = pkg.version;
|
|
180
|
+
} catch {}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Load a built font bundle by name. Tries the shipped `dist/fonts/<name>` first
|
|
184
|
+
* (the `npx` path), then the source `fonts/<name>` (running from a checkout).
|
|
185
|
+
*/
|
|
186
|
+
async function loadBundle(name) {
|
|
187
|
+
if (!(name in FONTS)) fail(`unknown font "${name}". Run \`tegaki --list-fonts\` to see the ${Object.keys(FONTS).length} bundled fonts.`);
|
|
188
|
+
const candidates = [new URL(`./fonts/${name}/bundle.mjs`, import.meta.url), new URL(`../fonts/${name}/bundle.ts`, import.meta.url)];
|
|
189
|
+
for (const url of candidates) try {
|
|
190
|
+
const mod = await import(url.href);
|
|
191
|
+
if (mod?.default) return mod.default;
|
|
192
|
+
} catch {}
|
|
193
|
+
fail(`could not load font bundle "${name}".`);
|
|
194
|
+
}
|
|
195
|
+
async function main() {
|
|
196
|
+
await resolveVersion();
|
|
197
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
198
|
+
if (!opts.text) {
|
|
199
|
+
process.stdout.write(HELP);
|
|
200
|
+
process.exit(0);
|
|
201
|
+
}
|
|
202
|
+
if (NEEDS_SHAPING.has(opts.font)) process.stderr.write(`tegaki: note — "${opts.font}" is a complex/RTL script. The CLI lays glyphs out by advance width without shaping, so joins and direction may be wrong. Use the browser studio (gkurt.com/tegaki/studio) for shaped output.\n`);
|
|
203
|
+
const font = await loadBundle(opts.font);
|
|
204
|
+
const timing = opts.stagger !== void 0 ? { stagger: {
|
|
205
|
+
advance: /%$/.test(opts.stagger) ? opts.stagger : Number(opts.stagger),
|
|
206
|
+
duration: opts.staggerDuration ?? "auto"
|
|
207
|
+
} } : void 0;
|
|
208
|
+
const svg = textToSvg(opts.text, font, {
|
|
209
|
+
fontSize: opts.fontSize,
|
|
210
|
+
lineHeight: opts.lineHeight,
|
|
211
|
+
color: opts.color,
|
|
212
|
+
mode: opts.mode,
|
|
213
|
+
pressure: opts.pressure,
|
|
214
|
+
smoothing: opts.smoothing,
|
|
215
|
+
segmentSize: opts.segmentSize,
|
|
216
|
+
timing
|
|
217
|
+
});
|
|
218
|
+
if (opts.output === "-") {
|
|
219
|
+
process.stdout.write(svg);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const outPath = opts.output ?? `${slug(opts.text)}.svg`;
|
|
223
|
+
await writeFile(outPath, svg, "utf-8");
|
|
224
|
+
const kb = (Buffer.byteLength(svg, "utf-8") / 1024).toFixed(1);
|
|
225
|
+
process.stderr.write(`tegaki: wrote ${outPath} (${opts.mode}, ${FONTS[opts.font]}, ${kb} KB)\n`);
|
|
226
|
+
}
|
|
227
|
+
main().catch((err) => {
|
|
228
|
+
fail(err instanceof Error ? err.message : String(err));
|
|
229
|
+
});
|
|
230
|
+
//#endregion
|
|
231
|
+
export {};
|
|
232
|
+
|
|
233
|
+
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * `tegaki` — turn text into an animated handwriting SVG from the command line.\n *\n * npx tegaki \"Tegaki is awesome\" # → tegaki-is-awesome.svg (looping)\n * npx tegaki \"Hello\" -f tangerine -o hi.svg\n *\n * SVG is the only format emitted: it's the one the renderer can produce with\n * zero native dependencies (no canvas, no headless browser). Raster/video\n * export (PNG/GIF/WebM) lives in the browser studio at gkurt.com/tegaki/studio.\n */\nimport { readFile, writeFile } from 'node:fs/promises';\nimport { type TextToSvgMode, textToSvg } from './lib/textToSvg.ts';\nimport type { TegakiBundle } from './types.ts';\n\n/** Bundled fonts the CLI can load, keyed by `--font` name. */\nconst FONTS: Record<string, string> = {\n caveat: 'Caveat (Latin)',\n italianno: 'Italianno (Latin)',\n tangerine: 'Tangerine (Latin)',\n parisienne: 'Parisienne (Latin)',\n 'suez-one': 'Suez One (Hebrew + Latin)',\n amiri: 'Amiri (Arabic + Latin)',\n tillana: 'Tillana (Devanagari + Latin)',\n 'klee-one': 'Klee One (Japanese + Latin)',\n 'nanum-pen-script': 'Nanum Pen Script (Korean + Latin)',\n};\n\n/** Fonts whose scripts need shaping the headless CLI does not apply (RTL / complex GPOS). */\nconst NEEDS_SHAPING = new Set(['suez-one', 'amiri', 'tillana']);\n\nconst MODES: TextToSvgMode[] = ['loop', 'once', 'static'];\n\ninterface CliOptions {\n text: string;\n output: string | null; // null → derive from text; '-' → stdout\n font: string;\n fontSize: number;\n lineHeight?: number;\n color: string;\n mode: TextToSvgMode;\n stagger?: string;\n staggerDuration?: number | 'auto';\n pressure?: number;\n smoothing: boolean;\n segmentSize?: number;\n}\n\nconst HELP = `tegaki — animated handwriting SVG generator\n\nUsage:\n tegaki <text...> [options]\n\nOptions:\n -o, --output <file> Output path (default: <slug>.svg; \"-\" writes to stdout)\n -f, --font <name> Bundled font (default: caveat). See --list-fonts.\n -m, --mode <mode> loop | once | static (default: loop)\n loop self-drawing, repeats forever (README hero)\n once draws itself once, then stays complete\n static finished artwork, no animation\n --size <px> Font size in px (default: 100)\n --color <css> Stroke color (default: #1a1a1a)\n --line-height <px> Line height in px (default: from font metrics)\n --stagger <advance> Overlap glyphs instead of drawing them in sequence.\n e.g. \"80%\" (of the previous glyph) or \"0.3\" (seconds)\n --stagger-duration <s|auto> Per-glyph duration when staggering (default: auto)\n --pressure <0-1> Variable stroke width for once/static (default: 1)\n --smoothing Smooth strokes onto a spline\n --segment-size <px> Stroke subdivision threshold (default: 2 when applicable)\n -h, --help Show this help\n -v, --version Show version\n --list-fonts List bundled fonts\n\nExamples:\n tegaki \"Tegaki is awesome\"\n tegaki \"Hello World\" --font tangerine --mode once -o hello.svg\n tegaki \"ABC\" --stagger 80% --size 140 --color \"#222\"\n`;\n\nfunction fail(message: string): never {\n process.stderr.write(`tegaki: ${message}\\n`);\n process.exit(1);\n}\n\n/** Slugify text into a safe base filename. */\nfunction slug(text: string): string {\n const s = text\n .trim()\n .slice(0, 40)\n .replace(/\\s+/g, '-')\n .replace(/[^\\w-]/g, '')\n .toLowerCase();\n return s || 'tegaki';\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n const words: string[] = [];\n const opts: CliOptions = {\n text: '',\n output: null,\n font: 'caveat',\n fontSize: 100,\n color: '#1a1a1a',\n mode: 'loop',\n smoothing: false,\n };\n\n // Pull the value for a flag, supporting both `--flag value` and `--flag=value`.\n const expectValue = (flag: string, inline: string | undefined, i: { v: number }): string => {\n if (inline !== undefined) return inline;\n const next = argv[++i.v];\n if (next === undefined) fail(`option ${flag} requires a value`);\n return next;\n };\n\n const idx = { v: 0 };\n for (idx.v = 0; idx.v < argv.length; idx.v++) {\n const arg = argv[idx.v]!;\n if (!arg.startsWith('-') || arg === '-') {\n words.push(arg);\n continue;\n }\n const eq = arg.indexOf('=');\n const flag = eq >= 0 ? arg.slice(0, eq) : arg;\n const inline = eq >= 0 ? arg.slice(eq + 1) : undefined;\n\n switch (flag) {\n case '-h':\n case '--help':\n process.stdout.write(HELP);\n process.exit(0);\n break;\n case '-v':\n case '--version':\n process.stdout.write(`${cachedVersion}\\n`);\n process.exit(0);\n break;\n case '--list-fonts':\n listFonts();\n process.exit(0);\n break;\n case '-o':\n case '--output':\n opts.output = expectValue(flag, inline, idx);\n break;\n case '-f':\n case '--font':\n opts.font = expectValue(flag, inline, idx).toLowerCase();\n break;\n case '-m':\n case '--mode': {\n const m = expectValue(flag, inline, idx) as TextToSvgMode;\n if (!MODES.includes(m)) fail(`unknown mode \"${m}\" (expected: ${MODES.join(', ')})`);\n opts.mode = m;\n break;\n }\n case '--size':\n opts.fontSize = numeric(flag, expectValue(flag, inline, idx));\n break;\n case '--line-height':\n opts.lineHeight = numeric(flag, expectValue(flag, inline, idx));\n break;\n case '--color':\n opts.color = expectValue(flag, inline, idx);\n break;\n case '--stagger':\n opts.stagger = expectValue(flag, inline, idx);\n break;\n case '--stagger-duration': {\n const v = expectValue(flag, inline, idx);\n opts.staggerDuration = v === 'auto' ? 'auto' : numeric(flag, v);\n break;\n }\n case '--pressure':\n opts.pressure = numeric(flag, expectValue(flag, inline, idx));\n break;\n case '--smoothing':\n opts.smoothing = true;\n break;\n case '--segment-size':\n opts.segmentSize = numeric(flag, expectValue(flag, inline, idx));\n break;\n default:\n fail(`unknown option \"${flag}\" (try --help)`);\n }\n }\n\n opts.text = words.join(' ');\n return opts;\n}\n\nfunction numeric(flag: string, value: string): number {\n const n = Number(value);\n if (!Number.isFinite(n)) fail(`option ${flag} expects a number, got \"${value}\"`);\n return n;\n}\n\nfunction listFonts(): void {\n process.stdout.write('Bundled fonts:\\n');\n for (const [name, label] of Object.entries(FONTS)) {\n process.stdout.write(` ${name.padEnd(18)} ${label}\\n`);\n }\n}\n\n// Resolved once at startup (before args are parsed) so `--version` can print synchronously.\nlet cachedVersion = 'unknown';\nasync function resolveVersion(): Promise<void> {\n try {\n const url = new URL('../package.json', import.meta.url);\n const pkg = JSON.parse(await readFile(url, 'utf-8')) as { version?: string };\n if (pkg.version) cachedVersion = pkg.version;\n } catch {\n // leave default\n }\n}\n\n/**\n * Load a built font bundle by name. Tries the shipped `dist/fonts/<name>` first\n * (the `npx` path), then the source `fonts/<name>` (running from a checkout).\n */\nasync function loadBundle(name: string): Promise<TegakiBundle> {\n if (!(name in FONTS)) {\n fail(`unknown font \"${name}\". Run \\`tegaki --list-fonts\\` to see the ${Object.keys(FONTS).length} bundled fonts.`);\n }\n const candidates = [\n new URL(`./fonts/${name}/bundle.mjs`, import.meta.url), // built: dist/cli.mjs → dist/fonts/<name>/bundle.mjs\n new URL(`../fonts/${name}/bundle.ts`, import.meta.url), // dev: src/cli.ts → fonts/<name>/bundle.ts\n ];\n for (const url of candidates) {\n try {\n const mod = (await import(url.href)) as { default?: TegakiBundle };\n if (mod?.default) return mod.default;\n } catch {\n // try next candidate\n }\n }\n fail(`could not load font bundle \"${name}\".`);\n}\n\nasync function main(): Promise<void> {\n await resolveVersion();\n const opts = parseArgs(process.argv.slice(2));\n\n if (!opts.text) {\n process.stdout.write(HELP);\n process.exit(0);\n }\n\n if (NEEDS_SHAPING.has(opts.font)) {\n process.stderr.write(\n `tegaki: note — \"${opts.font}\" is a complex/RTL script. The CLI lays glyphs out by ` +\n `advance width without shaping, so joins and direction may be wrong. ` +\n `Use the browser studio (gkurt.com/tegaki/studio) for shaped output.\\n`,\n );\n }\n\n const font = await loadBundle(opts.font);\n\n const timing =\n opts.stagger !== undefined\n ? {\n stagger: {\n advance: /%$/.test(opts.stagger) ? (opts.stagger as `${number}%`) : Number(opts.stagger),\n duration: opts.staggerDuration ?? ('auto' as const),\n },\n }\n : undefined;\n\n const svg = textToSvg(opts.text, font, {\n fontSize: opts.fontSize,\n lineHeight: opts.lineHeight,\n color: opts.color,\n mode: opts.mode,\n pressure: opts.pressure,\n smoothing: opts.smoothing,\n segmentSize: opts.segmentSize,\n timing,\n });\n\n if (opts.output === '-') {\n process.stdout.write(svg);\n return;\n }\n\n const outPath = opts.output ?? `${slug(opts.text)}.svg`;\n await writeFile(outPath, svg, 'utf-8');\n const kb = (Buffer.byteLength(svg, 'utf-8') / 1024).toFixed(1);\n process.stderr.write(`tegaki: wrote ${outPath} (${opts.mode}, ${FONTS[opts.font]}, ${kb} KB)\\n`);\n}\n\nmain().catch((err: unknown) => {\n fail(err instanceof Error ? err.message : String(err));\n});\n"],"mappings":"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"}
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { S as TimedPoint, _ as TegakiEffectName, a as BBox, b as TegakiMultiEffectName, c as CSSLength, d as LineCap, f as PathCommand, g as TegakiEffectConfigs, h as TegakiBundle, i as ShapedGlyph, l as FontOutput, m as Stroke, o as BUNDLE_VERSION, p as Point, r as BundleShaper, s as COMPATIBLE_BUNDLE_VERSIONS, t as ShaperFactory, u as GlyphData, v as TegakiEffects, x as TegakiSingletonEffectName, y as TegakiGlyphData } from "../shaper-registry-
|
|
2
|
-
import { A as
|
|
3
|
-
export { BBox, BUNDLE_VERSION, BundleShaper, COMPATIBLE_BUNDLE_VERSIONS, CSSLength, CreateElementFn, EffectDefinition, FontOutput, GlyphData, LayoutBBox, LineCap, PathCommand, Point, RenderStageContext, ResolvedEffect, ShapedGlyph, ShaperFactory, Stroke, TegakiBundle, TegakiEffectConfigs, TegakiEffectName, TegakiEffects, TegakiEngine, TegakiEngineOptions, TegakiGlyphData, TegakiMultiEffectName, TegakiQuality, TegakiSingletonEffectName, TextLayout, TimeControlMode, TimeControlProp, TimedPoint, Timeline, TimelineConfig, TimelineEntry, TimelineStaggerConfig, buildChildren, buildRootProps, computeLayoutBbox, computeTextLayout, computeTimeline, createBundle, domCreateElement, drawGlyph, ensureFontFace, findEffect, findEffects, getBundle, getEffectDefinition, hasRenderHooks, registerBundle, resolveBundle, resolveEffects };
|
|
1
|
+
import { S as TimedPoint, _ as TegakiEffectName, a as BBox, b as TegakiMultiEffectName, c as CSSLength, d as LineCap, f as PathCommand, g as TegakiEffectConfigs, h as TegakiBundle, i as ShapedGlyph, l as FontOutput, m as Stroke, o as BUNDLE_VERSION, p as Point, r as BundleShaper, s as COMPATIBLE_BUNDLE_VERSIONS, t as ShaperFactory, u as GlyphData, v as TegakiEffects, x as TegakiSingletonEffectName, y as TegakiGlyphData } from "../shaper-registry-DmlJGnE3.mjs";
|
|
2
|
+
import { A as computeTextLayout, C as findEffects, D as LayoutBBox, E as resolveEffects, F as computeTimeline, M as TimelineConfig, N as TimelineEntry, O as TextLayout, P as TimelineStaggerConfig, S as findEffect, T as hasRenderHooks, _ as ensureFontFace, a as CreateElementFn, b as RenderStageContext, c as TimeControlMode, d as getBundle, f as registerBundle, g as textToSvg, h as TextToSvgOptions, i as TegakiEngine, j as Timeline, k as computeLayoutBbox, l as TimeControlProp, m as TextToSvgMode, n as buildRootProps, o as TegakiEngineOptions, p as resolveBundle, r as domCreateElement, s as TegakiQuality, t as buildChildren, u as createBundle, v as drawGlyph, w as getEffectDefinition, x as ResolvedEffect, y as EffectDefinition } from "../index-D-lHv505.mjs";
|
|
3
|
+
export { type BBox, BUNDLE_VERSION, type BundleShaper, COMPATIBLE_BUNDLE_VERSIONS, type CSSLength, type CreateElementFn, type EffectDefinition, type FontOutput, type GlyphData, type LayoutBBox, type LineCap, type PathCommand, type Point, type RenderStageContext, type ResolvedEffect, type ShapedGlyph, type ShaperFactory, type Stroke, type TegakiBundle, type TegakiEffectConfigs, type TegakiEffectName, type TegakiEffects, TegakiEngine, type TegakiEngineOptions, type TegakiGlyphData, type TegakiMultiEffectName, type TegakiQuality, type TegakiSingletonEffectName, type TextLayout, type TextToSvgMode, type TextToSvgOptions, type TimeControlMode, type TimeControlProp, type TimedPoint, type Timeline, type TimelineConfig, type TimelineEntry, type TimelineStaggerConfig, buildChildren, buildRootProps, computeLayoutBbox, computeTextLayout, computeTimeline, createBundle, domCreateElement, drawGlyph, ensureFontFace, findEffect, findEffects, getBundle, getEffectDefinition, hasRenderHooks, registerBundle, resolveBundle, resolveEffects, textToSvg };
|
package/dist/core/index.mjs
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import { _ as
|
|
2
|
-
|
|
1
|
+
import { _ as getEffectDefinition, a as createBundle, c as resolveBundle, d as computeLayoutBbox, f as computeTextLayout, g as findEffects, h as findEffect, i as domCreateElement, l as BUNDLE_VERSION, m as drawGlyph, n as buildChildren, o as getBundle, p as ensureFontFace, r as buildRootProps, s as registerBundle, t as TegakiEngine, u as COMPATIBLE_BUNDLE_VERSIONS, v as hasRenderHooks, y as resolveEffects } from "../core-VIBhSqFM.mjs";
|
|
2
|
+
import { n as computeTimeline, t as textToSvg } from "../textToSvg-GTQMM8Le.mjs";
|
|
3
|
+
export { BUNDLE_VERSION, COMPATIBLE_BUNDLE_VERSIONS, TegakiEngine, buildChildren, buildRootProps, computeLayoutBbox, computeTextLayout, computeTimeline, createBundle, domCreateElement, drawGlyph, ensureFontFace, findEffect, findEffects, getBundle, getEffectDefinition, hasRenderHooks, registerBundle, resolveBundle, resolveEffects, textToSvg };
|