@motion-proto/live-tokens 0.66.0 → 0.67.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 +132 -0
- package/dist-plugin/{chunk-NRONZ3T5.js → chunk-T4PMCFJN.js} +220 -114
- package/dist-plugin/index.cjs +253 -129
- package/dist-plugin/index.js +27 -9
- package/dist-plugin/migrateData/index.cjs +220 -114
- package/dist-plugin/migrateData/index.js +1 -1
- package/package.json +8 -1
- package/src/editor/bootstrap.ts +12 -0
- package/src/editor/core/productionPulse.ts +1 -1
- package/src/editor/core/sketch/index.ts +23 -27
- package/src/editor/core/sketch/maskField.ts +200 -62
- package/src/editor/core/sketch/sketchLayer.ts +10 -4
- package/src/editor/core/sketch/sketchRegistry.ts +98 -0
- package/src/editor/core/sketch/sketchStore.ts +64 -33
- package/src/editor/core/sketch/sketchStyleService.ts +3 -0
- package/src/editor/core/sketch/sketchStyles.ts +57 -96
- package/src/editor/docs/content/sketch-mode.md +56 -14
- package/src/editor/docs/content.generated.ts +1 -1
- package/src/editor/ui/sketch/SketchTab.svelte +219 -74
- package/src/live-tokens/data/sketch-styles/dashed.json +47 -0
- package/src/live-tokens/data/sketch-styles/dry.json +47 -0
- package/src/live-tokens/data/sketch-styles/hatched.json +47 -0
- package/src/live-tokens/data/sketch-styles/marker.json +47 -0
- package/src/live-tokens/data/sketch-styles/napkin.json +47 -0
- package/src/live-tokens/data/sketch-styles/pencil.json +47 -0
- package/src/live-tokens/data/sketch-styles/whiteboard.json +47 -0
- package/src/live-tokens/data/themes/autumn.json +4 -4
- package/src/live-tokens/data/themes/halloween.json +4 -4
- package/src/live-tokens/data/themes/midnight-study.json +4 -4
- package/src/live-tokens/data/themes/ocean.json +4 -4
- package/src/live-tokens/data/themes/royal-velvet.json +4 -4
- package/src/live-tokens/data/themes/sketchy.json +4 -4
- package/src/live-tokens/data/themes/spring-meadow.json +4 -4
- package/src/live-tokens/data/themes/sunset.json +4 -4
- package/src/system/components/Button.svelte +2 -2
- package/src/system/components/IconButton.svelte +2 -2
- package/src/system/styles/fonts.css +6 -6
- package/template/src/main.ts +14 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,137 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.67.0 — Every sketchstyle is a file
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **A saved sketchstyle ships with your site.** 0.66.0 carried the look a theme
|
|
8
|
+
holds into a build, which covers one look per theme. Everything else a project
|
|
9
|
+
saved in the Sketchstyle view stayed behind: the files live in
|
|
10
|
+
`src/live-tokens/data/sketch-styles/` and only the dev server could read them,
|
|
11
|
+
so a picker on a built site silently listed the shipped seven and nothing
|
|
12
|
+
else. Hand them to `bootLiveTokens` and they are real everywhere:
|
|
13
|
+
|
|
14
|
+
```ts
|
|
15
|
+
const files = import.meta.glob('./live-tokens/data/sketch-styles/*.json', {
|
|
16
|
+
eager: true,
|
|
17
|
+
import: 'default',
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
await bootLiveTokens(App, '#app', {
|
|
21
|
+
sketchLooks: Object.entries(files).map(([path, file]) => {
|
|
22
|
+
const id = path.split('/').pop().replace('.json', '');
|
|
23
|
+
return { id, label: file.name || id, settings: file.settings };
|
|
24
|
+
}),
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Unlike `components`, these register in a build as well as in dev. Reaching a
|
|
29
|
+
published site is the whole point of them.
|
|
30
|
+
|
|
31
|
+
`create` writes this into `src/main.ts`, so a new project publishes what it
|
|
32
|
+
saves without wiring anything.
|
|
33
|
+
|
|
34
|
+
- **A Save pill in the Sketchstyle view**, which writes the dials back over the
|
|
35
|
+
sketchstyle you have selected. Updating a saved sketchstyle used to run
|
|
36
|
+
through the naming form: open it, accept the pre-filled label, submit, and
|
|
37
|
+
nothing on screen said a file had been replaced rather than created. Save
|
|
38
|
+
lights as soon as the dials leave the sketchstyle they name. On one of your
|
|
39
|
+
own it writes that file; on a shipped one it writes your project's own copy
|
|
40
|
+
under the same name, which takes its place in the list, and deleting that file
|
|
41
|
+
brings the shipped look back. **Save As** always creates, and starts its form
|
|
42
|
+
empty to say so.
|
|
43
|
+
|
|
44
|
+
### Changed
|
|
45
|
+
|
|
46
|
+
- **Every sketchstyle ships as a file.** The seven looks were a constant in
|
|
47
|
+
`sketchStyles.ts`. The Sketchstyle view could save over one, but the thing it
|
|
48
|
+
saved over had no file to read, copy or compare against, so "restore the
|
|
49
|
+
shipped Pencil" meant trusting that a deleted file fell back to something
|
|
50
|
+
nobody could open. They now ship as JSON under
|
|
51
|
+
`src/live-tokens/data/sketch-styles/`, one per look, and the module reads
|
|
52
|
+
them: the file is the look.
|
|
53
|
+
|
|
54
|
+
A shipped sketchstyle behaves like a shipped colors-and-type. Save over one
|
|
55
|
+
and your project gets its own copy that shadows it; delete that copy and the
|
|
56
|
+
packaged file comes back. The listing marks which is which (`isPackage`), and
|
|
57
|
+
deleting a look that only the package ships answers 403 rather than reporting
|
|
58
|
+
success and leaving it on screen.
|
|
59
|
+
|
|
60
|
+
Pencil, Marker and Whiteboard ship with reworked ink coverage. Pencil's grain
|
|
61
|
+
is now stretched and turned rather than square (`maskBlobX` 40 to 525 at 67
|
|
62
|
+
degrees, on turbulence), Marker's blobs are twice the size over a much higher
|
|
63
|
+
floor with the softness off, and Whiteboard's streak is finer and harder with
|
|
64
|
+
more rotation on the jitter. The other four are unchanged.
|
|
65
|
+
|
|
66
|
+
- **Primary and secondary buttons rest one rung lower.**
|
|
67
|
+
`--button-primary-surface` moves from `--surface-brand-high` to
|
|
68
|
+
`--surface-brand` and `--button-secondary-surface` from
|
|
69
|
+
`--surface-neutral-high` to `--surface-neutral`, with `--iconbutton-*`
|
|
70
|
+
following. The border scale runs at the same lightness as the `-high` surface
|
|
71
|
+
rung, so a filled button was outlined in its own fill colour: the sketch
|
|
72
|
+
effect's hatch, which inks itself from the part's stroke, came out invisible
|
|
73
|
+
on exactly these two variants while Danger, Success, and Warning shaded
|
|
74
|
+
normally. Those three already rest on `-low`. This puts Primary and Secondary
|
|
75
|
+
on the rung Badge and CornerBadge already use, and lifts white text off the
|
|
76
|
+
surface by a further step. The eight preset themes carry the new value.
|
|
77
|
+
|
|
78
|
+
- **Ink coverage scales on two axes, and the px it states are the px it
|
|
79
|
+
paints.** The Scale dial fitted a whole number of blobs to a fixed 600px tile,
|
|
80
|
+
so it could only reach the sizes that divide 600: it read 250px at the top of
|
|
81
|
+
its travel and painted 300px, there was nothing above that at all, and every
|
|
82
|
+
reading in between was the nearest fit rather than the number on the dial. The
|
|
83
|
+
tile is now painted at whatever the dial says, which makes the px exact and
|
|
84
|
+
opens the travel to 8px speckle and 600px patches.
|
|
85
|
+
|
|
86
|
+
The dial is a pair, **Scale across** and **Scale down**, held together by a
|
|
87
|
+
chain. Click it and the two part company: blobs wider than they are tall read
|
|
88
|
+
as ink dragged sideways, taller than wide as a vertical grain, and the fill
|
|
89
|
+
keeps the same field underneath either way. Sketchstyles stored before the
|
|
90
|
+
split come back square and linked, which is the look they had.
|
|
91
|
+
|
|
92
|
+
Unlinked, a **Rotation** dial appears with them and points the stretch
|
|
93
|
+
wherever you like. It is offered only there because a field the same in every
|
|
94
|
+
direction is the same field turned. The tile still meets itself at every
|
|
95
|
+
setting: a turned pattern repeats seamlessly only at the angles that land the
|
|
96
|
+
page's own axes back on whole noise cells, so the dial takes the nearest of
|
|
97
|
+
those and reads back the turn it landed on, usually within a degree or two of
|
|
98
|
+
the one you asked for.
|
|
99
|
+
|
|
100
|
+
- **Shipped and saved sketchstyles are one list, in one id namespace.** A
|
|
101
|
+
sketchstyle named after a shipped one replaces it and keeps its place, so a
|
|
102
|
+
project that wants its own Pencil saves one. The Sketchstyle view shows a
|
|
103
|
+
single grid; the ✕ marks the rows your project owns.
|
|
104
|
+
|
|
105
|
+
### Fixed
|
|
106
|
+
|
|
107
|
+
- **Saving no longer reloads the page.** A project registers its saved
|
|
108
|
+
sketchstyles with `import.meta.glob`, which is what `create` writes into
|
|
109
|
+
`main.ts`, so writing one invalidated the entry module and Vite answered with
|
|
110
|
+
a full reload. The Sketchstyle view the save came from was torn down and
|
|
111
|
+
rebuilt mid-edit, which read as the editor closing itself every time you
|
|
112
|
+
pressed Save. The dev server now keeps every JSON under the data directory off
|
|
113
|
+
its watcher: the editor reads that directory over its own API and re-lists
|
|
114
|
+
after each write, so the page already holds what the reload would fetch.
|
|
115
|
+
`tokens.generated.css` and `fonts.css` stay watched, since the page really
|
|
116
|
+
does import them and CSS updates without a reload. A data file changed from
|
|
117
|
+
outside the editor, by a CLI run or a branch switch, now needs the page
|
|
118
|
+
reloaded by hand.
|
|
119
|
+
|
|
120
|
+
### Breaking
|
|
121
|
+
|
|
122
|
+
Pre-1.0, and the sketch API is days old. Every consumer we know of is in this
|
|
123
|
+
repo or in a site we own.
|
|
124
|
+
|
|
125
|
+
- `SKETCH_LOOKS` is now the `sketchLooks` store, since looks register after the
|
|
126
|
+
module is imported and a constant array would be stale. A picker reads
|
|
127
|
+
`$sketchLooks` the way it already reads `$themeSketchLook`.
|
|
128
|
+
- `USER_STYLE_PREFIX` and `selectSavedSketchStyle` are gone. A saved
|
|
129
|
+
sketchstyle's id is its file slug, so `setSketch(id)` and
|
|
130
|
+
`selectSketchStyle(id)` take it like any other.
|
|
131
|
+
- A `user:` id already in a browser's storage is stripped on read, so no
|
|
132
|
+
migration is needed and nobody loses their selection. Themes need nothing at
|
|
133
|
+
all: a theme has always stored its `sketchStyle` by value, never by id.
|
|
134
|
+
|
|
3
135
|
## 0.66.0 — A theme's sketchstyle reaches the built site
|
|
4
136
|
|
|
5
137
|
### Added
|
|
@@ -268,65 +268,38 @@ var KNOWN_COMPONENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
|
|
|
268
268
|
"--sectiondivider-sm-color-family"
|
|
269
269
|
]);
|
|
270
270
|
|
|
271
|
-
// src/
|
|
272
|
-
var
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
fillTravel: 1.5,
|
|
276
|
-
strokeTravel: 1.5,
|
|
277
|
-
wobble: 45,
|
|
278
|
-
roughness: 3,
|
|
279
|
-
borderWavelength: 1,
|
|
280
|
-
waveform: 1,
|
|
281
|
-
strokeWidth: 1.5,
|
|
282
|
-
doubleStroke: false,
|
|
283
|
-
retraceOffset: 1.2,
|
|
284
|
-
retracePass: "copy",
|
|
285
|
-
fillStyle: "solid",
|
|
286
|
-
hatchInk: 0.4,
|
|
287
|
-
strokeStyle: "solid",
|
|
288
|
-
pressure: 0.25,
|
|
289
|
-
pressureMod: 0.35,
|
|
290
|
-
pooling: 1.2,
|
|
291
|
-
strokeInk: 1,
|
|
292
|
-
maskOn: true,
|
|
293
|
-
maskBlob: 100,
|
|
294
|
-
maskOutputMin: 0.45,
|
|
295
|
-
maskOutputMax: 1,
|
|
296
|
-
maskOctaves: 2,
|
|
297
|
-
maskGrain: "fractal",
|
|
298
|
-
maskPosterize: 1,
|
|
299
|
-
maskSoftness: 1.5,
|
|
300
|
-
jitterX: 2.5,
|
|
301
|
-
jitterY: 2.5,
|
|
302
|
-
jitterRot: 0.6,
|
|
303
|
-
jitterScale: 0.035,
|
|
304
|
-
cornerSpread: 10,
|
|
305
|
-
cornerTravel: 8,
|
|
306
|
-
iconTravel: 1.25,
|
|
307
|
-
iconWavelength: 0.625,
|
|
308
|
-
iconMaskOn: true,
|
|
309
|
-
iconMaskScale: 1
|
|
310
|
-
};
|
|
311
|
-
var SKETCH_STYLES = {
|
|
312
|
-
pencil: {
|
|
313
|
-
...base,
|
|
271
|
+
// src/live-tokens/data/sketch-styles/pencil.json
|
|
272
|
+
var pencil_default = {
|
|
273
|
+
name: "Pencil",
|
|
274
|
+
settings: {
|
|
314
275
|
label: "Pencil",
|
|
315
276
|
blurb: "Two graphite passes on their own seeds, so the outline disagrees with itself the way a hand coming back round does. Tight grain, little else.",
|
|
316
277
|
fillTravel: 0.75,
|
|
317
278
|
strokeTravel: 1.25,
|
|
318
279
|
wobble: 30,
|
|
319
280
|
roughness: 3,
|
|
281
|
+
borderWavelength: 1,
|
|
320
282
|
waveform: 1,
|
|
321
283
|
strokeWidth: 1.25,
|
|
322
284
|
doubleStroke: true,
|
|
323
|
-
retracePass: "reseeded",
|
|
324
285
|
retraceOffset: 1.5,
|
|
286
|
+
retracePass: "reseeded",
|
|
287
|
+
fillStyle: "solid",
|
|
288
|
+
hatchInk: 0.4,
|
|
289
|
+
strokeStyle: "solid",
|
|
290
|
+
pressure: 0.15,
|
|
291
|
+
pressureMod: 0.3,
|
|
292
|
+
pooling: 0,
|
|
325
293
|
strokeInk: 0.85,
|
|
326
|
-
|
|
327
|
-
|
|
294
|
+
maskOn: true,
|
|
295
|
+
maskBlobX: 525,
|
|
296
|
+
maskBlobY: 47,
|
|
297
|
+
maskBlobLinked: false,
|
|
298
|
+
maskAngle: 67,
|
|
299
|
+
maskOutputMin: 0.59,
|
|
328
300
|
maskOutputMax: 1,
|
|
329
301
|
maskOctaves: 3,
|
|
302
|
+
maskGrain: "turbulence",
|
|
330
303
|
maskPosterize: 1,
|
|
331
304
|
maskSoftness: 0,
|
|
332
305
|
jitterX: 1.5,
|
|
@@ -335,147 +308,243 @@ var SKETCH_STYLES = {
|
|
|
335
308
|
jitterScale: 0.022,
|
|
336
309
|
cornerSpread: 6,
|
|
337
310
|
cornerTravel: 4.5,
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
311
|
+
iconTravel: 0.75,
|
|
312
|
+
iconWavelength: 0.625,
|
|
313
|
+
iconMaskOn: true,
|
|
314
|
+
iconMaskScale: 1
|
|
342
315
|
},
|
|
343
|
-
|
|
344
|
-
|
|
316
|
+
updatedAt: "2026-08-28T14:35:06.291Z",
|
|
317
|
+
createdAt: "2026-08-28T14:35:06.291Z"
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
// src/live-tokens/data/sketch-styles/marker.json
|
|
321
|
+
var marker_default = {
|
|
322
|
+
name: "Marker",
|
|
323
|
+
settings: {
|
|
345
324
|
label: "Marker",
|
|
346
325
|
blurb: "Broad translucent nib gone round twice on the same line, so the overlap darkens and the ink pools where it slows.",
|
|
347
326
|
fillTravel: 2,
|
|
348
327
|
strokeTravel: 1.5,
|
|
349
328
|
wobble: 56,
|
|
350
|
-
|
|
329
|
+
roughness: 3,
|
|
351
330
|
borderWavelength: 1.3,
|
|
331
|
+
waveform: 1.4,
|
|
352
332
|
strokeWidth: 4,
|
|
353
333
|
doubleStroke: true,
|
|
334
|
+
retraceOffset: 2.2,
|
|
354
335
|
retracePass: "copy",
|
|
336
|
+
fillStyle: "solid",
|
|
337
|
+
hatchInk: 0.4,
|
|
338
|
+
strokeStyle: "solid",
|
|
339
|
+
pressure: 0.2,
|
|
340
|
+
pressureMod: 0.25,
|
|
341
|
+
pooling: 2,
|
|
355
342
|
strokeInk: 0.52,
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
343
|
+
maskOn: true,
|
|
344
|
+
maskBlobX: 230,
|
|
345
|
+
maskBlobY: 230,
|
|
346
|
+
maskBlobLinked: true,
|
|
347
|
+
maskAngle: 0,
|
|
348
|
+
maskOutputMin: 0.76,
|
|
359
349
|
maskOutputMax: 1,
|
|
360
350
|
maskOctaves: 3,
|
|
351
|
+
maskGrain: "fractal",
|
|
361
352
|
maskPosterize: 4,
|
|
362
|
-
maskSoftness:
|
|
353
|
+
maskSoftness: 0,
|
|
363
354
|
jitterX: 3,
|
|
364
355
|
jitterY: 3,
|
|
365
356
|
jitterRot: 0.8,
|
|
366
357
|
jitterScale: 0.045,
|
|
367
358
|
cornerSpread: 10,
|
|
368
359
|
cornerTravel: 8,
|
|
369
|
-
pressure: 0.2,
|
|
370
|
-
pressureMod: 0.25,
|
|
371
|
-
pooling: 2,
|
|
372
360
|
iconTravel: 1.25,
|
|
361
|
+
iconWavelength: 0.625,
|
|
362
|
+
iconMaskOn: true,
|
|
373
363
|
iconMaskScale: 4
|
|
374
364
|
},
|
|
375
|
-
|
|
376
|
-
|
|
365
|
+
updatedAt: "2026-08-28T14:45:04.324Z",
|
|
366
|
+
createdAt: "2026-08-28T14:45:04.324Z"
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
// src/live-tokens/data/sketch-styles/whiteboard.json
|
|
370
|
+
var whiteboard_default = {
|
|
371
|
+
name: "Whiteboard",
|
|
372
|
+
settings: {
|
|
377
373
|
label: "Whiteboard",
|
|
378
374
|
blurb: "The fattest nib on glass. One long smooth undulation, and a veined mask that streaks the fill like a half-wiped board.",
|
|
379
375
|
fillTravel: 2.5,
|
|
380
376
|
strokeTravel: 2.5,
|
|
381
377
|
wobble: 90,
|
|
382
378
|
roughness: 1,
|
|
383
|
-
waveform: 1,
|
|
384
379
|
borderWavelength: 1.5,
|
|
380
|
+
waveform: 1,
|
|
385
381
|
strokeWidth: 5.5,
|
|
386
382
|
doubleStroke: true,
|
|
383
|
+
retraceOffset: 3,
|
|
387
384
|
retracePass: "copy",
|
|
385
|
+
fillStyle: "solid",
|
|
386
|
+
hatchInk: 0.4,
|
|
387
|
+
strokeStyle: "solid",
|
|
388
|
+
pressure: 0.15,
|
|
389
|
+
pressureMod: 0.15,
|
|
390
|
+
pooling: 3.5,
|
|
388
391
|
strokeInk: 0.66,
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
392
|
+
maskOn: true,
|
|
393
|
+
maskBlobX: 180,
|
|
394
|
+
maskBlobY: 38,
|
|
395
|
+
maskBlobLinked: false,
|
|
396
|
+
maskAngle: 0,
|
|
397
|
+
maskOutputMin: 0.68,
|
|
393
398
|
maskOutputMax: 1,
|
|
394
|
-
maskOctaves:
|
|
399
|
+
maskOctaves: 3,
|
|
400
|
+
maskGrain: "turbulence",
|
|
395
401
|
maskPosterize: 3,
|
|
396
|
-
maskSoftness:
|
|
402
|
+
maskSoftness: 0,
|
|
397
403
|
jitterX: 4.5,
|
|
398
404
|
jitterY: 4.5,
|
|
399
|
-
jitterRot:
|
|
405
|
+
jitterRot: 3,
|
|
400
406
|
jitterScale: 0.07,
|
|
401
407
|
cornerSpread: 14,
|
|
402
408
|
cornerTravel: 11,
|
|
403
|
-
pressure: 0.15,
|
|
404
|
-
pressureMod: 0.15,
|
|
405
|
-
pooling: 3.5,
|
|
406
409
|
iconTravel: 1.75,
|
|
410
|
+
iconWavelength: 0.625,
|
|
411
|
+
iconMaskOn: true,
|
|
407
412
|
iconMaskScale: 1.5
|
|
408
413
|
},
|
|
409
|
-
|
|
410
|
-
|
|
414
|
+
updatedAt: "2026-08-28T14:46:58.140Z",
|
|
415
|
+
createdAt: "2026-08-28T14:46:58.140Z"
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// src/live-tokens/data/sketch-styles/hatched.json
|
|
419
|
+
var hatched_default = {
|
|
420
|
+
name: "Hatched",
|
|
421
|
+
settings: {
|
|
411
422
|
label: "Hatched",
|
|
412
423
|
blurb: "An etching. The fill is angled shading, the outline a single hard-edged scratch that chatters along its length. No mask: the hatch is the texture.",
|
|
413
424
|
fillTravel: 1.25,
|
|
414
425
|
strokeTravel: 1.5,
|
|
415
426
|
wobble: 24,
|
|
416
427
|
roughness: 3,
|
|
428
|
+
borderWavelength: 1,
|
|
417
429
|
waveform: 3,
|
|
418
430
|
strokeWidth: 1.5,
|
|
431
|
+
doubleStroke: false,
|
|
432
|
+
retraceOffset: 1.2,
|
|
433
|
+
retracePass: "copy",
|
|
419
434
|
fillStyle: "hatched",
|
|
420
435
|
hatchInk: 0.5,
|
|
421
|
-
|
|
436
|
+
strokeStyle: "solid",
|
|
437
|
+
pressure: 0.3,
|
|
438
|
+
pressureMod: 0.45,
|
|
439
|
+
pooling: 0.8,
|
|
440
|
+
strokeInk: 1,
|
|
422
441
|
maskOn: false,
|
|
423
|
-
|
|
442
|
+
maskBlobX: 100,
|
|
443
|
+
maskBlobY: 100,
|
|
444
|
+
maskBlobLinked: true,
|
|
445
|
+
maskAngle: 0,
|
|
446
|
+
maskOutputMin: 0.45,
|
|
447
|
+
maskOutputMax: 1,
|
|
448
|
+
maskOctaves: 2,
|
|
449
|
+
maskGrain: "fractal",
|
|
450
|
+
maskPosterize: 1,
|
|
451
|
+
maskSoftness: 1.5,
|
|
424
452
|
jitterX: 1.5,
|
|
425
453
|
jitterY: 1.5,
|
|
426
454
|
jitterRot: 0.4,
|
|
427
455
|
jitterScale: 0.03,
|
|
428
456
|
cornerSpread: 6,
|
|
429
457
|
cornerTravel: 6,
|
|
430
|
-
pressure: 0.3,
|
|
431
|
-
pressureMod: 0.45,
|
|
432
|
-
pooling: 0.8,
|
|
433
458
|
iconTravel: 1.25,
|
|
434
|
-
iconWavelength: 0.5
|
|
459
|
+
iconWavelength: 0.5,
|
|
460
|
+
iconMaskOn: false,
|
|
461
|
+
iconMaskScale: 1
|
|
435
462
|
},
|
|
436
|
-
|
|
437
|
-
|
|
463
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
464
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
// src/live-tokens/data/sketch-styles/dashed.json
|
|
468
|
+
var dashed_default = {
|
|
469
|
+
name: "Dashed",
|
|
470
|
+
settings: {
|
|
438
471
|
label: "Dashed",
|
|
439
472
|
blurb: "A drafting outline. One slow drift along the ruler, broken into strokes, with jitter, mask and pressure all off. The clean pole.",
|
|
440
|
-
strokeStyle: "dashed",
|
|
441
|
-
strokeTravel: 1,
|
|
442
473
|
fillTravel: 0.5,
|
|
474
|
+
strokeTravel: 1,
|
|
443
475
|
wobble: 120,
|
|
444
476
|
roughness: 1,
|
|
477
|
+
borderWavelength: 1,
|
|
445
478
|
waveform: 1,
|
|
446
479
|
strokeWidth: 1.5,
|
|
447
480
|
doubleStroke: false,
|
|
481
|
+
retraceOffset: 1.2,
|
|
482
|
+
retracePass: "copy",
|
|
483
|
+
fillStyle: "solid",
|
|
484
|
+
hatchInk: 0.4,
|
|
485
|
+
strokeStyle: "dashed",
|
|
486
|
+
pressure: 0,
|
|
487
|
+
pressureMod: 0,
|
|
488
|
+
pooling: 0,
|
|
489
|
+
strokeInk: 1,
|
|
448
490
|
maskOn: false,
|
|
449
|
-
|
|
491
|
+
maskBlobX: 100,
|
|
492
|
+
maskBlobY: 100,
|
|
493
|
+
maskBlobLinked: true,
|
|
494
|
+
maskAngle: 0,
|
|
495
|
+
maskOutputMin: 0.45,
|
|
496
|
+
maskOutputMax: 1,
|
|
497
|
+
maskOctaves: 2,
|
|
498
|
+
maskGrain: "fractal",
|
|
499
|
+
maskPosterize: 1,
|
|
500
|
+
maskSoftness: 1.5,
|
|
450
501
|
jitterX: 0,
|
|
451
502
|
jitterY: 0,
|
|
452
503
|
jitterRot: 0,
|
|
453
504
|
jitterScale: 0,
|
|
454
505
|
cornerSpread: 4,
|
|
455
506
|
cornerTravel: 3,
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
507
|
+
iconTravel: 0,
|
|
508
|
+
iconWavelength: 0.625,
|
|
509
|
+
iconMaskOn: false,
|
|
510
|
+
iconMaskScale: 1
|
|
460
511
|
},
|
|
461
|
-
|
|
462
|
-
|
|
512
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
513
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
514
|
+
};
|
|
515
|
+
|
|
516
|
+
// src/live-tokens/data/sketch-styles/napkin.json
|
|
517
|
+
var napkin_default = {
|
|
518
|
+
name: "Napkin",
|
|
519
|
+
settings: {
|
|
463
520
|
label: "Napkin",
|
|
464
521
|
blurb: "Ballpoint in a hurry. Everything loose at once: a square wave sends every edge to full travel, and the second pass lands wherever it lands.",
|
|
465
522
|
fillTravel: 3,
|
|
466
523
|
strokeTravel: 2.25,
|
|
467
524
|
wobble: 50,
|
|
468
525
|
roughness: 3,
|
|
526
|
+
borderWavelength: 1,
|
|
469
527
|
waveform: 2.5,
|
|
470
528
|
strokeWidth: 2.25,
|
|
471
529
|
doubleStroke: true,
|
|
472
|
-
retracePass: "reseeded",
|
|
473
530
|
retraceOffset: 4,
|
|
531
|
+
retracePass: "reseeded",
|
|
532
|
+
fillStyle: "solid",
|
|
533
|
+
hatchInk: 0.4,
|
|
534
|
+
strokeStyle: "solid",
|
|
535
|
+
pressure: 0.45,
|
|
536
|
+
pressureMod: 0.6,
|
|
537
|
+
pooling: 2.5,
|
|
474
538
|
strokeInk: 1,
|
|
475
|
-
|
|
539
|
+
maskOn: true,
|
|
540
|
+
maskBlobX: 150,
|
|
541
|
+
maskBlobY: 150,
|
|
542
|
+
maskBlobLinked: true,
|
|
543
|
+
maskAngle: 0,
|
|
476
544
|
maskOutputMin: 0.43,
|
|
477
545
|
maskOutputMax: 0.95,
|
|
478
546
|
maskOctaves: 2,
|
|
547
|
+
maskGrain: "fractal",
|
|
479
548
|
maskPosterize: 2,
|
|
480
549
|
maskSoftness: 10,
|
|
481
550
|
jitterX: 6,
|
|
@@ -484,28 +553,47 @@ var SKETCH_STYLES = {
|
|
|
484
553
|
jitterScale: 0.1,
|
|
485
554
|
cornerSpread: 20,
|
|
486
555
|
cornerTravel: 17,
|
|
487
|
-
pressure: 0.45,
|
|
488
|
-
pressureMod: 0.6,
|
|
489
|
-
pooling: 2.5,
|
|
490
556
|
iconTravel: 2.25,
|
|
557
|
+
iconWavelength: 0.625,
|
|
558
|
+
iconMaskOn: true,
|
|
491
559
|
iconMaskScale: 3.6
|
|
492
560
|
},
|
|
493
|
-
|
|
494
|
-
|
|
561
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
562
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
563
|
+
};
|
|
564
|
+
|
|
565
|
+
// src/live-tokens/data/sketch-styles/dry.json
|
|
566
|
+
var dry_default = {
|
|
567
|
+
name: "Dry marker",
|
|
568
|
+
settings: {
|
|
495
569
|
label: "Dry marker",
|
|
496
570
|
blurb: "Ink that ran out. One scratchy pass that breaks up along its length, over a fill the mask has worn nearly through in patches.",
|
|
497
571
|
fillTravel: 2.25,
|
|
498
572
|
strokeTravel: 1.75,
|
|
499
573
|
wobble: 50,
|
|
500
|
-
|
|
574
|
+
roughness: 3,
|
|
501
575
|
borderWavelength: 0.5,
|
|
576
|
+
waveform: 2,
|
|
502
577
|
strokeWidth: 3.5,
|
|
503
578
|
doubleStroke: false,
|
|
579
|
+
retraceOffset: 1.2,
|
|
580
|
+
retracePass: "copy",
|
|
581
|
+
fillStyle: "solid",
|
|
582
|
+
hatchInk: 0.4,
|
|
583
|
+
strokeStyle: "solid",
|
|
584
|
+
pressure: 0.4,
|
|
585
|
+
pressureMod: 0.8,
|
|
586
|
+
pooling: 1.5,
|
|
504
587
|
strokeInk: 0.4,
|
|
505
|
-
|
|
588
|
+
maskOn: true,
|
|
589
|
+
maskBlobX: 150,
|
|
590
|
+
maskBlobY: 150,
|
|
591
|
+
maskBlobLinked: true,
|
|
592
|
+
maskAngle: 0,
|
|
506
593
|
maskOutputMin: 0.24,
|
|
507
594
|
maskOutputMax: 0.91,
|
|
508
595
|
maskOctaves: 2,
|
|
596
|
+
maskGrain: "fractal",
|
|
509
597
|
maskPosterize: 4,
|
|
510
598
|
maskSoftness: 1.75,
|
|
511
599
|
jitterX: 5,
|
|
@@ -514,26 +602,34 @@ var SKETCH_STYLES = {
|
|
|
514
602
|
jitterScale: 0.08,
|
|
515
603
|
cornerSpread: 16,
|
|
516
604
|
cornerTravel: 13,
|
|
517
|
-
pressure: 0.4,
|
|
518
|
-
pressureMod: 0.8,
|
|
519
|
-
pooling: 1.5,
|
|
520
605
|
iconTravel: 1.75,
|
|
606
|
+
iconWavelength: 0.625,
|
|
607
|
+
iconMaskOn: true,
|
|
521
608
|
iconMaskScale: 3.8
|
|
522
|
-
}
|
|
609
|
+
},
|
|
610
|
+
updatedAt: "2026-08-28T15:47:36.934Z",
|
|
611
|
+
createdAt: "2026-08-28T15:47:36.934Z"
|
|
523
612
|
};
|
|
613
|
+
|
|
614
|
+
// src/editor/core/sketch/sketchStyles.ts
|
|
615
|
+
var SHIPPED_FILES = { pencil: pencil_default, marker: marker_default, whiteboard: whiteboard_default, hatched: hatched_default, dashed: dashed_default, napkin: napkin_default, dry: dry_default };
|
|
616
|
+
var SKETCH_STYLES = Object.fromEntries(
|
|
617
|
+
Object.entries(SHIPPED_FILES).map(([id, file]) => [id, file.settings])
|
|
618
|
+
);
|
|
524
619
|
var DEFAULT_SKETCH_STYLE = "marker";
|
|
525
620
|
function hydrateSketchStyle(raw) {
|
|
526
|
-
const
|
|
621
|
+
const base = SKETCH_STYLES[DEFAULT_SKETCH_STYLE];
|
|
527
622
|
const stored = raw ?? {};
|
|
528
|
-
const out = { ...
|
|
529
|
-
for (const key of Object.keys(
|
|
623
|
+
const out = { ...base };
|
|
624
|
+
for (const key of Object.keys(base)) {
|
|
530
625
|
if (stored[key] !== void 0) out[key] = stored[key];
|
|
531
626
|
}
|
|
532
|
-
if (out.fillStyle === "none") out.fillStyle =
|
|
627
|
+
if (out.fillStyle === "none") out.fillStyle = base.fillStyle;
|
|
533
628
|
convertTiledMask(stored, out);
|
|
534
629
|
convertCutToLevels(stored, out);
|
|
535
630
|
carryLevelsToOutput(stored, out);
|
|
536
631
|
halveSwingDials(stored, out);
|
|
632
|
+
splitBlobAxes(stored, out);
|
|
537
633
|
convertCyclesToWavelength(stored, out);
|
|
538
634
|
convertIconTileToScale(stored, out);
|
|
539
635
|
restoreDerivedRetrace(stored, out);
|
|
@@ -565,6 +661,13 @@ function convertCyclesToWavelength(stored, out) {
|
|
|
565
661
|
const layers = stored.octaves;
|
|
566
662
|
if (typeof layers === "number") out.roughness = Math.min(3, Math.max(1, layers));
|
|
567
663
|
}
|
|
664
|
+
function splitBlobAxes(stored, out) {
|
|
665
|
+
const blob = stored.maskBlob;
|
|
666
|
+
if (typeof blob !== "number") return;
|
|
667
|
+
out.maskBlobX = blob;
|
|
668
|
+
out.maskBlobY = blob;
|
|
669
|
+
out.maskBlobLinked = true;
|
|
670
|
+
}
|
|
568
671
|
function convertIconTileToScale(stored, out) {
|
|
569
672
|
const tile = stored.iconMaskTile;
|
|
570
673
|
if (typeof tile !== "number") return;
|
|
@@ -580,7 +683,10 @@ function convertTiledMask(stored, out) {
|
|
|
580
683
|
const scale = stored.maskScale;
|
|
581
684
|
if (typeof scale !== "number") return;
|
|
582
685
|
const freq = stored.maskFrequency;
|
|
583
|
-
if (typeof freq === "number")
|
|
686
|
+
if (typeof freq === "number") {
|
|
687
|
+
out.maskBlobX = Math.round(scale / (freq * LEGACY_TILE));
|
|
688
|
+
out.maskBlobY = out.maskBlobX;
|
|
689
|
+
}
|
|
584
690
|
const soft = stored.maskSoftness;
|
|
585
691
|
if (typeof soft === "number") out.maskSoftness = Number((soft * scale / LEGACY_TILE).toFixed(1));
|
|
586
692
|
}
|
|
@@ -693,12 +799,12 @@ function normalizeTheme(raw, resolvers) {
|
|
|
693
799
|
}
|
|
694
800
|
const filled = { components: [], aliases: 0, orphans: 0 };
|
|
695
801
|
for (const comp of resolvers.listComponentNames()) {
|
|
696
|
-
const
|
|
697
|
-
const baseAliases =
|
|
698
|
-
if (!
|
|
802
|
+
const base = asObject(resolvers.readComponentConfig(comp, "default"));
|
|
803
|
+
const baseAliases = base ? asObject(base.aliases) : null;
|
|
804
|
+
if (!base || !baseAliases) continue;
|
|
699
805
|
const entry = componentConfigs[comp];
|
|
700
806
|
if (!entry) {
|
|
701
|
-
const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(
|
|
807
|
+
const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(base);
|
|
702
808
|
componentConfigs[comp] = structuredClone(rest);
|
|
703
809
|
filled.components.push(comp);
|
|
704
810
|
continue;
|