tegaki 0.5.0 → 0.6.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 +6 -0
- package/README.md +33 -160
- package/dist/core/index.d.mts +2 -0
- package/dist/core/index.mjs +2 -0
- package/dist/core-aZknK_0L.mjs +1121 -0
- package/dist/core-aZknK_0L.mjs.map +1 -0
- package/dist/index-BUNd9bnS.d.mts +39 -0
- package/dist/index-Bzxy01Zq.d.mts +329 -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-Ddx6VfJc.mjs +53 -0
- package/dist/react-Ddx6VfJc.mjs.map +1 -0
- package/dist/solid/index.d.mts +19 -0
- package/dist/solid/index.mjs +77 -0
- package/dist/solid/index.mjs.map +1 -0
- package/package.json +55 -4
- package/src/astro/TegakiRenderer.astro +126 -0
- package/src/core/engine.ts +878 -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 +98 -0
- package/src/react/index.ts +2 -0
- package/src/solid/TegakiRenderer.tsx +99 -0
- package/src/solid/index.ts +2 -0
- package/src/svelte/TegakiRenderer.svelte +90 -0
- package/src/svelte/index.ts +2 -0
- package/src/vue/TegakiRenderer.vue +95 -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,11 @@
|
|
|
1
1
|
# tegaki
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`9288227`](https://github.com/KurtGokhan/tegaki/commit/9288227945a7623158990744809dc7d711536a7a) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Tegaki is framework agnostic now
|
|
8
|
+
|
|
3
9
|
## 0.5.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<h3 align="center">Handwriting animation for any font</h3>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
|
-
Tegaki (手書き)
|
|
8
|
+
Tegaki (手書き) turns any Google Font into animated handwriting.<br />
|
|
9
9
|
No manual path authoring. No native dependencies. Just pick a font.
|
|
10
10
|
</p>
|
|
11
11
|
|
|
@@ -14,45 +14,21 @@
|
|
|
14
14
|
<a href="https://github.com/KurtGokhan/tegaki/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/tegaki" alt="license" /></a>
|
|
15
15
|
</p>
|
|
16
16
|
|
|
17
|
-
|
|
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:
|
|
26
|
-
|
|
27
|
-
```tsx
|
|
28
|
-
import { TegakiRenderer } from 'tegaki';
|
|
29
|
-
import font from './output/caveat/bundle.ts';
|
|
17
|
+
<p align="center">
|
|
18
|
+
<img src="media/hello-world.svg" alt="Hello World handwriting animation" width="500" />
|
|
19
|
+
</p>
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<TegakiRenderer font={font} style={{ fontSize: '48px' }}>
|
|
34
|
-
Hello World
|
|
35
|
-
</TegakiRenderer>
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
```
|
|
21
|
+
---
|
|
39
22
|
|
|
40
|
-
|
|
23
|
+
## Quick Start
|
|
41
24
|
|
|
42
|
-
|
|
25
|
+
**1. Install**
|
|
43
26
|
|
|
44
27
|
```bash
|
|
45
28
|
npm install tegaki
|
|
46
29
|
```
|
|
47
30
|
|
|
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`
|
|
31
|
+
**2. Use** (React example)
|
|
56
32
|
|
|
57
33
|
```tsx
|
|
58
34
|
import { TegakiRenderer } from 'tegaki';
|
|
@@ -67,151 +43,48 @@ function App() {
|
|
|
67
43
|
}
|
|
68
44
|
```
|
|
69
45
|
|
|
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
|
|
46
|
+
That's it. The text draws itself stroke by stroke with natural timing.
|
|
75
47
|
|
|
76
|
-
|
|
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 |
|
|
48
|
+
## Framework Support
|
|
85
49
|
|
|
86
|
-
|
|
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`.
|
|
50
|
+
Tegaki works with all major frameworks:
|
|
104
51
|
|
|
105
52
|
```tsx
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
<TegakiRenderer font={font} time={{ mode: 'uncontrolled', speed: 2, loop: true }}>
|
|
111
|
-
Hello
|
|
112
|
-
</TegakiRenderer>
|
|
53
|
+
import { TegakiRenderer } from 'tegaki/react'; // React
|
|
54
|
+
import { TegakiRenderer } from 'tegaki/svelte'; // Svelte
|
|
55
|
+
import { TegakiRenderer } from 'tegaki/vue'; // Vue
|
|
56
|
+
import { TegakiRenderer } from 'tegaki/solid'; // SolidJS
|
|
113
57
|
```
|
|
114
58
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
```
|
|
130
|
-
|
|
131
|
-
#### CSS
|
|
132
|
-
|
|
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.
|
|
134
|
-
|
|
135
|
-
```tsx
|
|
136
|
-
<TegakiRenderer font={font} time="css" style={...}>Hello</TegakiRenderer>
|
|
137
|
-
```
|
|
138
|
-
|
|
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
|
-
}
|
|
59
|
+
```astro
|
|
60
|
+
---
|
|
61
|
+
import TegakiRenderer from 'tegaki/astro'; // Astro
|
|
62
|
+
---
|
|
155
63
|
```
|
|
156
64
|
|
|
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
65
|
```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 }, ...]
|
|
66
|
+
import { TegakiEngine } from 'tegaki/core'; // Vanilla JS
|
|
179
67
|
```
|
|
180
68
|
|
|
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
|
|
69
|
+
## Built-in Fonts
|
|
186
70
|
|
|
187
|
-
|
|
71
|
+
Four handwriting fonts are bundled and ready to use:
|
|
188
72
|
|
|
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
|
-
```
|
|
73
|
+
- **Caveat** — `tegaki/fonts/caveat`
|
|
74
|
+
- **Italianno** — `tegaki/fonts/italianno`
|
|
75
|
+
- **Tangerine** — `tegaki/fonts/tangerine`
|
|
76
|
+
- **Parisienne** — `tegaki/fonts/parisienne`
|
|
199
77
|
|
|
200
|
-
|
|
78
|
+
For other Google Fonts, use the [interactive generator](https://gkurt.com/tegaki/generator/) to create a custom bundle.
|
|
201
79
|
|
|
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 |
|
|
80
|
+
## Documentation
|
|
206
81
|
|
|
207
|
-
|
|
82
|
+
Visit **[gkurt.com/tegaki](https://gkurt.com/tegaki)** for full documentation:
|
|
208
83
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
bun checks # Lint + typecheck + tests
|
|
214
|
-
```
|
|
84
|
+
- [Getting Started](https://gkurt.com/tegaki/getting-started/)
|
|
85
|
+
- [Framework Guides](https://gkurt.com/tegaki/frameworks/react/) (React, Svelte, Vue, SolidJS, Astro, Vanilla)
|
|
86
|
+
- [Generating Fonts](https://gkurt.com/tegaki/guides/generating-fonts/)
|
|
87
|
+
- [API Reference](https://gkurt.com/tegaki/api/tegaki-renderer/)
|
|
215
88
|
|
|
216
89
|
## License
|
|
217
90
|
|
|
@@ -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-Bzxy01Zq.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 };
|