@heyramzi/ui 2.11.0 → 2.11.2
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/dist/agents/helpers.js +38 -38
- package/dist/agents/page-state.js +49 -50
- package/dist/agents/vendor/color.js +146 -127
- package/dist/agents/vendor/draw.js +617 -508
- package/dist/agents/vendor/engine.js +698 -599
- package/dist/agents/vendor/mesh.js +653 -683
- package/dist/agents/vendor/plastic.js +3913 -3112
- package/dist/agents/vendor/presets.js +163 -164
- package/dist/agents/vendor/shapes.js +21 -20
- package/dist/agents/vendor/ticker.js +41 -42
- package/dist/agents/vendor/types.js +1 -0
- package/dist/agents/vendor/wear.js +1421 -1448
- package/dist/ai/confirmation/confirmation-context.svelte.js +6 -6
- package/dist/ai/confirmation/index.js +3 -1
- package/dist/ai/index.js +33 -0
- package/dist/ai/prompt-input/index.js +3 -1
- package/dist/ai/reasoning/index.js +3 -1
- package/dist/ai/reasoning/reasoning-context.svelte.js +6 -6
- package/dist/ai/suggestion/index.js +3 -1
- package/dist/ai/typing-dots/index.js +3 -1
- package/dist/animations/text-swap.js +24 -24
- package/dist/brand/index.js +54 -48
- package/dist/canvas/card/resize.js +5 -3
- package/dist/canvas/edges/edge-path.js +255 -242
- package/dist/canvas/editor/context-menu.js +39 -36
- package/dist/canvas/editor/dispatch.svelte.js +154 -151
- package/dist/canvas/editor/editor-context.js +7 -2
- package/dist/canvas/editor/editor-mode.js +1 -0
- package/dist/canvas/editor/frame.js +73 -76
- package/dist/canvas/editor/hand-context.js +5 -2
- package/dist/canvas/editor/history-core.js +163 -191
- package/dist/canvas/editor/keymap.js +95 -169
- package/dist/canvas/editor/layout-actions.js +143 -144
- package/dist/canvas/editor/lock.js +52 -51
- package/dist/canvas/editor/rebase.js +217 -240
- package/dist/canvas/editor/style.js +132 -137
- package/dist/canvas/editor/text-field-context.js +7 -2
- package/dist/canvas/editor/z-order.js +65 -70
- package/dist/canvas/headless/alignment.js +22 -16
- package/dist/canvas/headless/break-apart-find.js +286 -279
- package/dist/canvas/headless/break-apart-pieces.js +62 -58
- package/dist/canvas/headless/break-apart-plan.js +299 -325
- package/dist/canvas/headless/break-apart-style.js +75 -70
- package/dist/canvas/headless/break-apart.js +188 -181
- package/dist/canvas/headless/canvas-cleanup.js +78 -58
- package/dist/canvas/headless/edge-anchors.js +115 -116
- package/dist/canvas/headless/edge-memo.js +24 -22
- package/dist/canvas/headless/edge-serialization.js +17 -27
- package/dist/canvas/headless/figure-geometry.js +232 -264
- package/dist/canvas/headless/fit-viewport.js +84 -67
- package/dist/canvas/headless/grid.js +88 -86
- package/dist/canvas/headless/icon-node.js +44 -36
- package/dist/canvas/headless/index.js +1 -0
- package/dist/canvas/headless/linkify.js +17 -19
- package/dist/canvas/headless/pen-marks.js +101 -95
- package/dist/canvas/headless/sketch.js +231 -209
- package/dist/canvas/headless/snap-guides.js +99 -83
- package/dist/canvas/headless/svg-figure.js +133 -117
- package/dist/canvas/headless/table-layout.js +146 -107
- package/dist/canvas/index.js +2 -0
- package/dist/canvas/lod/lod-mode.svelte.js +20 -18
- package/dist/canvas/lod/render-all.svelte.js +36 -39
- package/dist/canvas/ops/arrange.js +78 -71
- package/dist/canvas/ops/ops.js +260 -255
- package/dist/canvas/pen/colors.js +37 -35
- package/dist/canvas/pen/eraser.js +28 -27
- package/dist/canvas/pen/geometry.js +120 -130
- package/dist/canvas/pen/index.js +1 -0
- package/dist/canvas/pen/ops.js +11 -11
- package/dist/canvas/pen/pen-session.js +150 -159
- package/dist/canvas/pen/plugin.js +107 -104
- package/dist/canvas/pen/shapes.js +73 -68
- package/dist/canvas/pen/stroke-path.js +32 -30
- package/dist/canvas/pen/types.js +21 -21
- package/dist/canvas/pen/ui.js +10 -8
- package/dist/canvas/plugin.js +46 -46
- package/dist/canvas/screen/glyphs.js +12 -11
- package/dist/canvas/screen/labels.js +22 -22
- package/dist/canvas/screen/parts.js +98 -111
- package/dist/canvas/screen/plugin.js +47 -56
- package/dist/canvas/screen/types.js +30 -35
- package/dist/canvas/screen/ui.js +7 -7
- package/dist/canvas/test-utils.js +14 -14
- package/dist/canvas/types.js +1 -0
- package/dist/canvas/ui/forward-wheel.js +24 -25
- package/dist/canvas/ui/icons.js +64 -131
- package/dist/canvas/ui/place-panel.js +58 -49
- package/dist/canvas/ui/shortcut-tip.js +14 -12
- package/dist/canvas/ui/tools.js +300 -385
- package/dist/charts/dashboard/chart.js +4 -0
- package/dist/charts/dashboard/data-table.js +11 -0
- package/dist/charts/dashboard/windows.js +8 -3
- package/dist/charts/edge-fade.js +10 -5
- package/dist/charts/hover-band.js +16 -11
- package/dist/charts/index.js +0 -1
- package/dist/charts/motion.js +11 -7
- package/dist/charts/primitives/chart-utils.js +12 -12
- package/dist/components/copy/clipboard.js +32 -32
- package/dist/components/copy/copied.svelte.js +31 -23
- package/dist/components/data-table/data-table.js +39 -39
- package/dist/components/docs/index.js +4 -0
- package/dist/components/docs/scroll-spy.svelte.js +73 -68
- package/dist/components/list-page/filter-section.js +4 -1
- package/dist/components/list-page/index.js +2 -0
- package/dist/components/list-page/list-table.js +7 -2
- package/dist/components/list-page/queue-rail.js +14 -0
- package/dist/components/list-page/section-host.js +4 -2
- package/dist/components/list-page/step.js +4 -3
- package/dist/components/list-page/types.js +1 -0
- package/dist/components/picker/trigger.js +48 -30
- package/dist/components/picker/types.js +1 -0
- package/dist/components/segmented/collapse.js +38 -27
- package/dist/components/segmented/index.js +8 -0
- package/dist/components/segmented/segmented.js +67 -42
- package/dist/components/star-rating-input/index.js +3 -1
- package/dist/components/table-view/types.js +1 -0
- package/dist/components/tags-input/tags.js +81 -69
- package/dist/components/theme/index.js +4 -0
- package/dist/components/toolbar/index.js +4 -0
- package/dist/components/toolbar/toolbar-trigger.js +14 -1
- package/dist/editor/anchors.js +17 -13
- package/dist/editor/block-id.js +52 -51
- package/dist/editor/block-ops.js +108 -80
- package/dist/editor/doc-blocks.js +155 -166
- package/dist/editor/extensions.js +139 -180
- package/dist/editor/index.js +4 -0
- package/dist/editor/markdown-test-helpers.js +4 -2
- package/dist/editor/markdown.js +420 -408
- package/dist/editor/serializer.js +204 -200
- package/dist/editor/slash-items.js +89 -101
- package/dist/editor/youtube-url.js +25 -20
- package/dist/effects/animated-beam/path-calculator.svelte.js +43 -38
- package/dist/effects/animated-beam/types.js +1 -0
- package/dist/effects/border-beam/css.js +92 -78
- package/dist/effects/border-beam/presets.js +1705 -1720
- package/dist/effects/border-beam/register-properties.js +43 -33
- package/dist/effects/border-beam/types.js +1 -0
- package/dist/effects/image-comparison/compare.js +3 -2
- package/dist/effects/image-reveal/types.js +1 -0
- package/dist/effects/magnetic/magnetic.js +58 -52
- package/dist/effects/reveal/observe.js +50 -40
- package/dist/effects/reveal/types.js +1 -0
- package/dist/effects/shader-gradient/color.js +36 -29
- package/dist/effects/shader-gradient/renderer.js +384 -295
- package/dist/effects/shader-gradient/shaders.js +31 -0
- package/dist/effects/shader-gradient/types.js +1 -0
- package/dist/icons/apple-symbol-exports.js +99 -124
- package/dist/icons/sf-symbols.js +357 -461
- package/dist/icons/trades.js +43 -28
- package/dist/inbox/index.js +1 -0
- package/dist/inbox/logic.js +126 -122
- package/dist/inbox/types.js +43 -43
- package/dist/lib/arrive.js +19 -12
- package/dist/lib/icon-types.js +1 -0
- package/dist/lib/initials.js +16 -10
- package/dist/lib/layout.js +5 -0
- package/dist/lib/panel.js +13 -0
- package/dist/lib/result.js +22 -22
- package/dist/lib/sliding-pill.js +59 -44
- package/dist/lib/theme-transition.js +43 -43
- package/dist/lib/tone.js +31 -24
- package/dist/lib/utils.js +3 -1
- package/dist/onboarding/define-tours.js +24 -23
- package/dist/onboarding/onboarding.svelte.js +16 -12
- package/dist/onboarding/pick.js +10 -6
- package/dist/onboarding/stores.js +40 -41
- package/dist/onboarding/wait.js +24 -23
- package/dist/panel/side-panel-types.js +1 -0
- package/dist/record/demo-data.js +459 -486
- package/dist/record/fields.js +129 -131
- package/dist/record/format.js +70 -82
- package/dist/record/gutter.js +1 -0
- package/dist/record/kinds.js +95 -105
- package/dist/record/logic.js +238 -219
- package/dist/record/types.js +49 -48
- package/dist/shadcn/accordion/index.js +3 -1
- package/dist/shadcn/alert/index.js +3 -1
- package/dist/shadcn/alert-dialog/index.js +3 -1
- package/dist/shadcn/attachment/index.js +3 -1
- package/dist/shadcn/avatar/index.js +3 -1
- package/dist/shadcn/breadcrumb/index.js +3 -1
- package/dist/shadcn/bubble/index.js +3 -1
- package/dist/shadcn/button/index.js +3 -1
- package/dist/shadcn/calendar/index.js +3 -1
- package/dist/shadcn/card/index.js +3 -1
- package/dist/shadcn/checkbox/index.js +3 -1
- package/dist/shadcn/code-block/index.js +3 -1
- package/dist/shadcn/collapsible/index.js +3 -1
- package/dist/shadcn/command/index.js +4 -1
- package/dist/shadcn/context-menu/index.js +3 -1
- package/dist/shadcn/dialog/index.js +3 -1
- package/dist/shadcn/dropdown-menu/menu-item.js +40 -20
- package/dist/shadcn/empty/index.js +3 -1
- package/dist/shadcn/field/index.js +3 -1
- package/dist/shadcn/hooks/highlighter.js +77 -75
- package/dist/shadcn/hooks/is-mobile.svelte.js +3 -3
- package/dist/shadcn/hooks/use-highlighted-code.svelte.js +62 -62
- package/dist/shadcn/input/index.js +3 -1
- package/dist/shadcn/kbd/index.js +3 -1
- package/dist/shadcn/label/index.js +3 -1
- package/dist/shadcn/marker/index.js +3 -1
- package/dist/shadcn/message/index.js +3 -1
- package/dist/shadcn/message-scroller/index.js +3 -1
- package/dist/shadcn/popover/index.js +3 -1
- package/dist/shadcn/progress/index.js +3 -1
- package/dist/shadcn/progress/tone.js +8 -7
- package/dist/shadcn/radio-group/index.js +3 -1
- package/dist/shadcn/scroll-area/index.js +3 -1
- package/dist/shadcn/select/index.js +3 -1
- package/dist/shadcn/separator/index.js +3 -1
- package/dist/shadcn/sheet/index.js +3 -1
- package/dist/shadcn/sidebar/context.svelte.js +42 -28
- package/dist/shadcn/sidebar/index.js +3 -1
- package/dist/shadcn/skeleton/index.js +3 -1
- package/dist/shadcn/slider/index.js +3 -1
- package/dist/shadcn/switch/index.js +3 -1
- package/dist/shadcn/table/index.js +3 -1
- package/dist/shadcn/tabs/index.js +3 -1
- package/dist/shadcn/textarea/index.js +3 -1
- package/dist/shadcn/toggle/index.js +3 -1
- package/dist/shadcn/toggle-group/index.js +3 -1
- package/dist/shadcn/tooltip/context.js +7 -2
- package/dist/shadcn/tooltip/index.js +3 -1
- package/dist/shadcn/trace/index.js +3 -1
- package/dist/slides/bridges.js +65 -59
- package/dist/slides/deck-controller.svelte.js +210 -207
- package/dist/slides/export/capture.js +66 -71
- package/dist/slides/export/ffmpeg.js +76 -72
- package/dist/slides/export/index.js +3 -0
- package/dist/slides/export/launch.js +9 -6
- package/dist/slides/export/pdf.js +60 -54
- package/dist/slides/export/types.js +1 -0
- package/dist/slides/labels.js +24 -24
- package/dist/slides/layout.js +39 -41
- package/dist/slides/model.js +9 -7
- package/dist/slides/navigation.js +78 -73
- package/dist/slides/types.js +2 -2
- package/dist/status/define-statuses.js +18 -14
- package/dist/status/status-types.js +1 -0
- package/dist/test-setup.js +24 -20
- package/dist/thread/logic.js +73 -77
- package/dist/thread/types.js +21 -21
- package/dist/work/board-order.js +94 -90
- package/dist/work/dates.js +16 -9
- package/dist/work/detail/detail-types.js +18 -18
- package/dist/work/docs/edited.js +32 -29
- package/dist/work/docs/index.js +4 -0
- package/dist/work/docs/labels.js +34 -34
- package/dist/work/docs/menu.js +113 -106
- package/dist/work/docs/outline.js +39 -29
- package/dist/work/gantt/logic.js +211 -235
- package/dist/work/inbox/inbox-logic.js +71 -75
- package/dist/work/inbox/inbox-statuses.js +75 -72
- package/dist/work/inbox/inbox-types.js +1 -0
- package/dist/work/kanban-drag.js +27 -22
- package/dist/work/kanban-types.js +1 -0
- package/dist/work/presets/sales.js +36 -32
- package/dist/work/reorder.js +9 -8
- package/dist/work/task-types.js +1 -0
- package/dist/work/time/duration.js +51 -46
- package/dist/work/time/time-types.js +23 -23
- package/dist/work/use-kanban-dnd.svelte.js +126 -125
- package/package.json +3 -1
- package/src/components/list-page/master-detail.svelte +3 -1
- package/src/components/list-page/rail-row.svelte +4 -4
- package/src/components/tags-input/tags-input.svelte +2 -0
- package/src/editor/markdown.ts +30 -35
|
@@ -1,250 +1,272 @@
|
|
|
1
|
+
// Hand-drawn layer, server-safe: palette, geometry, seeding. The seed comes from
|
|
2
|
+
// the node id, so server SVG and Svelte draw the same wobble.
|
|
3
|
+
// Look and authoring: see the package README.
|
|
1
4
|
import rough from "roughjs";
|
|
2
5
|
import { createMemo } from "./edge-memo.js";
|
|
6
|
+
// =========================
|
|
7
|
+
// PALETTE
|
|
8
|
+
// =========================
|
|
9
|
+
/** Accent names a board author writes. Excalidraw's own stroke colors. */
|
|
3
10
|
export const SKETCH_ACCENTS = [
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
"ink",
|
|
12
|
+
"red",
|
|
13
|
+
"green",
|
|
14
|
+
"blue",
|
|
15
|
+
"violet",
|
|
16
|
+
"amber",
|
|
17
|
+
"teal",
|
|
18
|
+
"indigo",
|
|
19
|
+
"terra"
|
|
13
20
|
];
|
|
21
|
+
/** Excalidraw's strokes plus its lightest tint per hue; brand colors would read as app, not whiteboard. */
|
|
14
22
|
const PALETTE = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
23
|
+
ink: {
|
|
24
|
+
stroke: "#1e1e1e",
|
|
25
|
+
fill: "#ffffff",
|
|
26
|
+
heading: "#1e1e1e",
|
|
27
|
+
body: "#343a40"
|
|
28
|
+
},
|
|
29
|
+
red: {
|
|
30
|
+
stroke: "#c92a2a",
|
|
31
|
+
fill: "#fff5f5",
|
|
32
|
+
heading: "#a61e4d",
|
|
33
|
+
body: "#3b3b46"
|
|
34
|
+
},
|
|
35
|
+
green: {
|
|
36
|
+
stroke: "#2f9e44",
|
|
37
|
+
fill: "#f4fce3",
|
|
38
|
+
heading: "#2b8a3e",
|
|
39
|
+
body: "#3b3b46"
|
|
40
|
+
},
|
|
41
|
+
blue: {
|
|
42
|
+
stroke: "#1971c2",
|
|
43
|
+
fill: "#e7f5ff",
|
|
44
|
+
heading: "#1864ab",
|
|
45
|
+
body: "#3b3b46"
|
|
46
|
+
},
|
|
47
|
+
violet: {
|
|
48
|
+
stroke: "#6741d9",
|
|
49
|
+
fill: "#f3f0ff",
|
|
50
|
+
heading: "#5f3dc4",
|
|
51
|
+
body: "#3b3b46"
|
|
52
|
+
},
|
|
53
|
+
amber: {
|
|
54
|
+
stroke: "#e8a33d",
|
|
55
|
+
fill: "#fff9db",
|
|
56
|
+
heading: "#b8860b",
|
|
57
|
+
body: "#3b3b46"
|
|
58
|
+
},
|
|
59
|
+
teal: {
|
|
60
|
+
stroke: "#0c8599",
|
|
61
|
+
fill: "#e3fafc",
|
|
62
|
+
heading: "#0b7285",
|
|
63
|
+
body: "#3b3b46"
|
|
64
|
+
},
|
|
65
|
+
// The brand pair the email figures are drawn in: tools/whiteboard/src/scene.ts INK and HIGHLIGHT.
|
|
66
|
+
indigo: {
|
|
67
|
+
stroke: "#414fd2",
|
|
68
|
+
fill: "#ffffff",
|
|
69
|
+
heading: "#414fd2",
|
|
70
|
+
body: "#414fd2"
|
|
71
|
+
},
|
|
72
|
+
terra: {
|
|
73
|
+
stroke: "#f0503d",
|
|
74
|
+
fill: "#ffffff",
|
|
75
|
+
heading: "#f0503d",
|
|
76
|
+
body: "#f0503d"
|
|
77
|
+
}
|
|
69
78
|
};
|
|
79
|
+
/** The same hues lifted for the Ink board: light strokes, a dark wash, and text that stays readable on it. */
|
|
70
80
|
const DARK_PALETTE = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
81
|
+
ink: {
|
|
82
|
+
stroke: "#e9ecef",
|
|
83
|
+
fill: "#151b30",
|
|
84
|
+
heading: "#f1f3f5",
|
|
85
|
+
body: "#ced4da"
|
|
86
|
+
},
|
|
87
|
+
red: {
|
|
88
|
+
stroke: "#ff8787",
|
|
89
|
+
fill: "#2a1822",
|
|
90
|
+
heading: "#ffa8c5",
|
|
91
|
+
body: "#ced4da"
|
|
92
|
+
},
|
|
93
|
+
green: {
|
|
94
|
+
stroke: "#69db7c",
|
|
95
|
+
fill: "#132a20",
|
|
96
|
+
heading: "#8ce99a",
|
|
97
|
+
body: "#ced4da"
|
|
98
|
+
},
|
|
99
|
+
blue: {
|
|
100
|
+
stroke: "#74c0fc",
|
|
101
|
+
fill: "#12253d",
|
|
102
|
+
heading: "#a5d8ff",
|
|
103
|
+
body: "#ced4da"
|
|
104
|
+
},
|
|
105
|
+
violet: {
|
|
106
|
+
stroke: "#b197fc",
|
|
107
|
+
fill: "#211c3d",
|
|
108
|
+
heading: "#d0bfff",
|
|
109
|
+
body: "#ced4da"
|
|
110
|
+
},
|
|
111
|
+
amber: {
|
|
112
|
+
stroke: "#ffd43b",
|
|
113
|
+
fill: "#2b2612",
|
|
114
|
+
heading: "#ffe066",
|
|
115
|
+
body: "#ced4da"
|
|
116
|
+
},
|
|
117
|
+
teal: {
|
|
118
|
+
stroke: "#66d9e8",
|
|
119
|
+
fill: "#112a30",
|
|
120
|
+
heading: "#99e9f2",
|
|
121
|
+
body: "#ced4da"
|
|
122
|
+
},
|
|
123
|
+
indigo: {
|
|
124
|
+
stroke: "#8b96ff",
|
|
125
|
+
fill: "#151b30",
|
|
126
|
+
heading: "#a5adff",
|
|
127
|
+
body: "#a5adff"
|
|
128
|
+
},
|
|
129
|
+
terra: {
|
|
130
|
+
stroke: "#ff8a78",
|
|
131
|
+
fill: "#151b30",
|
|
132
|
+
heading: "#ff9d8d",
|
|
133
|
+
body: "#ff9d8d"
|
|
134
|
+
}
|
|
125
135
|
};
|
|
136
|
+
/** Server renders (exports, emails) stay on the light palette; the editor passes its theme. */
|
|
126
137
|
export function sketchColors(accent, dark = false) {
|
|
127
|
-
|
|
128
|
-
|
|
138
|
+
const palette = dark ? DARK_PALETTE : PALETTE;
|
|
139
|
+
return palette[accent ?? "ink"] ?? palette.ink;
|
|
129
140
|
}
|
|
130
141
|
export function isSketchAccent(value) {
|
|
131
|
-
|
|
142
|
+
return typeof value === "string" && SKETCH_ACCENTS.includes(value);
|
|
132
143
|
}
|
|
144
|
+
// =========================
|
|
145
|
+
// SEEDING
|
|
146
|
+
// =========================
|
|
147
|
+
/** A stable 31-bit seed (FNV-1a): unseeded calls reshuffle the wobble, so cards would redraw each render. */
|
|
133
148
|
export function seedFrom(id) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
149
|
+
let hash = 2166136261;
|
|
150
|
+
for (let i = 0; i < id.length; i += 1) {
|
|
151
|
+
hash ^= id.charCodeAt(i);
|
|
152
|
+
hash = Math.imul(hash, 16777619);
|
|
153
|
+
}
|
|
154
|
+
return Math.abs(hash) % 2147483647;
|
|
140
155
|
}
|
|
141
156
|
const generator = rough.generator();
|
|
142
|
-
|
|
157
|
+
/** Arrows are redrawn whenever the page repaints them, so a line or head already drawn is handed back. */
|
|
158
|
+
const MEMO_LIMIT = 4e3;
|
|
143
159
|
const lines = createMemo(MEMO_LIMIT);
|
|
144
160
|
const heads = createMemo(MEMO_LIMIT);
|
|
161
|
+
/** Shared feel. Low roughness reads as a careful hand; high reads as a scribble. */
|
|
145
162
|
function baseOptions(seed, colors, overrides) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
163
|
+
return {
|
|
164
|
+
seed,
|
|
165
|
+
roughness: 1.1,
|
|
166
|
+
bowing: 1.4,
|
|
167
|
+
stroke: colors.stroke,
|
|
168
|
+
strokeWidth: 1.6,
|
|
169
|
+
// WHY solid, not hachure: a hatched fill behind three lines of body copy
|
|
170
|
+
// makes the text unreadable at the zoom a card is actually read at.
|
|
171
|
+
fillStyle: "solid",
|
|
172
|
+
...overrides
|
|
173
|
+
};
|
|
155
174
|
}
|
|
156
175
|
const FORMAL = {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
roughness: 0,
|
|
177
|
+
bowing: 0,
|
|
178
|
+
disableMultiStroke: true,
|
|
179
|
+
strokeWidth: 1.4
|
|
161
180
|
};
|
|
162
181
|
function toPaths(drawable) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
182
|
+
return generator.toPaths(drawable).map((p) => ({
|
|
183
|
+
d: p.d,
|
|
184
|
+
stroke: p.stroke,
|
|
185
|
+
// rough leaves `fill` off a path it did not fill, and an unfilled path is
|
|
186
|
+
// the same thing as one filled with nothing.
|
|
187
|
+
fill: p.fill ?? "none",
|
|
188
|
+
strokeWidth: p.strokeWidth
|
|
189
|
+
}));
|
|
169
190
|
}
|
|
191
|
+
/** A card outline: rough.js has no rounded rectangle, so a rounded path instead (square reads as a box). */
|
|
170
192
|
export function roughCard(width, height, { seed, colors }, { radius = 14, formal = false } = {}) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
193
|
+
const w = Math.max(width, radius * 2 + 2);
|
|
194
|
+
const h = Math.max(height, radius * 2 + 2);
|
|
195
|
+
const r = Math.min(radius, w / 2 - 1, h / 2 - 1);
|
|
196
|
+
const d = [
|
|
197
|
+
`M ${r} 0`,
|
|
198
|
+
`L ${w - r} 0`,
|
|
199
|
+
`Q ${w} 0 ${w} ${r}`,
|
|
200
|
+
`L ${w} ${h - r}`,
|
|
201
|
+
`Q ${w} ${h} ${w - r} ${h}`,
|
|
202
|
+
`L ${r} ${h}`,
|
|
203
|
+
`Q 0 ${h} 0 ${h - r}`,
|
|
204
|
+
`L 0 ${r}`,
|
|
205
|
+
`Q 0 0 ${r} 0`,
|
|
206
|
+
"Z"
|
|
207
|
+
].join(" ");
|
|
208
|
+
return toPaths(generator.path(d, baseOptions(seed, colors, {
|
|
209
|
+
fill: colors.fill,
|
|
210
|
+
...formal ? FORMAL : {}
|
|
211
|
+
})));
|
|
190
212
|
}
|
|
213
|
+
/** An ellipse card is drawn round its text, not through it: this much wider and taller than the box. */
|
|
191
214
|
export const ELLIPSE_CARD_SCALE = {
|
|
192
|
-
|
|
193
|
-
|
|
215
|
+
x: 1.32,
|
|
216
|
+
y: 1.42
|
|
194
217
|
};
|
|
218
|
+
/** The circle-this-bit annotation, drawn as one loose pass. */
|
|
195
219
|
export function roughEllipse(width, height, { seed, colors }, { formal = false } = {}) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
220
|
+
return toPaths(generator.ellipse(width / 2, height / 2, width, height, baseOptions(seed, colors, {
|
|
221
|
+
roughness: 1.6,
|
|
222
|
+
strokeWidth: 2.2,
|
|
223
|
+
fill: undefined,
|
|
224
|
+
...formal ? FORMAL : {}
|
|
225
|
+
})));
|
|
202
226
|
}
|
|
227
|
+
/** A box with no rounding: the frame you draw around a whole column. */
|
|
203
228
|
export function roughRect(width, height, { seed, colors }, { filled = false, formal = false } = {}) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
229
|
+
return toPaths(generator.rectangle(1, 1, Math.max(width - 2, 2), Math.max(height - 2, 2), baseOptions(seed, colors, {
|
|
230
|
+
fill: filled ? colors.fill : undefined,
|
|
231
|
+
...formal ? FORMAL : {}
|
|
232
|
+
})));
|
|
208
233
|
}
|
|
234
|
+
/** A closed outline through the given points: the diamond mark, drawn like the box beside it. */
|
|
209
235
|
export function roughPolygon(points, { seed, colors }, { formal = false } = {}) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
fill: undefined,
|
|
215
|
-
...formal ? FORMAL : {}
|
|
216
|
-
})));
|
|
236
|
+
return toPaths(generator.polygon(points.map(([x, y]) => [x, y]), baseOptions(seed, colors, {
|
|
237
|
+
fill: undefined,
|
|
238
|
+
...formal ? FORMAL : {}
|
|
239
|
+
})));
|
|
217
240
|
}
|
|
241
|
+
/** The hand-drawn rule under a title, `y` down from the top. */
|
|
218
242
|
export function roughUnderline(width, { seed, colors }, { y = 4, formal = false } = {}) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
243
|
+
return toPaths(generator.line(0, y, width, y, baseOptions(seed, colors, {
|
|
244
|
+
strokeWidth: 2,
|
|
245
|
+
bowing: 2.4,
|
|
246
|
+
...formal ? FORMAL : {}
|
|
247
|
+
})));
|
|
224
248
|
}
|
|
249
|
+
/** The shaft of a hand-ruled connector, with no head. */
|
|
225
250
|
export function roughLine(from, to, { seed, colors }, { formal = false } = {}) {
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
251
|
+
const hand = formal ? FORMAL : {};
|
|
252
|
+
// The same line is asked for on every redraw of its arrow, and rough.js is the slow part.
|
|
253
|
+
return lines(`${seed}|${colors.stroke}|${formal}|${from.x},${from.y}|${to.x},${to.y}`, () => toPaths(generator.line(from.x, from.y, to.x, to.y, baseOptions(seed, colors, {
|
|
254
|
+
strokeWidth: 1.8,
|
|
255
|
+
...hand
|
|
256
|
+
}))));
|
|
231
257
|
}
|
|
258
|
+
/** Two hand-drawn wings with their tip at `tip`, pointing along `angle` (radians). */
|
|
232
259
|
export function roughHead(tip, angle, { seed, colors }, { formal = false } = {}) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
roughness: 0.8,
|
|
242
|
-
...hand
|
|
243
|
-
})))));
|
|
260
|
+
const hand = formal ? FORMAL : {};
|
|
261
|
+
const head = 11;
|
|
262
|
+
const spread = .42;
|
|
263
|
+
return heads(`${seed}|${colors.stroke}|${formal}|${tip.x},${tip.y}|${angle}`, () => [angle + Math.PI - spread, angle + Math.PI + spread].flatMap((a, i) => toPaths(generator.line(tip.x, tip.y, tip.x + Math.cos(a) * head, tip.y + Math.sin(a) * head, baseOptions(seed + i + 1, colors, {
|
|
264
|
+
strokeWidth: 1.8,
|
|
265
|
+
roughness: .8,
|
|
266
|
+
...hand
|
|
267
|
+
})))));
|
|
244
268
|
}
|
|
269
|
+
/** A straight-ish connector between two canvas points, plus its arrow head. */
|
|
245
270
|
export function roughArrow(from, to, pen, style = {}) {
|
|
246
|
-
|
|
247
|
-
...roughLine(from, to, pen, style),
|
|
248
|
-
...roughHead(to, Math.atan2(to.y - from.y, to.x - from.x), pen, style)
|
|
249
|
-
];
|
|
271
|
+
return [...roughLine(from, to, pen, style), ...roughHead(to, Math.atan2(to.y - from.y, to.x - from.x), pen, style)];
|
|
250
272
|
}
|