@neta-art/cohub 3.2.0 → 4.0.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/dist/board/codec.js +0 -9
- package/dist/board/core/draw-geometry.d.ts +3 -4
- package/dist/board/core/draw-geometry.js +21 -29
- package/dist/board/core/file-preview.d.ts +4 -2
- package/dist/board/core/file-preview.js +20 -9
- package/dist/board/core/palette.d.ts +2 -2
- package/dist/board/core/palette.js +28 -0
- package/dist/board/core/shape-types.d.ts +2 -6
- package/dist/board/core/text-metrics.d.ts +2 -2
- package/dist/board/core/text-metrics.js +2 -2
- package/dist/board/core/tool-styles.d.ts +52 -0
- package/dist/board/core/tool-styles.js +51 -0
- package/dist/board/geometry.d.ts +9 -1
- package/dist/board/geometry.js +25 -1
- package/dist/board/index.d.ts +6 -5
- package/dist/board/index.js +5 -4
- package/dist/board/render/renderers/board-renderer-registry.js +0 -2
- package/dist/board/render/renderers/file-card-renderer.d.ts +8 -1
- package/dist/board/render/renderers/file-card-renderer.js +37 -58
- package/dist/board/render/themes/board-theme-registry.d.ts +2 -0
- package/dist/board/render/themes/clean-theme.js +6 -3
- package/dist/chunks/http.d.ts +2 -2
- package/dist/chunks/http.js +4 -0
- package/dist/chunks/websocket.d.ts +54 -2
- package/dist/http.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/protocol/dist/board-constants.js +2 -1
- package/dist/protocol/dist/board-document.d.ts +3 -80
- package/dist/protocol/dist/board-document.js +4 -14
- package/dist/protocol/dist/realtime/board-awareness.js +3 -1
- package/package.json +3 -2
- package/dist/board/render/renderers/note-card-renderer.d.ts +0 -5
- package/dist/board/render/renderers/note-card-renderer.js +0 -112
package/dist/board/codec.js
CHANGED
|
@@ -88,15 +88,6 @@ function boardNodeToItemValue(node) {
|
|
|
88
88
|
...locked ? { locked } : {},
|
|
89
89
|
style
|
|
90
90
|
};
|
|
91
|
-
case "note": return {
|
|
92
|
-
id: node.nodeId,
|
|
93
|
-
type: "note",
|
|
94
|
-
text: typeof data.text === "string" ? data.text : "",
|
|
95
|
-
color: typeof data.color === "string" ? data.color : "amber",
|
|
96
|
-
frame,
|
|
97
|
-
...locked ? { locked } : {},
|
|
98
|
-
style
|
|
99
|
-
};
|
|
100
91
|
case "geo": return {
|
|
101
92
|
id: node.nodeId,
|
|
102
93
|
type: "geo",
|
|
@@ -12,10 +12,9 @@ declare function computeDrawBounds(points: DrawPoint[], size: number): Rect;
|
|
|
12
12
|
*/
|
|
13
13
|
declare function simplifyDrawIndices(points: DrawPoint[], tolerance: number): number[];
|
|
14
14
|
/**
|
|
15
|
-
* Build a closed outline
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* filled Pixi polygon. Returns an empty array for degenerate input.
|
|
15
|
+
* Build a closed, pressure-sensitive outline suitable for a filled Pixi polygon.
|
|
16
|
+
* The raw samples remain authoritative; the outline is derived with rounded caps
|
|
17
|
+
* and joins that stay stable through sharp turns and self-intersections.
|
|
19
18
|
*/
|
|
20
19
|
declare function buildStrokeOutline(points: DrawPoint[], size: number): Array<{
|
|
21
20
|
x: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getStroke } from "perfect-freehand";
|
|
1
2
|
//#region src/board/core/draw-geometry.ts
|
|
2
3
|
/** Radius of a sample in world units given the stroke size and pressure. */
|
|
3
4
|
function sampleRadius(size, pressure) {
|
|
@@ -80,10 +81,9 @@ function perpendicularDistance(point, a, b) {
|
|
|
80
81
|
return Math.hypot(point.x - projX, point.y - projY);
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
|
-
* Build a closed outline
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* filled Pixi polygon. Returns an empty array for degenerate input.
|
|
84
|
+
* Build a closed, pressure-sensitive outline suitable for a filled Pixi polygon.
|
|
85
|
+
* The raw samples remain authoritative; the outline is derived with rounded caps
|
|
86
|
+
* and joins that stay stable through sharp turns and self-intersections.
|
|
87
87
|
*/
|
|
88
88
|
function buildStrokeOutline(points, size) {
|
|
89
89
|
const n = points.length;
|
|
@@ -129,31 +129,23 @@ function buildStrokeOutline(points, size) {
|
|
|
129
129
|
}
|
|
130
130
|
];
|
|
131
131
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
y: current.y + ny * r
|
|
150
|
-
});
|
|
151
|
-
right.push({
|
|
152
|
-
x: current.x - nx * r,
|
|
153
|
-
y: current.y - ny * r
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
return [...left, ...right.reverse()];
|
|
132
|
+
return getStroke(points.map((point) => [
|
|
133
|
+
point.x,
|
|
134
|
+
point.y,
|
|
135
|
+
point.p
|
|
136
|
+
]), {
|
|
137
|
+
size: Math.max(1, size),
|
|
138
|
+
thinning: .5,
|
|
139
|
+
smoothing: .5,
|
|
140
|
+
streamline: 0,
|
|
141
|
+
simulatePressure: false,
|
|
142
|
+
last: true,
|
|
143
|
+
start: { cap: true },
|
|
144
|
+
end: { cap: true }
|
|
145
|
+
}).map(([x, y]) => ({
|
|
146
|
+
x,
|
|
147
|
+
y
|
|
148
|
+
}));
|
|
157
149
|
}
|
|
158
150
|
/**
|
|
159
151
|
* Distance from a world point to the stroke's polyline, in the shape's local
|
|
@@ -84,6 +84,8 @@ type SplitSource = {
|
|
|
84
84
|
* YAML parser.
|
|
85
85
|
*/
|
|
86
86
|
declare function splitFrontmatter(source: string): SplitSource;
|
|
87
|
+
/** Read the document title declared by top-level frontmatter. */
|
|
88
|
+
declare function readTitleFromFrontmatter(frontmatter: string | null): string | null;
|
|
87
89
|
/**
|
|
88
90
|
* Read the first cover-ish scalar from a frontmatter block.
|
|
89
91
|
*
|
|
@@ -136,7 +138,7 @@ declare function shouldFetchFileExcerpt(input: {
|
|
|
136
138
|
* This distinction is the whole point: a board is a long-lived document, and a
|
|
137
139
|
* card should not claim a file is gone because the network blipped. It is also
|
|
138
140
|
* why availability is client-local transient state and never written to the
|
|
139
|
-
* node — see the
|
|
141
|
+
* node — see the rationale in board-file-preview-source.
|
|
140
142
|
*/
|
|
141
143
|
type FileAvailability = "ok" | "missing" | "unavailable";
|
|
142
144
|
/**
|
|
@@ -173,4 +175,4 @@ declare function filePreviewMemoKey(spaceId: string, path: string, mtimeMs?: num
|
|
|
173
175
|
*/
|
|
174
176
|
declare function mergeFileSnapshot(cached: BoardFileSnapshotFacts | undefined, incoming: BoardFileSnapshotFacts, complete: boolean): BoardFileSnapshotFacts;
|
|
175
177
|
//#endregion
|
|
176
|
-
export { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileAvailability, FilePreviewKind, ResolvedCover, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter };
|
|
178
|
+
export { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileAvailability, FilePreviewKind, ResolvedCover, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, readTitleFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter };
|
|
@@ -142,15 +142,10 @@ function unquote(value) {
|
|
|
142
142
|
if (first === "\"" && last === "\"" || first === "'" && last === "'") return trimmed.slice(1, -1);
|
|
143
143
|
return trimmed;
|
|
144
144
|
}
|
|
145
|
-
/**
|
|
146
|
-
|
|
147
|
-
*
|
|
148
|
-
* Only top-level keys are considered (a leading-space line is nested and skipped)
|
|
149
|
-
* so `cover:` under some other mapping cannot be mistaken for the file's own.
|
|
150
|
-
*/
|
|
151
|
-
function readCoverFromFrontmatter(frontmatter) {
|
|
152
|
-
if (!frontmatter) return null;
|
|
145
|
+
/** Read non-empty top-level scalar values from a frontmatter block. */
|
|
146
|
+
function readFrontmatterScalars(frontmatter) {
|
|
153
147
|
const found = /* @__PURE__ */ new Map();
|
|
148
|
+
if (!frontmatter) return found;
|
|
154
149
|
for (const line of frontmatter.split(/\r?\n/)) {
|
|
155
150
|
if (!line.trim() || /^\s/.test(line) || line.trimStart().startsWith("#")) continue;
|
|
156
151
|
const match = /^([A-Za-z0-9_:.-]+):(.*)$/.exec(line);
|
|
@@ -159,6 +154,20 @@ function readCoverFromFrontmatter(frontmatter) {
|
|
|
159
154
|
const value = unquote(match[2] ?? "");
|
|
160
155
|
if (key && value && !found.has(key)) found.set(key, value);
|
|
161
156
|
}
|
|
157
|
+
return found;
|
|
158
|
+
}
|
|
159
|
+
/** Read the document title declared by top-level frontmatter. */
|
|
160
|
+
function readTitleFromFrontmatter(frontmatter) {
|
|
161
|
+
return readFrontmatterScalars(frontmatter).get("title") ?? null;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Read the first cover-ish scalar from a frontmatter block.
|
|
165
|
+
*
|
|
166
|
+
* Only top-level keys are considered (a leading-space line is nested and skipped)
|
|
167
|
+
* so `cover:` under some other mapping cannot be mistaken for the file's own.
|
|
168
|
+
*/
|
|
169
|
+
function readCoverFromFrontmatter(frontmatter) {
|
|
170
|
+
const found = readFrontmatterScalars(frontmatter);
|
|
162
171
|
for (const key of COVER_KEYS) {
|
|
163
172
|
const value = found.get(key);
|
|
164
173
|
if (value) return value;
|
|
@@ -200,6 +209,8 @@ function buildFileSnapshot(input) {
|
|
|
200
209
|
const content = input.content;
|
|
201
210
|
if (typeof content !== "string" || content.length === 0) return snapshot;
|
|
202
211
|
const { frontmatter, body } = splitFrontmatter(content);
|
|
212
|
+
const frontmatterTitle = readTitleFromFrontmatter(frontmatter);
|
|
213
|
+
if (frontmatterTitle) snapshot.title = frontmatterTitle;
|
|
203
214
|
const cover = resolveCoverRef(input.path, readCoverFromFrontmatter(frontmatter));
|
|
204
215
|
if (cover?.kind === "url") snapshot.coverUrl = cover.url;
|
|
205
216
|
else if (cover?.kind === "path") snapshot.coverPath = cover.path;
|
|
@@ -268,4 +279,4 @@ function mergeFileSnapshot(cached, incoming, complete) {
|
|
|
268
279
|
};
|
|
269
280
|
}
|
|
270
281
|
//#endregion
|
|
271
|
-
export { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter };
|
|
282
|
+
export { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, readTitleFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/board/core/palette.d.ts
|
|
2
2
|
/**
|
|
3
|
-
* Board color palette — a small, named set of shape colors shared by
|
|
3
|
+
* Board color palette — a small, named set of shape colors shared by text,
|
|
4
4
|
* geo, draw and arrow shapes. Colors are stored by id in shape props (never
|
|
5
5
|
* raw hex), so themes and space `.cohub/theme.css` can remap them via CSS
|
|
6
6
|
* tokens while persisted data stays compact and forward-compatible.
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* --board-color-{id}-stroke | -fill | -label
|
|
10
10
|
* with hard-coded light/dark tables as offline / export fallbacks.
|
|
11
11
|
*/
|
|
12
|
-
type BoardColorId = "brand" | "neutral" | "blue" | "green" | "amber" | "violet" | "rose";
|
|
12
|
+
type BoardColorId = "brand" | "neutral" | "black" | "white" | "blue" | "green" | "amber" | "violet" | "rose";
|
|
13
13
|
type BoardColorValue = {
|
|
14
14
|
/** Stroke / accent color (sRGB hex). */
|
|
15
15
|
stroke: number;
|
|
@@ -36,6 +36,34 @@ const BOARD_COLORS = [
|
|
|
36
36
|
label: LABEL_LIGHT
|
|
37
37
|
}
|
|
38
38
|
},
|
|
39
|
+
{
|
|
40
|
+
id: "black",
|
|
41
|
+
label: "Black",
|
|
42
|
+
dark: {
|
|
43
|
+
stroke: 0,
|
|
44
|
+
fill: 0,
|
|
45
|
+
label: LABEL_DARK
|
|
46
|
+
},
|
|
47
|
+
light: {
|
|
48
|
+
stroke: 0,
|
|
49
|
+
fill: 0,
|
|
50
|
+
label: LABEL_LIGHT
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: "white",
|
|
55
|
+
label: "White",
|
|
56
|
+
dark: {
|
|
57
|
+
stroke: 16777215,
|
|
58
|
+
fill: 16777215,
|
|
59
|
+
label: LABEL_DARK
|
|
60
|
+
},
|
|
61
|
+
light: {
|
|
62
|
+
stroke: 16777215,
|
|
63
|
+
fill: 16777215,
|
|
64
|
+
label: LABEL_LIGHT
|
|
65
|
+
}
|
|
66
|
+
},
|
|
39
67
|
{
|
|
40
68
|
id: "blue",
|
|
41
69
|
label: "Blue",
|
|
@@ -47,7 +47,7 @@ type ShapeCapabilities = {
|
|
|
47
47
|
aspectLocked: boolean;
|
|
48
48
|
/** Shows the rotation handle. */
|
|
49
49
|
canRotate: boolean;
|
|
50
|
-
/** Supports double-click inline editing
|
|
50
|
+
/** Supports double-click inline editing. */
|
|
51
51
|
canEdit: boolean;
|
|
52
52
|
/** Can be a binding target for arrows. */
|
|
53
53
|
canBind: boolean;
|
|
@@ -123,10 +123,6 @@ type ArrowShapeProps = {
|
|
|
123
123
|
arrowEnd: boolean;
|
|
124
124
|
label: string;
|
|
125
125
|
};
|
|
126
|
-
type NoteShapeProps = {
|
|
127
|
-
text: string;
|
|
128
|
-
color: string;
|
|
129
|
-
};
|
|
130
126
|
type TextShapeProps = {
|
|
131
127
|
text: string;
|
|
132
128
|
color: string;
|
|
@@ -141,4 +137,4 @@ type VideoShapeProps = {
|
|
|
141
137
|
mimeType?: string;
|
|
142
138
|
};
|
|
143
139
|
//#endregion
|
|
144
|
-
export { ArrowEndpoint, ArrowShapeProps, DrawPoint, DrawShapeProps, FULL_CAPABILITIES, GEO_KINDS, GeoKind, GeoShapeProps, HandleDragResult, ImageShapeProps,
|
|
140
|
+
export { ArrowEndpoint, ArrowShapeProps, DrawPoint, DrawShapeProps, FULL_CAPABILITIES, GEO_KINDS, GeoKind, GeoShapeProps, HandleDragResult, ImageShapeProps, ShapeCapabilities, ShapeGeometry, ShapeHandle, ShapeHandleId, ShapeResizeMode, TextShapeProps, VideoShapeProps, isGeoKind, resizeModeForCapabilities };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
//#region src/board/core/text-metrics.d.ts
|
|
2
2
|
declare const TEXT_FONT_FAMILY = "Geist";
|
|
3
|
-
declare const TEXT_FONT_SIZE =
|
|
4
|
-
declare const TEXT_LINE_HEIGHT =
|
|
3
|
+
declare const TEXT_FONT_SIZE = 24;
|
|
4
|
+
declare const TEXT_LINE_HEIGHT = 32;
|
|
5
5
|
declare const TEXT_MIN_FONT_SIZE = 2;
|
|
6
6
|
declare const TEXT_MAX_FONT_SIZE = 512;
|
|
7
7
|
type BoardTextMeasurer = (text: string, fontSize: number) => number | null;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BOARD_TEXT_FONT_FAMILY } from "../../protocol/dist/board-constants.js";
|
|
2
2
|
//#region src/board/core/text-metrics.ts
|
|
3
3
|
const TEXT_FONT_FAMILY = BOARD_TEXT_FONT_FAMILY;
|
|
4
|
-
const TEXT_FONT_SIZE =
|
|
5
|
-
const TEXT_LINE_HEIGHT =
|
|
4
|
+
const TEXT_FONT_SIZE = 24;
|
|
5
|
+
const TEXT_LINE_HEIGHT = 32;
|
|
6
6
|
const TEXT_MIN_FONT_SIZE = 2;
|
|
7
7
|
const TEXT_MAX_FONT_SIZE = 512;
|
|
8
8
|
const TEXT_LINE_HEIGHT_RATIO = TEXT_LINE_HEIGHT / TEXT_FONT_SIZE;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { BoardColorId } from "./palette.js";
|
|
2
|
+
import { GeoKind } from "./shape-types.js";
|
|
3
|
+
//#region src/board/core/tool-styles.d.ts
|
|
4
|
+
declare const BOARD_STROKE_MIN_SIZE = 1;
|
|
5
|
+
declare const BOARD_STROKE_MAX_SIZE = 64;
|
|
6
|
+
type BoardToolStyleMap = {
|
|
7
|
+
text: {
|
|
8
|
+
color: BoardColorId;
|
|
9
|
+
};
|
|
10
|
+
geo: {
|
|
11
|
+
color: BoardColorId;
|
|
12
|
+
geo: GeoKind;
|
|
13
|
+
};
|
|
14
|
+
draw: {
|
|
15
|
+
color: BoardColorId;
|
|
16
|
+
size: number;
|
|
17
|
+
};
|
|
18
|
+
arrow: {
|
|
19
|
+
color: BoardColorId;
|
|
20
|
+
size: number;
|
|
21
|
+
};
|
|
22
|
+
frame: {
|
|
23
|
+
color: BoardColorId;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
type BoardStyledToolId = keyof BoardToolStyleMap;
|
|
27
|
+
type BoardToolStylePatch = { [K in BoardStyledToolId]?: Partial<BoardToolStyleMap[K]>; };
|
|
28
|
+
declare const DEFAULT_BOARD_TOOL_STYLES: {
|
|
29
|
+
readonly text: {
|
|
30
|
+
readonly color: "neutral";
|
|
31
|
+
};
|
|
32
|
+
readonly geo: {
|
|
33
|
+
readonly color: "brand";
|
|
34
|
+
readonly geo: "rectangle";
|
|
35
|
+
};
|
|
36
|
+
readonly draw: {
|
|
37
|
+
readonly color: "brand";
|
|
38
|
+
readonly size: 4;
|
|
39
|
+
};
|
|
40
|
+
readonly arrow: {
|
|
41
|
+
readonly color: "brand";
|
|
42
|
+
readonly size: 2.5;
|
|
43
|
+
};
|
|
44
|
+
readonly frame: {
|
|
45
|
+
readonly color: "neutral";
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
declare function clampBoardStrokeSize(size: number): number;
|
|
49
|
+
/** Return a mutable, validated style map for an editor or another Board client. */
|
|
50
|
+
declare function createBoardToolStyles(patch?: BoardToolStylePatch): BoardToolStyleMap;
|
|
51
|
+
//#endregion
|
|
52
|
+
export { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BoardStyledToolId, BoardToolStyleMap, BoardToolStylePatch, DEFAULT_BOARD_TOOL_STYLES, clampBoardStrokeSize, createBoardToolStyles };
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { BOARD_ARROW_STROKE_SIZE } from "../../protocol/dist/board-constants.js";
|
|
2
|
+
import { isBoardColorId } from "./palette.js";
|
|
3
|
+
import { isGeoKind } from "./shape-types.js";
|
|
4
|
+
//#region src/board/core/tool-styles.ts
|
|
5
|
+
const BOARD_STROKE_MIN_SIZE = 1;
|
|
6
|
+
const BOARD_STROKE_MAX_SIZE = 64;
|
|
7
|
+
const DEFAULT_BOARD_TOOL_STYLES = {
|
|
8
|
+
text: { color: "neutral" },
|
|
9
|
+
geo: {
|
|
10
|
+
color: "brand",
|
|
11
|
+
geo: "rectangle"
|
|
12
|
+
},
|
|
13
|
+
draw: {
|
|
14
|
+
color: "brand",
|
|
15
|
+
size: 4
|
|
16
|
+
},
|
|
17
|
+
arrow: {
|
|
18
|
+
color: "brand",
|
|
19
|
+
size: BOARD_ARROW_STROKE_SIZE
|
|
20
|
+
},
|
|
21
|
+
frame: { color: "neutral" }
|
|
22
|
+
};
|
|
23
|
+
function finiteOr(value, fallback) {
|
|
24
|
+
return typeof value === "number" && Number.isFinite(value) ? value : fallback;
|
|
25
|
+
}
|
|
26
|
+
function clampBoardStrokeSize(size) {
|
|
27
|
+
return Math.min(64, Math.max(1, size));
|
|
28
|
+
}
|
|
29
|
+
/** Return a mutable, validated style map for an editor or another Board client. */
|
|
30
|
+
function createBoardToolStyles(patch = {}) {
|
|
31
|
+
const drawSize = clampBoardStrokeSize(finiteOr(patch.draw?.size, DEFAULT_BOARD_TOOL_STYLES.draw.size));
|
|
32
|
+
const arrowSize = clampBoardStrokeSize(finiteOr(patch.arrow?.size, DEFAULT_BOARD_TOOL_STYLES.arrow.size));
|
|
33
|
+
return {
|
|
34
|
+
text: { color: isBoardColorId(patch.text?.color) ? patch.text.color : DEFAULT_BOARD_TOOL_STYLES.text.color },
|
|
35
|
+
geo: {
|
|
36
|
+
color: isBoardColorId(patch.geo?.color) ? patch.geo.color : DEFAULT_BOARD_TOOL_STYLES.geo.color,
|
|
37
|
+
geo: isGeoKind(patch.geo?.geo) ? patch.geo.geo : DEFAULT_BOARD_TOOL_STYLES.geo.geo
|
|
38
|
+
},
|
|
39
|
+
draw: {
|
|
40
|
+
color: isBoardColorId(patch.draw?.color) ? patch.draw.color : DEFAULT_BOARD_TOOL_STYLES.draw.color,
|
|
41
|
+
size: drawSize
|
|
42
|
+
},
|
|
43
|
+
arrow: {
|
|
44
|
+
color: isBoardColorId(patch.arrow?.color) ? patch.arrow.color : DEFAULT_BOARD_TOOL_STYLES.arrow.color,
|
|
45
|
+
size: arrowSize
|
|
46
|
+
},
|
|
47
|
+
frame: { color: isBoardColorId(patch.frame?.color) ? patch.frame.color : DEFAULT_BOARD_TOOL_STYLES.frame.color }
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, DEFAULT_BOARD_TOOL_STYLES, clampBoardStrokeSize, createBoardToolStyles };
|
package/dist/board/geometry.d.ts
CHANGED
|
@@ -79,7 +79,15 @@ declare function rotationHandlePosition(frame: Rect & {
|
|
|
79
79
|
type ResizeHandle = "nw" | "n" | "ne" | "e" | "se" | "s" | "sw" | "w";
|
|
80
80
|
declare const CORNER_RESIZE_HANDLES: readonly ["nw", "ne", "se", "sw"];
|
|
81
81
|
declare const EDGE_RESIZE_HANDLES: readonly ["n", "e", "s", "w"];
|
|
82
|
+
type CornerResizeHandle = (typeof CORNER_RESIZE_HANDLES)[number];
|
|
83
|
+
/** Screen-space depth of the rotation zone outside each resize corner. */
|
|
84
|
+
declare const CORNER_ROTATION_ZONE_WIDTH = 16;
|
|
82
85
|
declare const RESIZE_HANDLES: ResizeHandle[];
|
|
86
|
+
/**
|
|
87
|
+
* Hit-test the outward quadrant around each corner, outside its resize target.
|
|
88
|
+
* This gives fine pointers Figma-style corner rotation without adding chrome.
|
|
89
|
+
*/
|
|
90
|
+
declare function frameCornerRotationHandleAt(frame: BoardFrame, point: WorldPoint, zoom: number, screenRadius?: number): CornerResizeHandle | null;
|
|
83
91
|
/**
|
|
84
92
|
* Hit-test the continuous edge zones of a rotated frame. Corners are inset so
|
|
85
93
|
* their resize handles retain priority even on small nodes.
|
|
@@ -128,4 +136,4 @@ declare function fitToContent(content: Rect, surface: Size, padding?: number): B
|
|
|
128
136
|
/** World-space rectangle currently visible in the board stage. */
|
|
129
137
|
declare function visibleWorldRect(viewport: BoardViewport, surfaceWidth: number, surfaceHeight: number): Rect;
|
|
130
138
|
//#endregion
|
|
131
|
-
export { CORNER_RESIZE_HANDLES, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ScreenPoint, Size, VIEWPORT_MARGIN_RATIO, WorldPoint, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
|
|
139
|
+
export { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CornerResizeHandle, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ScreenPoint, Size, VIEWPORT_MARGIN_RATIO, WorldPoint, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
|
package/dist/board/geometry.js
CHANGED
|
@@ -197,6 +197,8 @@ const EDGE_RESIZE_HANDLES = [
|
|
|
197
197
|
"s",
|
|
198
198
|
"w"
|
|
199
199
|
];
|
|
200
|
+
/** Screen-space depth of the rotation zone outside each resize corner. */
|
|
201
|
+
const CORNER_ROTATION_ZONE_WIDTH = 16;
|
|
200
202
|
const RESIZE_HANDLES = [
|
|
201
203
|
"nw",
|
|
202
204
|
"n",
|
|
@@ -208,6 +210,28 @@ const RESIZE_HANDLES = [
|
|
|
208
210
|
"w"
|
|
209
211
|
];
|
|
210
212
|
/**
|
|
213
|
+
* Hit-test the outward quadrant around each corner, outside its resize target.
|
|
214
|
+
* This gives fine pointers Figma-style corner rotation without adding chrome.
|
|
215
|
+
*/
|
|
216
|
+
function frameCornerRotationHandleAt(frame, point, zoom, screenRadius = 8) {
|
|
217
|
+
const rect = frameRect(frame);
|
|
218
|
+
const center = rectCenter(rect);
|
|
219
|
+
const local = frame.rotation ? rotatePointAround(point, center, -degToRad(frame.rotation)) : point;
|
|
220
|
+
const safeZoom = Math.max(zoom, 1e-4);
|
|
221
|
+
const innerRadius = screenRadius / safeZoom;
|
|
222
|
+
const outerRadius = (screenRadius + 16) / safeZoom;
|
|
223
|
+
for (const handle of CORNER_RESIZE_HANDLES) {
|
|
224
|
+
const corner = handlePosition(rect, handle);
|
|
225
|
+
const direction = HANDLE_DIRECTION[handle];
|
|
226
|
+
const outwardX = (local.x - corner.x) * direction.x;
|
|
227
|
+
const outwardY = (local.y - corner.y) * direction.y;
|
|
228
|
+
if (outwardX < -1e-4 || outwardY < -1e-4) continue;
|
|
229
|
+
const distance = Math.hypot(outwardX, outwardY);
|
|
230
|
+
if (distance > innerRadius && distance <= outerRadius) return handle;
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
211
235
|
* Hit-test the continuous edge zones of a rotated frame. Corners are inset so
|
|
212
236
|
* their resize handles retain priority even on small nodes.
|
|
213
237
|
*/
|
|
@@ -465,4 +489,4 @@ function visibleWorldRect(viewport, surfaceWidth, surfaceHeight) {
|
|
|
465
489
|
};
|
|
466
490
|
}
|
|
467
491
|
//#endregion
|
|
468
|
-
export { CORNER_RESIZE_HANDLES, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
|
|
492
|
+
export { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround };
|
package/dist/board/index.d.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, BoardManifest, BoardNodeRecord, BoardRecord, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
|
|
2
2
|
import { BoardExtensionDefinition, BoardExtensionRegistry, BoardPresetDefinition, CompiledSequence, DEFAULT_BOARD_LIMITS, QualityProfile, RenderBounds, TimelineClipInput, TimelineInput, clip, compileSequence, createBoardExtensionRegistry, timeline } from "./animation.js";
|
|
3
|
-
import { ArrowEndpoint, ArrowEndpointSchema, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema,
|
|
3
|
+
import { ArrowEndpoint, ArrowEndpointSchema, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, BoardMediaSnapshot, BoardMediaSnapshotSchema, BoardTextItem, BoardTextItemSchema, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, DrawPoint, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, SpaceFileRef, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardItemLoose, unknownRealType } from "../protocol/dist/board-document.js";
|
|
4
4
|
import { BOARD_NODE_SOURCE, DEFAULT_BOARD_APPEARANCE, ITEM_BASE_KEYS, WireBackedBoardItem, boardBootstrapToDocument, boardNodeToItem, isRecord, nodeInputFromRecord, sourceForItem } from "./codec.js";
|
|
5
|
-
import { CORNER_RESIZE_HANDLES, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ScreenPoint, Size, VIEWPORT_MARGIN_RATIO, WorldPoint, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
|
|
5
|
+
import { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CornerResizeHandle, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, ResizeHandle, ScreenPoint, Size, VIEWPORT_MARGIN_RATIO, WorldPoint, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
|
|
6
6
|
import { FrameLookup, ResolvedArrow, anchorToWorld, arrowBounds, bindEndpointAt, distanceToArrow, resolveArrow, resolveEndpoint, sampleQuadratic, translateArrow, worldToAnchor } from "./core/bindings.js";
|
|
7
7
|
import { buildStrokeOutline, computeDrawBounds, distanceToStroke, sampleRadius, simplifyDrawIndices } from "./core/draw-geometry.js";
|
|
8
8
|
import { BOARD_EXPORT_MAX_TEXTURES, BoardExportAssetSelection, selectBoardExportAssets } from "./core/export-assets.js";
|
|
9
9
|
import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, boardFrameLookup, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./core/export-plan.js";
|
|
10
|
-
import { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileAvailability, FilePreviewKind, ResolvedCover, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./core/file-preview.js";
|
|
10
|
+
import { BoardFileSnapshotFacts, BuildSnapshotInput, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FileAvailability, FilePreviewKind, ResolvedCover, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, readTitleFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./core/file-preview.js";
|
|
11
11
|
import { BOARD_COLORS, BoardColorEntry, BoardColorId, BoardColorValue, BoardShapeColors, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor } from "./core/palette.js";
|
|
12
|
-
import { ArrowShapeProps, DrawShapeProps, FULL_CAPABILITIES, GEO_KINDS, GeoKind, GeoShapeProps, HandleDragResult, ImageShapeProps,
|
|
12
|
+
import { ArrowShapeProps, DrawShapeProps, FULL_CAPABILITIES, GEO_KINDS, GeoKind, GeoShapeProps, HandleDragResult, ImageShapeProps, ShapeCapabilities, ShapeGeometry, ShapeHandle, ShapeHandleId, ShapeResizeMode, TextShapeProps, VideoShapeProps, isGeoKind, resizeModeForCapabilities } from "./core/shape-types.js";
|
|
13
13
|
import { ShapeDefinition, definitionForItem, getShapeDefinition, registerShapeDefinition, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, unknownShapeDefinition } from "./core/shape-definition.js";
|
|
14
14
|
import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardTextLineHeight, clampBoardTextFontSize, measureBoardText, setBoardTextMeasurer } from "./core/text-metrics.js";
|
|
15
|
+
import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BoardStyledToolId, BoardToolStyleMap, BoardToolStylePatch, DEFAULT_BOARD_TOOL_STYLES, clampBoardStrokeSize, createBoardToolStyles } from "./core/tool-styles.js";
|
|
15
16
|
import { boardImageKeySource, imageAssetKey } from "./image-key.js";
|
|
16
|
-
export { ArrowEndpoint, ArrowEndpointSchema, type ArrowShapeProps, BOARD_COLORS, BOARD_DOCUMENT_KIND, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION, BOARD_NODE_SOURCE, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardColorEntry, BoardColorId, BoardColorValue, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, type BoardManifest, BoardMediaSnapshot, BoardMediaSnapshotSchema, type BoardNodeRecord,
|
|
17
|
+
export { ArrowEndpoint, ArrowEndpointSchema, type ArrowShapeProps, BOARD_COLORS, BOARD_DOCUMENT_KIND, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION, BOARD_NODE_SOURCE, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BoardAppearance, BoardAppearanceSchema, BoardArrowItem, BoardArrowItemSchema, BoardColorEntry, BoardColorId, BoardColorValue, BoardDocument, BoardDocumentSchema, BoardDrawItem, BoardDrawItemSchema, BoardExportAssetSelection, BoardExportPlan, BoardExportPlanInput, BoardExportRegion, BoardExtensionDefinition, BoardExtensionRegistry, BoardFileItem, BoardFileItemSchema, BoardFileSnapshot, BoardFileSnapshotFacts, BoardFileSnapshotSchema, BoardFrame, BoardFrameItem, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItem, BoardGeoItemSchema, BoardImageItem, BoardImageItemSchema, BoardItem, BoardItemSchema, BoardItemStyle, BoardItemStyleSchema, BoardKnownItem, type BoardManifest, BoardMediaSnapshot, BoardMediaSnapshotSchema, type BoardNodeRecord, BoardPresetDefinition, type BoardRecord, BoardShapeColors, BoardStyledToolId, BoardTextItem, BoardTextItemSchema, BoardToolStyleMap, BoardToolStylePatch, BoardUnknownItem, BoardVideoItem, BoardVideoItemSchema, BoardViewport, BoardViewportSchema, BuildSnapshotInput, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, CompiledSequence, CornerResizeHandle, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_TOOL_STYLES, DrawPoint, DrawPointSchema, type DrawShapeProps, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, FileAvailability, FilePreviewKind, FrameLookup, GEO_KINDS, type GeoKind, type GeoShapeProps, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, type HandleDragResult, ITEM_BASE_KEYS, type ImageShapeProps, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, KnownBoardItemType, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, Point, QualityProfile, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, Rect, RenderBounds, ResizeHandle, ResolvedArrow, ResolvedCover, ScreenPoint, type ShapeCapabilities, ShapeDefinition, type ShapeGeometry, type ShapeHandle, type ShapeHandleId, type ShapeResizeMode, Size, SpaceFileRef, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, type TextShapeProps, TimelineClipInput, TimelineInput, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, type VideoShapeProps, WireBackedBoardItem, WorldPoint, anchorToWorld, angleFromCenter, arrowBounds, availabilityFromError, bindEndpointAt, boardBootstrapToDocument, boardColorCssVar, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardTextLineHeight, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, clip, compileSequence, computeDrawBounds, createBoardExtensionRegistry, createBoardToolStyles, definitionForItem, degToRad, distanceToArrow, distanceToStroke, expandRect, exportItemBounds, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getShapeDefinition, handlePosition, imageAssetKey, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardDocument, normalizeRotation, normalizeViewport, panBy, parseBoardItemLoose, parseBoardManifest, pickBoardColor, planBoardExport, pointToWorld, radToDeg, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectsIntersect, registerShapeDefinition, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveCoverRef, resolveEndpoint, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleQuadratic, sampleRadius, scaleFrames, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, timeline, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, visibleWorldRect, worldPoint, worldToAnchor, worldToScreen, zoomAround };
|
package/dist/board/index.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { BoardExtensionRegistry, DEFAULT_BOARD_LIMITS, clip, compileSequence, createBoardExtensionRegistry, timeline } from "./animation.js";
|
|
2
2
|
import { BOARD_DOCUMENT_KIND, BOARD_EXTENSION, InvalidBoardFileError, isBoardPath, parseBoardManifest, serializeBoardManifest } from "../protocol/dist/board.js";
|
|
3
|
-
import { ArrowEndpointSchema, BoardAppearanceSchema, BoardArrowItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema,
|
|
3
|
+
import { ArrowEndpointSchema, BoardAppearanceSchema, BoardArrowItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, DrawPointSchema, KNOWN_BOARD_ITEM_TYPES, SpaceFileRefSchema, UNKNOWN_BOARD_ITEM_TYPE, isFileBackedItem, isMediaItem, isUnknownItem, parseBoardItemLoose, unknownRealType } from "../protocol/dist/board-document.js";
|
|
4
4
|
import { TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, boardTextLineHeight, clampBoardTextFontSize, measureBoardText, setBoardTextMeasurer } from "./core/text-metrics.js";
|
|
5
5
|
import { BOARD_NODE_SOURCE, DEFAULT_BOARD_APPEARANCE, ITEM_BASE_KEYS, boardBootstrapToDocument, boardNodeToItem, isRecord, nodeInputFromRecord, sourceForItem } from "./codec.js";
|
|
6
|
-
import { CORNER_RESIZE_HANDLES, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
|
|
6
|
+
import { CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, EDGE_RESIZE_HANDLES, FIT_PADDING, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, VIEWPORT_MARGIN_RATIO, angleFromCenter, clamp, clampZoom, degToRad, expandRect, fitToContent, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, handlePosition, itemBounds, normalizeRotation, normalizeViewport, panBy, pointToWorld, radToDeg, rectCenter, rectContainsPoint, rectsIntersect, resizeFrame, resizeFrameToSize, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, scaleFrames, screenPoint, screenToWorld, selectionBounds, unionRects, visibleWorldRect, worldPoint, worldToScreen, zoomAround } from "./geometry.js";
|
|
7
7
|
import { boardImageKeySource, imageAssetKey } from "./image-key.js";
|
|
8
8
|
import { anchorToWorld, arrowBounds, bindEndpointAt, distanceToArrow, resolveArrow, resolveEndpoint, sampleQuadratic, translateArrow, worldToAnchor } from "./core/bindings.js";
|
|
9
9
|
import { buildStrokeOutline, computeDrawBounds, distanceToStroke, sampleRadius, simplifyDrawIndices } from "./core/draw-geometry.js";
|
|
10
10
|
import { BOARD_EXPORT_MAX_TEXTURES, selectBoardExportAssets } from "./core/export-assets.js";
|
|
11
11
|
import { BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, boardFrameLookup, exportItemBounds, normalizeBoardDocument, planBoardExport } from "./core/export-plan.js";
|
|
12
|
-
import { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./core/file-preview.js";
|
|
12
|
+
import { FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, availabilityFromError, buildFileExcerpt, buildFileSnapshot, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, formatFileSize, isFileSnapshotFresh, mergeFileSnapshot, readCoverFromFrontmatter, readTitleFromFrontmatter, resolveCoverRef, resolveSpacePath, shouldFetchFileExcerpt, splitFrontmatter } from "./core/file-preview.js";
|
|
13
13
|
import { BOARD_COLORS, DEFAULT_BOARD_COLOR, boardColorCssVar, buildFallbackShapeColors, isBoardColorId, pickBoardColor, resolveBoardColor } from "./core/palette.js";
|
|
14
14
|
import { FULL_CAPABILITIES, GEO_KINDS, isGeoKind, resizeModeForCapabilities } from "./core/shape-types.js";
|
|
15
15
|
import { definitionForItem, getShapeDefinition, registerShapeDefinition, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, unknownShapeDefinition } from "./core/shape-definition.js";
|
|
16
|
-
|
|
16
|
+
import { BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, DEFAULT_BOARD_TOOL_STYLES, clampBoardStrokeSize, createBoardToolStyles } from "./core/tool-styles.js";
|
|
17
|
+
export { ArrowEndpointSchema, BOARD_COLORS, BOARD_DOCUMENT_KIND, BOARD_EXPORT_DEFAULT_PADDING, BOARD_EXPORT_DEFAULT_SCALE, BOARD_EXPORT_ITEM_WARN_THRESHOLD, BOARD_EXPORT_MAX_EDGE, BOARD_EXPORT_MAX_PIXELS, BOARD_EXPORT_MAX_TEXTURES, BOARD_EXTENSION, BOARD_NODE_SOURCE, BOARD_STROKE_MAX_SIZE, BOARD_STROKE_MIN_SIZE, BoardAppearanceSchema, BoardArrowItemSchema, BoardDocumentSchema, BoardDrawItemSchema, BoardExtensionRegistry, BoardFileItemSchema, BoardFileSnapshotSchema, BoardFrameItemSchema, BoardFrameSchema, BoardGeoItemSchema, BoardImageItemSchema, BoardItemSchema, BoardItemStyleSchema, BoardMediaSnapshotSchema, BoardTextItemSchema, BoardVideoItemSchema, BoardViewportSchema, CORNER_RESIZE_HANDLES, CORNER_ROTATION_ZONE_WIDTH, DEFAULT_BOARD_APPEARANCE, DEFAULT_BOARD_COLOR, DEFAULT_BOARD_LIMITS, DEFAULT_BOARD_TOOL_STYLES, DrawPointSchema, EDGE_RESIZE_HANDLES, FILE_EXCERPT_MAX_BYTES, FILE_EXCERPT_MAX_CHARS, FIT_PADDING, FULL_CAPABILITIES, GEO_KINDS, HANDLE_DIRECTION, HANDLE_HIT_RADIUS, ITEM_BASE_KEYS, InvalidBoardFileError, KNOWN_BOARD_ITEM_TYPES, MAX_BOARD_ZOOM, MIN_BOARD_ZOOM, MIN_ITEM_SIZE, RESIZE_HANDLES, ROTATION_HANDLE_OFFSET, SpaceFileRefSchema, TEXT_FONT_FAMILY, TEXT_FONT_SIZE, TEXT_LINE_HEIGHT, TEXT_MAX_FONT_SIZE, TEXT_MIN_FONT_SIZE, UNKNOWN_BOARD_ITEM_TYPE, VIEWPORT_MARGIN_RATIO, anchorToWorld, angleFromCenter, arrowBounds, availabilityFromError, bindEndpointAt, boardBootstrapToDocument, boardColorCssVar, boardFrameLookup, boardImageKeySource, boardNodeToItem, boardTextLineHeight, buildFallbackShapeColors, buildFileExcerpt, buildFileSnapshot, buildStrokeOutline, clamp, clampBoardStrokeSize, clampBoardTextFontSize, clampZoom, clip, compileSequence, computeDrawBounds, createBoardExtensionRegistry, createBoardToolStyles, definitionForItem, degToRad, distanceToArrow, distanceToStroke, expandRect, exportItemBounds, fileBaseName, filePreviewKind, filePreviewMemoKey, filePreviewScope, fileTypeLabel, fitToContent, formatFileSize, frameContainsPoint, frameCornerRotationHandleAt, frameCorners, frameEdgeHandleAt, frameHandlePosition, frameRayIntersection, frameRect, getShapeDefinition, handlePosition, imageAssetKey, isBoardColorId, isBoardPath, isFileBackedItem, isFileSnapshotFresh, isGeoKind, isMediaItem, isRecord, isUnknownItem, itemBounds, measureBoardText, mergeFileSnapshot, nodeInputFromRecord, normalizeBoardDocument, normalizeRotation, normalizeViewport, panBy, parseBoardItemLoose, parseBoardManifest, pickBoardColor, planBoardExport, pointToWorld, radToDeg, readCoverFromFrontmatter, readTitleFromFrontmatter, rectCenter, rectContainsPoint, rectsIntersect, registerShapeDefinition, resizeFrame, resizeFrameToSize, resizeModeForCapabilities, resolveArrow, resolveBoardColor, resolveCoverRef, resolveEndpoint, resolveSpacePath, rotateFrames, rotatePointAround, rotationHandleAnchor, rotationHandlePosition, sampleQuadratic, sampleRadius, scaleFrames, screenPoint, screenToWorld, selectBoardExportAssets, selectionBounds, serializeBoardManifest, setBoardTextMeasurer, shapeBounds, shapeCapabilities, shapeHandles, shapeHitTest, shapeResizeMode, shouldFetchFileExcerpt, simplifyDrawIndices, sourceForItem, splitFrontmatter, timeline, translateArrow, unionRects, unknownRealType, unknownShapeDefinition, visibleWorldRect, worldPoint, worldToAnchor, worldToScreen, zoomAround };
|
|
@@ -5,14 +5,12 @@ import { fileCardRenderer } from "./file-card-renderer.js";
|
|
|
5
5
|
import { frameCardRenderer } from "./frame-card-renderer.js";
|
|
6
6
|
import { geoCardRenderer } from "./geo-card-renderer.js";
|
|
7
7
|
import { imageCardRenderer } from "./image-card-renderer.js";
|
|
8
|
-
import { noteCardRenderer } from "./note-card-renderer.js";
|
|
9
8
|
import { textCardRenderer } from "./text-card-renderer.js";
|
|
10
9
|
import { unknownCardRenderer } from "./unknown-card-renderer.js";
|
|
11
10
|
import { videoCardRenderer } from "./video-card-renderer.js";
|
|
12
11
|
//#region src/board/render/renderers/board-renderer-registry.ts
|
|
13
12
|
const boardCardRenderers = [
|
|
14
13
|
textCardRenderer,
|
|
15
|
-
noteCardRenderer,
|
|
16
14
|
imageCardRenderer,
|
|
17
15
|
videoCardRenderer,
|
|
18
16
|
fileCardRenderer,
|
|
@@ -26,8 +26,15 @@ declare function fitLineWithEllipsis(line: string, wrapWidth: number, measureWid
|
|
|
26
26
|
* the last kept line. No character-by-character multi-line remeasure.
|
|
27
27
|
*/
|
|
28
28
|
declare function fitTextToLines(text: Text, value: string, maxLines: number, wrapWidth: number): void;
|
|
29
|
+
/** Scale an image into a fixed cover band without cropping or distortion. */
|
|
30
|
+
declare function containCoverRect(width: number, height: number, imageWidth: number, imageHeight: number): {
|
|
31
|
+
x: number;
|
|
32
|
+
y: number;
|
|
33
|
+
width: number;
|
|
34
|
+
height: number;
|
|
35
|
+
};
|
|
29
36
|
declare const fileCardRenderer: BoardCardRenderer;
|
|
30
37
|
/** Helper kept for type narrowing in tests. */
|
|
31
38
|
declare function isFileItem(item: BoardItem): item is BoardFileItem;
|
|
32
39
|
//#endregion
|
|
33
|
-
export { ellipsizeWrappedLines, fileCardRenderer, fitLineWithEllipsis, fitTextToLines, isFileItem };
|
|
40
|
+
export { containCoverRect, ellipsizeWrappedLines, fileCardRenderer, fitLineWithEllipsis, fitTextToLines, isFileItem };
|