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 +12 -0
- package/README.md +38 -169
- package/dist/core/index.d.mts +2 -0
- package/dist/core/index.mjs +2 -0
- package/dist/core-Cw5jNWFa.mjs +1128 -0
- package/dist/core-Cw5jNWFa.mjs.map +1 -0
- package/dist/index-Bmbc0eTI.d.mts +39 -0
- package/dist/index-YdGpXlqf.d.mts +333 -0
- package/dist/index.d.mts +3 -288
- package/dist/index.mjs +3 -922
- package/dist/react/index.d.mts +3 -0
- package/dist/react/index.mjs +3 -0
- package/dist/react-DfB_wEik.mjs +60 -0
- package/dist/react-DfB_wEik.mjs.map +1 -0
- package/dist/solid/index.d.mts +19 -0
- package/dist/solid/index.mjs +80 -0
- package/dist/solid/index.mjs.map +1 -0
- package/package.json +55 -4
- package/src/astro/TegakiRenderer.astro +128 -0
- package/src/core/engine.ts +900 -0
- package/src/core/index.ts +14 -0
- package/src/env.d.ts +12 -0
- package/src/index.ts +1 -12
- package/src/lib/css-properties.ts +24 -0
- package/src/lib/font.ts +29 -0
- package/src/react/TegakiRenderer.tsx +102 -0
- package/src/react/index.ts +2 -0
- package/src/solid/TegakiRenderer.tsx +100 -0
- package/src/solid/index.ts +2 -0
- package/src/svelte/TegakiRenderer.svelte +103 -0
- package/src/svelte/index.ts +2 -0
- package/src/vue/TegakiRenderer.vue +94 -0
- package/src/vue/index.ts +2 -0
- package/dist/index.mjs.map +0 -1
- package/src/lib/TegakiRenderer.tsx +0 -629
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
|
-
|
|
2
|
-
<img src="media/tegaki-card.png" alt="Tegaki" width="640" />
|
|
3
|
-
</p>
|
|
1
|
+
# Tegaki
|
|
4
2
|
|
|
5
|
-
|
|
3
|
+
**Handwriting animation for any font**
|
|
6
4
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
Tegaki (手書き) turns any Google Font into animated handwriting.
|
|
6
|
+
No manual path authoring. No native dependencies. Just pick a font.
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/tegaki)
|
|
9
|
+
[](https://github.com/KurtGokhan/tegaki/blob/main/LICENSE)
|
|
10
|
+
|
|
11
|
+
<br clear="both" />
|
|
11
12
|
|
|
12
13
|
<p align="center">
|
|
13
|
-
<
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
+
## Framework Support
|
|
132
45
|
|
|
133
|
-
|
|
46
|
+
Tegaki works with all major frameworks:
|
|
134
47
|
|
|
135
48
|
```tsx
|
|
136
|
-
|
|
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
|
-
```
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
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 {
|
|
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
|
-
##
|
|
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
|
-
|
|
67
|
+
Four handwriting fonts are bundled and ready to use:
|
|
188
68
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
-
|
|
74
|
+
For other Google Fonts, use the [interactive generator](https://gkurt.com/tegaki/generator/) to create a custom bundle.
|
|
201
75
|
|
|
202
|
-
|
|
203
|
-
|---------|-----|-------------|
|
|
204
|
-
| [`tegaki`](packages/renderer) | [](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
|
-
|
|
78
|
+
Visit **[gkurt.com/tegaki](https://gkurt.com/tegaki)** for full documentation:
|
|
208
79
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
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 };
|