tegaki 0.5.0 → 0.7.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # tegaki
2
2
 
3
+ ## 0.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`be540e1`](https://github.com/KurtGokhan/tegaki/commit/be540e13d47804b2068ee111f0297ef4809d6550) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Remove extra wrapper div from TegakiRenderer DOM output. The engine now uses the adapter's container element directly as its root (`data-tegaki="root"`), eliminating a redundant nested div. This fixes CSS-controlled animations where styles applied to the `<TegakiRenderer>` component (like `animation-timeline`) weren't reaching the engine's root element. `renderElements` now returns `{ rootProps, content }` instead of a single element tree.
8
+
9
+ ## 0.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [`9288227`](https://github.com/KurtGokhan/tegaki/commit/9288227945a7623158990744809dc7d711536a7a) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Tegaki is framework agnostic now
14
+
3
15
  ## 0.5.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -1,58 +1,30 @@
1
- <p align="center">
2
- <img src="media/tegaki-card.png" alt="Tegaki" width="640" />
3
- </p>
1
+ # Tegaki
4
2
 
5
- <h3 align="center">Handwriting animation for any font</h3>
3
+ **Handwriting animation for any font**
6
4
 
7
- <p align="center">
8
- Tegaki (手書き) generates stroke data from fonts and renders animated handwriting in React.<br />
9
- No manual path authoring. No native dependencies. Just pick a font.
10
- </p>
5
+ Tegaki (手書き) turns any Google Font into animated handwriting.
6
+ No manual path authoring. No native dependencies. Just pick a font.
7
+
8
+ [![npm](https://img.shields.io/npm/v/tegaki)](https://www.npmjs.com/package/tegaki)
9
+ [![license](https://img.shields.io/npm/l/tegaki)](https://github.com/KurtGokhan/tegaki/blob/main/LICENSE)
10
+
11
+ <br clear="both" />
11
12
 
12
13
  <p align="center">
13
- <a href="https://www.npmjs.com/package/tegaki"><img src="https://img.shields.io/npm/v/tegaki" alt="npm" /></a>
14
- <a href="https://github.com/KurtGokhan/tegaki/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/tegaki" alt="license" /></a>
14
+ <img src="media/hello-world.svg" alt="Hello World handwriting animation" width="500" />
15
15
  </p>
16
16
 
17
17
  ---
18
18
 
19
- ## How it works
20
-
21
- **1. Generate** a font bundle from any Google Font using the [Tegaki website](https://tegaki.js.org/generator/):
22
-
23
- Each glyph is run through a processing pipeline — flatten bezier curves, rasterize, skeletonize via Zhang-Suen thinning, trace polylines, compute stroke widths via distance transform, determine stroke order — and the result is a set of animated SVGs with timing data.
24
-
25
- **2. Render** the animated text in React:
19
+ ## Quick Start
26
20
 
27
- ```tsx
28
- import { TegakiRenderer } from 'tegaki';
29
- import font from './output/caveat/bundle.ts';
30
-
31
- function App() {
32
- return (
33
- <TegakiRenderer font={font} style={{ fontSize: '48px' }}>
34
- Hello World
35
- </TegakiRenderer>
36
- );
37
- }
38
- ```
39
-
40
- The text draws itself stroke by stroke, with accurate widths and natural timing.
41
-
42
- ## Install
21
+ **1. Install**
43
22
 
44
23
  ```bash
45
24
  npm install tegaki
46
25
  ```
47
26
 
48
- ## Built-in fonts
49
-
50
- Tegaki ships with pre-generated bundles for four Google Fonts, ready to use without running the generator:
51
-
52
- - **Caveat** — `tegaki/fonts/caveat`
53
- - **Italianno** — `tegaki/fonts/italianno`
54
- - **Tangerine** — `tegaki/fonts/tangerine`
55
- - **Parisienne** — `tegaki/fonts/parisienne`
27
+ **2. Use** (React example)
56
28
 
57
29
  ```tsx
58
30
  import { TegakiRenderer } from 'tegaki';
@@ -67,151 +39,48 @@ function App() {
67
39
  }
68
40
  ```
69
41
 
70
- These bundles include all printable ASCII characters (letters, digits, punctuation). For other fonts, use the [generator on the Tegaki website](https://tegaki.js.org/generator/).
71
-
72
- All bundled fonts are licensed under the [SIL Open Font License](https://openfontlicense.org/). See [FONTS-LICENSE.md](packages/renderer/FONTS-LICENSE.md) for full attribution.
73
-
74
- ## `<TegakiRenderer>` props
75
-
76
- | Prop | Type | Default | Description |
77
- |------|------|---------|-------------|
78
- | `font` | `TegakiBundle` | — | Font bundle with animated glyph SVGs |
79
- | `text` | `string` | — | Text to animate (or pass as `children`) |
80
- | `children` | `string \| number` | — | Text content, coerced to string |
81
- | `time` | `TimeControlProp` | — | Time control mode (see below) |
82
- | `onComplete` | `() => void` | — | Called when animation reaches the end |
83
- | `mode` | `'svg' \| 'canvas'` | `'svg'` | Rendering mode |
84
- | `showOverlay` | `boolean` | `false` | Show debug text overlay |
85
-
86
- Plus all standard `<div>` props (`className`, `style`, etc.).
87
-
88
- ### Time control modes
89
-
90
- The `time` prop accepts three modes via a discriminated union:
91
-
92
- | Value | Mode | Description |
93
- |-------|------|-------------|
94
- | *omitted* | Uncontrolled | Auto-plays with default settings |
95
- | `number` | Controlled | Shorthand for `{ mode: 'controlled', value: n }` |
96
- | `'css'` | CSS | Shorthand for `{ mode: 'css' }` |
97
- | `{ mode: 'controlled', value }` | Controlled | You drive the time directly |
98
- | `{ mode: 'uncontrolled', ... }` | Uncontrolled | Component manages playback |
99
- | `{ mode: 'css' }` | CSS | Driven by `--tegaki-progress` CSS property |
100
-
101
- #### Uncontrolled
102
-
103
- The component manages its own playback — auto-plays on mount, responds to `speed`, `playing`, and `loop`.
104
-
105
- ```tsx
106
- // Default: auto-play at 1x
107
- <TegakiRenderer font={font}>Hello</TegakiRenderer>
108
-
109
- // With options
110
- <TegakiRenderer font={font} time={{ mode: 'uncontrolled', speed: 2, loop: true }}>
111
- Hello
112
- </TegakiRenderer>
113
- ```
114
-
115
- | Option | Type | Default | Description |
116
- |--------|------|---------|-------------|
117
- | `initialTime` | `number` | `0` | Starting time in seconds |
118
- | `speed` | `number` | `1` | Playback speed multiplier |
119
- | `playing` | `boolean` | `true` | Whether animation is playing |
120
- | `loop` | `boolean` | `false` | Restart when animation ends |
121
- | `onTimeChange` | `(time: number) => void` | — | Called each frame with current time |
122
-
123
- #### Controlled
124
-
125
- You provide the exact time. Useful for syncing with a slider, streaming text, or external state.
126
-
127
- ```tsx
128
- <TegakiRenderer font={font} time={currentTime}>Hello</TegakiRenderer>
129
- ```
42
+ That's it. The text draws itself stroke by stroke with natural timing.
130
43
 
131
- #### CSS
44
+ ## Framework Support
132
45
 
133
- Animation progress is driven by the `--tegaki-progress` CSS custom property (0–1). This enables pure-CSS control via animations, transitions, or scroll-timeline — no JS bridge needed.
46
+ Tegaki works with all major frameworks:
134
47
 
135
48
  ```tsx
136
- <TegakiRenderer font={font} time="css" style={...}>Hello</TegakiRenderer>
49
+ import { TegakiRenderer } from 'tegaki/react'; // React
50
+ import { TegakiRenderer } from 'tegaki/svelte'; // Svelte
51
+ import { TegakiRenderer } from 'tegaki/vue'; // Vue
52
+ import { TegakiRenderer } from 'tegaki/solid'; // SolidJS
137
53
  ```
138
54
 
139
- ```css
140
- /* Example: scroll-driven animation */
141
- .scroll-container {
142
- overflow-x: scroll;
143
- scroll-timeline: --tegaki inline;
144
- }
145
-
146
- .tegaki-wrapper {
147
- animation: tegaki-reveal linear both;
148
- animation-timeline: --tegaki;
149
- }
150
-
151
- @keyframes tegaki-reveal {
152
- from { --tegaki-progress: 0; }
153
- to { --tegaki-progress: 1; }
154
- }
55
+ ```astro
56
+ ---
57
+ import TegakiRenderer from 'tegaki/astro'; // Astro
58
+ ---
155
59
  ```
156
60
 
157
- ### CSS custom properties
158
-
159
- The component exposes these CSS custom properties on its root element in all modes:
160
-
161
- | Property | Direction | Description |
162
- |----------|-----------|-------------|
163
- | `--tegaki-duration` | Output | Total animation length in seconds |
164
- | `--tegaki-time` | Output | Current time in seconds |
165
- | `--tegaki-progress` | Input (CSS mode) / Output | Current progress (0–1) |
166
-
167
- All three are registered via `CSS.registerProperty` as `<number>` with `inherits: true`, making them animatable and transitionable.
168
-
169
- ### `computeTimeline(text, font)`
170
-
171
- Returns timing info for a string without rendering anything:
172
-
173
61
  ```ts
174
- import { computeTimeline } from 'tegaki';
175
-
176
- const { entries, totalDuration } = computeTimeline('Hello', font);
177
- // totalDuration: 2.45 (seconds)
178
- // entries: [{ char: 'H', offset: 0, duration: 0.52, hasSvg: true }, ...]
62
+ import { TegakiEngine } from 'tegaki/core'; // Vanilla JS
179
63
  ```
180
64
 
181
- ## Generating font bundles
182
-
183
- Use the [interactive generator on the Tegaki website](https://tegaki.js.org/generator/) to create font bundles from any Google Font. The generator lets you customize options like resolution, character set, and skeletonization algorithm, then download the output bundle to use in your app.
184
-
185
- ## Pipeline
65
+ ## Built-in Fonts
186
66
 
187
- The entire processing pipeline is pure TypeScript — no canvas, no native image libraries, no Python. It runs identically in Node/Bun and in the browser.
67
+ Four handwriting fonts are bundled and ready to use:
188
68
 
189
- ```
190
- Font file
191
- Flatten bezier curves to polylines
192
- Rasterize to binary bitmap (scanline fill, nonzero winding)
193
- → Skeletonize to 1px-wide skeleton (Zhang-Suen thinning)
194
- → Trace skeleton into polylines (spur pruning + RDP simplification)
195
- → Compute stroke width at each point (distance transform)
196
- → Order strokes top-to-bottom, left-to-right
197
- → Generate animated SVG with per-stroke timing
198
- ```
69
+ - **Caveat** — `tegaki/fonts/caveat`
70
+ - **Italianno** — `tegaki/fonts/italianno`
71
+ - **Tangerine** `tegaki/fonts/tangerine`
72
+ - **Parisienne** `tegaki/fonts/parisienne`
199
73
 
200
- ## Packages
74
+ For other Google Fonts, use the [interactive generator](https://gkurt.com/tegaki/generator/) to create a custom bundle.
201
75
 
202
- | Package | npm | Description |
203
- |---------|-----|-------------|
204
- | [`tegaki`](packages/renderer) | [![npm](https://img.shields.io/npm/v/tegaki)](https://www.npmjs.com/package/tegaki) | React component for animated handwriting |
205
- | [`@tegaki/website`](packages/website) | — | Website with interactive generator and preview |
76
+ ## Documentation
206
77
 
207
- ## Contributing
78
+ Visit **[gkurt.com/tegaki](https://gkurt.com/tegaki)** for full documentation:
208
79
 
209
- ```bash
210
- bun install # Install dependencies
211
- bun dev # Start dev server (website)
212
- bun start # Run the CLI (generator)
213
- bun checks # Lint + typecheck + tests
214
- ```
80
+ - [Getting Started](https://gkurt.com/tegaki/getting-started/)
81
+ - [Framework Guides](https://gkurt.com/tegaki/frameworks/react/) (React, Svelte, Vue, SolidJS, Astro, Vanilla)
82
+ - [Generating Fonts](https://gkurt.com/tegaki/guides/generating-fonts/)
83
+ - [API Reference](https://gkurt.com/tegaki/api/tegaki-renderer/)
215
84
 
216
85
  ## License
217
86
 
@@ -0,0 +1,2 @@
1
+ import { A as TegakiSingletonEffectName, C as Stroke, D as TegakiEffects, E as TegakiEffectName, O as TegakiGlyphData, S as Point, T as TegakiEffectConfigs, _ as CSSLength, a as TimeControlProp, b as LineCap, c as TimelineEntry, d as computeTextLayout, f as ensureFontFace, g as BBox, h as resolveEffects, i as TimeControlMode, j as TimedPoint, k as TegakiMultiEffectName, l as computeTimeline, m as ResolvedEffect, n as TegakiEngine, o as Timeline, p as drawGlyph, r as TegakiEngineOptions, s as TimelineConfig, t as CreateElementFn, u as TextLayout, v as FontOutput, w as TegakiBundle, x as PathCommand, y as GlyphData } from "../index-YdGpXlqf.mjs";
2
+ export { BBox, CSSLength, CreateElementFn, FontOutput, GlyphData, LineCap, PathCommand, Point, ResolvedEffect, Stroke, TegakiBundle, TegakiEffectConfigs, TegakiEffectName, TegakiEffects, TegakiEngine, TegakiEngineOptions, TegakiGlyphData, TegakiMultiEffectName, TegakiSingletonEffectName, TextLayout, TimeControlMode, TimeControlProp, TimedPoint, Timeline, TimelineConfig, TimelineEntry, computeTextLayout, computeTimeline, drawGlyph, ensureFontFace, resolveEffects };
@@ -0,0 +1,2 @@
1
+ import { a as drawGlyph, i as ensureFontFace, n as computeTimeline, r as computeTextLayout, s as resolveEffects, t as TegakiEngine } from "../core-Cw5jNWFa.mjs";
2
+ export { TegakiEngine, computeTextLayout, computeTimeline, drawGlyph, ensureFontFace, resolveEffects };