@reekon-tools/boldr-utils 1.26.1 → 1.26.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/annotation/canvas/pdfCanvasPages.d.ts +7 -4
- package/dist/annotation/canvas/pdfCanvasPages.js +93 -14
- package/dist/annotation/canvas/tileCalibration.d.ts +16 -0
- package/dist/annotation/canvas/tileCalibration.js +91 -0
- package/dist/annotation/canvas/useAnnotationCanvasState.js +7 -67
- package/dist/annotation/data/hooks/usePdfCanvasDoc.js +24 -7
- package/dist/export/pdf/renderCanvasToPdf.js +7 -5
- package/dist/export/pdf/types.d.ts +11 -0
- package/dist/exports.d.ts +2 -1
- package/dist/exports.js +2 -1
- package/dist/server.d.ts +2 -1
- package/dist/server.js +2 -1
- package/dist/types/pdfCanvas.d.ts +12 -1
- package/package.json +1 -1
- package/dist/canvas/AnnotationCanvas.d.ts +0 -11
- package/dist/canvas/AnnotationCanvas.js +0 -10
- package/dist/canvas/AnnotationCanvas.native.d.ts +0 -8
- package/dist/canvas/AnnotationCanvas.native.js +0 -6
- package/dist/canvas/AnnotationCanvasInner.d.ts +0 -39
- package/dist/canvas/AnnotationCanvasInner.js +0 -219
- package/dist/canvas/AnnotationCanvasInner.native.d.ts +0 -35
- package/dist/canvas/AnnotationCanvasInner.native.js +0 -138
- package/dist/canvas/AnnotationCanvasSkia.d.ts +0 -27
- package/dist/canvas/AnnotationCanvasSkia.js +0 -20
- package/dist/canvas/Tool.d.ts +0 -38
- package/dist/canvas/Tool.js +0 -1
- package/dist/canvas/elements/BackgroundImageElement.d.ts +0 -9
- package/dist/canvas/elements/BackgroundImageElement.js +0 -37
- package/dist/canvas/elements/MeasurementStampElement.d.ts +0 -13
- package/dist/canvas/elements/MeasurementStampElement.js +0 -30
- package/dist/canvas/elements/ShapeElement.d.ts +0 -7
- package/dist/canvas/elements/ShapeElement.js +0 -62
- package/dist/canvas/elements/StrokeElement.d.ts +0 -7
- package/dist/canvas/elements/StrokeElement.js +0 -18
- package/dist/canvas/measurementPicker.d.ts +0 -10
- package/dist/canvas/measurementPicker.js +0 -1
- package/dist/canvas/measurementStampOverlay.d.ts +0 -11
- package/dist/canvas/measurementStampOverlay.js +0 -1
- package/dist/canvas/pointerAdapter.d.ts +0 -3
- package/dist/canvas/pointerAdapter.js +0 -19
- package/dist/canvas/stampLayout.d.ts +0 -5
- package/dist/canvas/stampLayout.js +0 -14
- package/dist/canvas/tools/measurementStampTool.d.ts +0 -9
- package/dist/canvas/tools/measurementStampTool.js +0 -37
- package/dist/canvas/tools/panTool.d.ts +0 -5
- package/dist/canvas/tools/panTool.js +0 -25
- package/dist/canvas/tools/penTool.d.ts +0 -13
- package/dist/canvas/tools/penTool.js +0 -68
- package/dist/canvas/tools/selectTool.d.ts +0 -2
- package/dist/canvas/tools/selectTool.js +0 -182
- package/dist/canvas/useAnnotationCanvasState.d.ts +0 -54
- package/dist/canvas/useAnnotationCanvasState.js +0 -210
- package/dist/canvas/viewport.d.ts +0 -16
- package/dist/canvas/viewport.js +0 -54
- package/dist/data/AnnotationDataContext.d.ts +0 -8
- package/dist/data/AnnotationDataContext.js +0 -11
- package/dist/data/AnnotationDataProvider.d.ts +0 -65
- package/dist/data/AnnotationDataProvider.js +0 -4
- package/dist/data/InMemoryAnnotationProvider.d.ts +0 -30
- package/dist/data/InMemoryAnnotationProvider.js +0 -197
- package/dist/data/canvasPersistence.d.ts +0 -3
- package/dist/data/canvasPersistence.js +0 -26
- package/dist/data/hooks/useAnnotationCanvasDoc.d.ts +0 -33
- package/dist/data/hooks/useAnnotationCanvasDoc.js +0 -314
- package/dist/data/hooks/useAnnotationDoc.d.ts +0 -7
- package/dist/data/hooks/useAnnotationDoc.js +0 -33
- package/dist/data/hooks/useAnnotationList.d.ts +0 -7
- package/dist/data/hooks/useAnnotationList.js +0 -26
- package/dist/data/hooks/useAnnotationMutations.d.ts +0 -9
- package/dist/data/hooks/useAnnotationMutations.js +0 -11
- package/dist/hooks/useParseMeasurement.d.ts +0 -4
- package/dist/hooks/useParseMeasurement.js +0 -14
- package/dist/utils/evaluateFormula.d.ts +0 -20
- package/dist/utils/evaluateFormula.js +0 -31
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type AnnotationCanvasState, type AnnotationPdfDocument, type Vec2 } from '../../types/annotation.js';
|
|
2
|
-
import type { PdfCanvasData, PdfCanvasPage, PdfCanvasPageState, PdfCanvasRev, PdfPageRotation } from '../../types/pdfCanvas.js';
|
|
1
|
+
import { type AnnotationCanvasState, type AnnotationPdfDocument, type PlacedMeasurementRef, type Vec2 } from '../../types/annotation.js';
|
|
2
|
+
import type { PdfCanvasData, PdfCanvasPage, PdfCanvasPageState, PdfCanvasPlacement, PdfCanvasTileScales, PdfCanvasRev, PdfPageRotation } from '../../types/pdfCanvas.js';
|
|
3
3
|
export interface PdfPageDisplaySize {
|
|
4
4
|
width: number;
|
|
5
5
|
height: number;
|
|
@@ -10,16 +10,19 @@ export declare const pdfPageDisplaySize: (page: Pick<PdfCanvasPage, "width" | "h
|
|
|
10
10
|
export declare const pdfCanvasPageDocId: (pageIndex: number) => string;
|
|
11
11
|
export declare const emptyPdfCanvasPageState: (pageIndex: number) => PdfCanvasPageState;
|
|
12
12
|
export declare const pdfCanvasPageDocument: (data: PdfCanvasData, pageIndex: number) => AnnotationPdfDocument;
|
|
13
|
-
type PdfCanvasKnobs =
|
|
13
|
+
type PdfCanvasKnobs = PdfCanvasTileScales;
|
|
14
14
|
export declare const pdfCanvasKnobsOf: (source: Partial<PdfCanvasKnobs>) => PdfCanvasKnobs;
|
|
15
15
|
export declare const pdfCanvasKnobsEqual: (a: Partial<PdfCanvasKnobs>, b: Partial<PdfCanvasKnobs>) => boolean;
|
|
16
|
+
export declare const pdfCanvasPageKnobs: (data: Pick<PdfCanvasData, "pageTileScales"> & PdfCanvasKnobs, pageIndex: number) => PdfCanvasKnobs;
|
|
16
17
|
export declare const pageStateToCanvasState: (data: PdfCanvasData, pageState: PdfCanvasPageState | null, pageIndex: number) => AnnotationCanvasState;
|
|
17
18
|
export declare const canvasStateToPageState: (canvas: AnnotationCanvasState, pageIndex: number, stamp: {
|
|
18
19
|
updatedAt: number;
|
|
19
20
|
rev?: PdfCanvasRev;
|
|
20
21
|
}) => PdfCanvasPageState;
|
|
22
|
+
export declare const pdfCanvasPagePlacements: (placed: readonly PlacedMeasurementRef[]) => PdfCanvasPlacement[];
|
|
23
|
+
export declare const pdfCanvasPlacementsOf: (pdfCanvas: Pick<PdfCanvasData, "placementsByPage"> | null | undefined) => PdfCanvasPlacement[];
|
|
21
24
|
export type PdfRotationDelta = 90 | -90 | 180;
|
|
22
25
|
export declare const rotatePointInPage: (p: Vec2, size: PdfPageDisplaySize, delta: PdfRotationDelta) => Vec2;
|
|
23
|
-
export declare const rotatePageState: <T extends Pick<PdfCanvasPageState, "strokes" | "shapes" | "placedMeasurements" | "planes">>(state: T, currentSize: PdfPageDisplaySize, delta: PdfRotationDelta) => T;
|
|
26
|
+
export declare const rotatePageState: <T extends Pick<PdfCanvasPageState, "strokes" | "shapes" | "placedMeasurements" | "planes" | "backgroundImages">>(state: T, currentSize: PdfPageDisplaySize, delta: PdfRotationDelta) => T;
|
|
24
27
|
export declare const rotatePdfCanvasPage: (page: PdfCanvasPage, delta: PdfRotationDelta) => PdfCanvasPage;
|
|
25
28
|
export {};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// AnnotationCanvasState the engine mounts, and the coordinate transform that
|
|
4
4
|
// turns a page's annotations with it when the page is rotated.
|
|
5
5
|
import { createDefaultLayer, createEmptyCanvasState, } from '../../types/annotation.js';
|
|
6
|
+
import { backgroundLayerFullDocRect, backgroundLayersOf, } from './backgroundLayers.js';
|
|
6
7
|
import { textShapeBounds } from './textGeometry.js';
|
|
7
8
|
// Snap any degree value onto the four legal rotations, modulo 360.
|
|
8
9
|
export const normalizePdfRotation = (deg) => {
|
|
@@ -58,7 +59,8 @@ const KNOB_KEYS = [
|
|
|
58
59
|
'headerTileScaleFactorMobile',
|
|
59
60
|
'tileDocSize',
|
|
60
61
|
];
|
|
61
|
-
// The
|
|
62
|
+
// The tile-scale knobs present on a canvas or knob record (undefined keys
|
|
63
|
+
// omitted).
|
|
62
64
|
export const pdfCanvasKnobsOf = (source) => {
|
|
63
65
|
const out = {};
|
|
64
66
|
for (const key of KNOB_KEYS) {
|
|
@@ -69,6 +71,13 @@ export const pdfCanvasKnobsOf = (source) => {
|
|
|
69
71
|
return out;
|
|
70
72
|
};
|
|
71
73
|
export const pdfCanvasKnobsEqual = (a, b) => KNOB_KEYS.every((key) => a[key] === b[key]);
|
|
74
|
+
// One page's tile-scale knobs: its own `pageTileScales` entry, else the
|
|
75
|
+
// legacy file-wide knobs (files written before scale went per-page, Asana
|
|
76
|
+
// 1218877420681571 — they keep their look until a page's knobs change).
|
|
77
|
+
export const pdfCanvasPageKnobs = (data, pageIndex) => {
|
|
78
|
+
const own = data.pageTileScales?.[String(pageIndex)];
|
|
79
|
+
return pdfCanvasKnobsOf(own && typeof own === 'object' ? own : data);
|
|
80
|
+
};
|
|
72
81
|
// The AnnotationCanvasState the editor mounts for one page. A null page state
|
|
73
82
|
// (never annotated) yields an empty canvas over the page.
|
|
74
83
|
export const pageStateToCanvasState = (data, pageState, pageIndex) => {
|
|
@@ -81,7 +90,15 @@ export const pageStateToCanvasState = (data, pageState, pageIndex) => {
|
|
|
81
90
|
});
|
|
82
91
|
return {
|
|
83
92
|
...base,
|
|
84
|
-
...
|
|
93
|
+
...pdfCanvasPageKnobs(data, pageIndex),
|
|
94
|
+
...(pageState?.backgroundImages?.length
|
|
95
|
+
? {
|
|
96
|
+
viewport: {
|
|
97
|
+
...base.viewport,
|
|
98
|
+
backgroundImages: pageState.backgroundImages,
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
: {}),
|
|
85
102
|
layers: pageState && pageState.layers.length > 0 ? pageState.layers : base.layers,
|
|
86
103
|
strokes: pageState?.strokes ?? [],
|
|
87
104
|
shapes: pageState?.shapes ?? [],
|
|
@@ -90,18 +107,60 @@ export const pageStateToCanvasState = (data, pageState, pageIndex) => {
|
|
|
90
107
|
};
|
|
91
108
|
};
|
|
92
109
|
// Inverse of pageStateToCanvasState: the elements to persist for one page.
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
// The viewport's size and pdfDocument are derived from the file record and
|
|
111
|
+
// never stored on the page doc; its image layers are page CONTENT (an
|
|
112
|
+
// expanded image tile lives there) and are.
|
|
113
|
+
export const canvasStateToPageState = (canvas, pageIndex, stamp) => {
|
|
114
|
+
const backgroundImages = backgroundLayersOf(canvas.viewport);
|
|
115
|
+
return {
|
|
116
|
+
schemaVersion: 1,
|
|
117
|
+
pageIndex,
|
|
118
|
+
layers: canvas.layers,
|
|
119
|
+
strokes: canvas.strokes,
|
|
120
|
+
shapes: canvas.shapes,
|
|
121
|
+
placedMeasurements: canvas.placedMeasurements,
|
|
122
|
+
...(canvas.planes !== undefined ? { planes: canvas.planes } : {}),
|
|
123
|
+
...(backgroundImages.length > 0 ? { backgroundImages } : {}),
|
|
124
|
+
updatedAt: stamp.updatedAt,
|
|
125
|
+
...(stamp.rev ? { rev: stamp.rev } : {}),
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
// The measurement bindings of one page's tiles, for
|
|
129
|
+
// `PdfCanvasData.placementsByPage`. Group-header chips, object tiles and
|
|
130
|
+
// unbound tiles (a plane dimension, an unbound "+") bind no measurement and
|
|
131
|
+
// are left out, so an empty list means "nothing placed on this page".
|
|
132
|
+
export const pdfCanvasPagePlacements = (placed) => {
|
|
133
|
+
const out = [];
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
for (const p of placed) {
|
|
136
|
+
if (!p || p.isGroupHeader || p.fileId)
|
|
137
|
+
continue;
|
|
138
|
+
const bound = !!p.measurementId || !!p.measurementPath;
|
|
139
|
+
if (!bound && !(p.groupId && p.columnId))
|
|
140
|
+
continue;
|
|
141
|
+
const entry = {
|
|
142
|
+
...(p.measurementId ? { measurementId: p.measurementId } : {}),
|
|
143
|
+
...(p.measurementPath ? { measurementPath: p.measurementPath } : {}),
|
|
144
|
+
...(p.groupId ? { groupId: p.groupId } : {}),
|
|
145
|
+
...(p.columnId ? { columnId: p.columnId } : {}),
|
|
146
|
+
};
|
|
147
|
+
const key = JSON.stringify(entry);
|
|
148
|
+
if (seen.has(key))
|
|
149
|
+
continue;
|
|
150
|
+
seen.add(key);
|
|
151
|
+
out.push(entry);
|
|
152
|
+
}
|
|
153
|
+
return out;
|
|
154
|
+
};
|
|
155
|
+
// Every page's measurement bindings on a PdfCanvas file, flattened — what the
|
|
156
|
+
// placed-in-file readers treat exactly like an inline canvas's
|
|
157
|
+
// placedMeasurements.
|
|
158
|
+
export const pdfCanvasPlacementsOf = (pdfCanvas) => {
|
|
159
|
+
const byPage = pdfCanvas?.placementsByPage;
|
|
160
|
+
if (!byPage || typeof byPage !== 'object')
|
|
161
|
+
return [];
|
|
162
|
+
return Object.values(byPage).flatMap((list) => Array.isArray(list) ? list : []);
|
|
163
|
+
};
|
|
105
164
|
export const rotatePointInPage = (p, size, delta) => {
|
|
106
165
|
switch (normalizePdfRotation(delta)) {
|
|
107
166
|
case 90:
|
|
@@ -237,10 +296,30 @@ const rotatePlane = (plane, size, delta) => {
|
|
|
237
296
|
}),
|
|
238
297
|
};
|
|
239
298
|
};
|
|
299
|
+
// Image layers carry no rotation (a transform is translate + scale), so like
|
|
300
|
+
// text they stay upright: the layer keeps its size and is re-anchored so the
|
|
301
|
+
// centre of its full image turns with the page.
|
|
302
|
+
const rotateBackgroundLayer = (layer, size, delta) => {
|
|
303
|
+
const full = backgroundLayerFullDocRect(layer);
|
|
304
|
+
const centre = rotatePointInPage({ x: full.x + full.width / 2, y: full.y + full.height / 2 }, size, delta);
|
|
305
|
+
return {
|
|
306
|
+
...layer,
|
|
307
|
+
transform: {
|
|
308
|
+
...layer.transform,
|
|
309
|
+
x: centre.x - full.width / 2,
|
|
310
|
+
y: centre.y - full.height / 2,
|
|
311
|
+
},
|
|
312
|
+
};
|
|
313
|
+
};
|
|
240
314
|
// Rewrite every coordinate of a page's state from its current displayed size
|
|
241
315
|
// into the size it will have after turning by `delta`.
|
|
242
316
|
export const rotatePageState = (state, currentSize, delta) => ({
|
|
243
317
|
...state,
|
|
318
|
+
...(state.backgroundImages !== undefined
|
|
319
|
+
? {
|
|
320
|
+
backgroundImages: state.backgroundImages.map((l) => rotateBackgroundLayer(l, currentSize, delta)),
|
|
321
|
+
}
|
|
322
|
+
: {}),
|
|
244
323
|
strokes: state.strokes.map((s) => rotateStroke(s, currentSize, delta)),
|
|
245
324
|
shapes: state.shapes.map((s) => rotateShape(s, currentSize, delta)),
|
|
246
325
|
placedMeasurements: state.placedMeasurements.map((p) => rotatePlaced(p, currentSize, delta)),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AnnotationCanvasState, TileScalePlatform } from '../../types/annotation.js';
|
|
2
|
+
import type { PdfCanvasData, PdfCanvasPageState } from '../../types/pdfCanvas.js';
|
|
3
|
+
export declare const computeBaseFitZoom: (canvas: AnnotationCanvasState, width: number, height: number) => number;
|
|
4
|
+
export interface ResolvedTileFactors {
|
|
5
|
+
tileScaleFactor: number;
|
|
6
|
+
headerTileScaleFactor: number;
|
|
7
|
+
fileTileScaleFactor: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const resolveTileFactors: (canvas: AnnotationCanvasState, platform: TileScalePlatform, baseFitZoom: number, hasViewport: boolean) => ResolvedTileFactors;
|
|
10
|
+
export interface TileDocSizes {
|
|
11
|
+
tileDocSize: number;
|
|
12
|
+
headerTileDocSize: number;
|
|
13
|
+
fileTileDocSize: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const tileDocSizesFor: (canvas: AnnotationCanvasState, platform: TileScalePlatform, width: number, height: number) => TileDocSizes;
|
|
16
|
+
export declare const pdfCanvasPageTileDocSizes: (data: PdfCanvasData, pageStates: Partial<Record<number, PdfCanvasPageState>>, platform: TileScalePlatform, width: number, height: number) => Record<number, TileDocSizes>;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// How large tiles are on a canvas, as pure functions — the editor
|
|
2
|
+
// (useAnnotationCanvasState) and the PDF export resolve them the same way.
|
|
3
|
+
//
|
|
4
|
+
// A tile's footprint is base × per-tile `scale` × the platform's document-wide
|
|
5
|
+
// factor, at the canvas's CONTENT-FIT zoom (tiles are doc-constant from there).
|
|
6
|
+
// So how much of the drawing a tile covers depends on the screen the canvas is
|
|
7
|
+
// fitted into: only a client knows its own, and an exporter that wants "the
|
|
8
|
+
// same as on my screen" needs the screen size, not just the stored factors.
|
|
9
|
+
import { backgroundLayerDocRect, backgroundLayersOf, } from './backgroundLayers.js';
|
|
10
|
+
import { pageStateToCanvasState } from './pdfCanvasPages.js';
|
|
11
|
+
import { pdfFirstPageDocRect } from './pdfDocument.js';
|
|
12
|
+
import { resolveFileTileScaleFactor, resolveHeaderTileScaleFactor, resolveTileScaleFactor, tileDocSizeForFactor, tileScaleFromDocSize, } from './stampLayout.js';
|
|
13
|
+
import { fitRectToScreen } from './viewport.js';
|
|
14
|
+
// The content-fit zoom tiles are sized against. A PDF-backed canvas
|
|
15
|
+
// references its FIRST PAGE (not the whole filmstrip — see
|
|
16
|
+
// pdfFirstPageDocRect), whatever image layers sit on it: the PDF is the
|
|
17
|
+
// drawing, and images are placed ON it. Referencing an image instead made
|
|
18
|
+
// every tile on a PDF page jump in size the moment an image object tile was
|
|
19
|
+
// expanded (there was no image before it), and jump back on collapse or
|
|
20
|
+
// delete (Asana 1218877420681573). Otherwise the first image layer — on a
|
|
21
|
+
// photo canvas the photo IS the drawing — else the virtual doc rect.
|
|
22
|
+
export const computeBaseFitZoom = (canvas, width, height) => {
|
|
23
|
+
if (!(width > 0) || !(height > 0))
|
|
24
|
+
return 1;
|
|
25
|
+
const { viewport } = canvas;
|
|
26
|
+
const pdfFirstPage = viewport.pdfDocument
|
|
27
|
+
? pdfFirstPageDocRect(viewport.pdfDocument)
|
|
28
|
+
: null;
|
|
29
|
+
const first = pdfFirstPage ? undefined : backgroundLayersOf(viewport)[0];
|
|
30
|
+
const baseRect = pdfFirstPage ??
|
|
31
|
+
(first ? backgroundLayerDocRect(first) : null) ?? {
|
|
32
|
+
x: 0,
|
|
33
|
+
y: 0,
|
|
34
|
+
width: viewport.width,
|
|
35
|
+
height: viewport.height,
|
|
36
|
+
};
|
|
37
|
+
return fitRectToScreen(baseRect, width, height).zoom;
|
|
38
|
+
};
|
|
39
|
+
// The platform's three tile-kind factors. A mobile canvas whose own knob is
|
|
40
|
+
// still unset derives its factor from the web-stamped doc-space calibration
|
|
41
|
+
// (tileDocSize) instead of web's raw screen-space value: at the content-fit
|
|
42
|
+
// view its tiles then cover the same area of the drawing the web user saw.
|
|
43
|
+
// The header / object factors ride the same calibration ratio so their
|
|
44
|
+
// relation to the measurement factor survives the override. The first mobile
|
|
45
|
+
// slider commit writes tileScaleFactorMobile and takes over for good.
|
|
46
|
+
export const resolveTileFactors = (canvas, platform, baseFitZoom, hasViewport) => {
|
|
47
|
+
let tileScaleFactor = resolveTileScaleFactor(canvas, platform);
|
|
48
|
+
let headerTileScaleFactor = resolveHeaderTileScaleFactor(canvas, platform);
|
|
49
|
+
let fileTileScaleFactor = resolveFileTileScaleFactor(canvas, platform);
|
|
50
|
+
if (platform === 'mobile' &&
|
|
51
|
+
canvas.tileScaleFactorMobile == null &&
|
|
52
|
+
canvas.tileDocSize != null &&
|
|
53
|
+
canvas.tileDocSize > 0 &&
|
|
54
|
+
hasViewport) {
|
|
55
|
+
const calibrated = tileScaleFromDocSize(canvas.tileDocSize, baseFitZoom);
|
|
56
|
+
headerTileScaleFactor =
|
|
57
|
+
tileScaleFactor > 0
|
|
58
|
+
? headerTileScaleFactor * (calibrated / tileScaleFactor)
|
|
59
|
+
: calibrated;
|
|
60
|
+
fileTileScaleFactor =
|
|
61
|
+
tileScaleFactor > 0
|
|
62
|
+
? fileTileScaleFactor * (calibrated / tileScaleFactor)
|
|
63
|
+
: calibrated;
|
|
64
|
+
tileScaleFactor = calibrated;
|
|
65
|
+
}
|
|
66
|
+
return { tileScaleFactor, headerTileScaleFactor, fileTileScaleFactor };
|
|
67
|
+
};
|
|
68
|
+
// The doc-space edge a scale-1 tile of each kind covers on `canvas` when it is
|
|
69
|
+
// fitted into a `width` × `height` view on `platform` — what an export needs
|
|
70
|
+
// to draw tiles exactly as that screen shows them.
|
|
71
|
+
export const tileDocSizesFor = (canvas, platform, width, height) => {
|
|
72
|
+
const zoom = computeBaseFitZoom(canvas, width, height);
|
|
73
|
+
const f = resolveTileFactors(canvas, platform, zoom, width > 0 && height > 0);
|
|
74
|
+
return {
|
|
75
|
+
tileDocSize: tileDocSizeForFactor(f.tileScaleFactor, zoom),
|
|
76
|
+
headerTileDocSize: tileDocSizeForFactor(f.headerTileScaleFactor, zoom),
|
|
77
|
+
fileTileDocSize: tileDocSizeForFactor(f.fileTileScaleFactor, zoom),
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
// Every page of a PdfCanvas file, calibrated as the requesting screen shows
|
|
81
|
+
// it: each page mounts as its own canvas with its own knobs (tile scale is per
|
|
82
|
+
// page — Asana 1218877420681571) and its own content-fit zoom, so one
|
|
83
|
+
// calibration taken from the page on screen would mis-size every other page.
|
|
84
|
+
export const pdfCanvasPageTileDocSizes = (data, pageStates, platform, width, height) => {
|
|
85
|
+
const out = {};
|
|
86
|
+
for (let i = 0; i < data.document.pages.length; i++) {
|
|
87
|
+
const canvas = pageStateToCanvasState(data, pageStates[i] ?? null, i);
|
|
88
|
+
out[i] = tileDocSizesFor(canvas, platform, width, height);
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { applyPatch, invertPatch, DEFAULT_LAYER_ID, } from '../../types/annotation.js';
|
|
3
|
-
import {
|
|
3
|
+
import { stampTileDims, STAMP_TILE_SIZE, tileDocSizeForFactor, } from './stampLayout.js';
|
|
4
4
|
import { SNAP_RADIUS_PX } from './snapGeometry.js';
|
|
5
|
+
import { computeBaseFitZoom, resolveTileFactors } from './tileCalibration.js';
|
|
5
6
|
import { createViewportApi, fitDocRectViewport, fitRectToScreen, panBy, zoomAt, DEFAULT_VIEWPORT, DEFAULT_ZOOM_LIMITS, } from './viewport.js';
|
|
6
|
-
import { computeZoomFloor
|
|
7
|
-
import {
|
|
7
|
+
import { computeZoomFloor } from './pdfDocument.js';
|
|
8
|
+
import { backgroundLayersOf, backgroundLayersUnionRect, } from './backgroundLayers.js';
|
|
8
9
|
import { buildRemoveMeasurementOps, recomputeAnchor, rectCenter, DEFAULT_LINE_POS, } from './measurementGeometry.js';
|
|
9
10
|
// The viewport that frames the document's content inside a screen rect of the
|
|
10
11
|
// canvas box. When background images are present we fit the union of their
|
|
@@ -70,38 +71,6 @@ const computeContentFitRect = (canvas, rect) => {
|
|
|
70
71
|
};
|
|
71
72
|
};
|
|
72
73
|
const computeContentFit = (canvas, width, height) => computeContentFitRect(canvas, { x: 0, y: 0, width, height });
|
|
73
|
-
// Content-fit zoom of the DOCUMENT alone — the FIRST background layer's
|
|
74
|
-
// rendered rect when present, the document rect otherwise, deliberately
|
|
75
|
-
// ignoring placed tiles — into the full canvas box. This is the stable
|
|
76
|
-
// reference zoom for tile sizing (see tileViewportScale below): at this zoom
|
|
77
|
-
// a tile renders at exactly its slider size. computeContentFitRect's
|
|
78
|
-
// tile-extended union would make the reference move whenever a tile is
|
|
79
|
-
// dragged outside the image (every tile on the canvas would resize); the
|
|
80
|
-
// document rect can't. The reference is pinned to the first layer — never
|
|
81
|
-
// the layer union — for the same reason: adding, dragging, or scaling a
|
|
82
|
-
// SECOND image must not silently resize (and re-hit-test) every placed tile
|
|
83
|
-
// on the canvas. For a single-image doc the first layer's rect is exactly
|
|
84
|
-
// the legacy fit rect, so existing canvases keep their tile sizes.
|
|
85
|
-
const computeBaseFitZoom = (canvas, width, height) => {
|
|
86
|
-
if (!(width > 0) || !(height > 0))
|
|
87
|
-
return 1;
|
|
88
|
-
const { viewport } = canvas;
|
|
89
|
-
const first = backgroundLayersOf(viewport)[0];
|
|
90
|
-
// A PDF-backed canvas with no image layers references its FIRST PAGE, not
|
|
91
|
-
// the whole filmstrip — see pdfFirstPageDocRect for why.
|
|
92
|
-
const pdfFirstPage = viewport.pdfDocument
|
|
93
|
-
? pdfFirstPageDocRect(viewport.pdfDocument)
|
|
94
|
-
: null;
|
|
95
|
-
const baseRect = first
|
|
96
|
-
? backgroundLayerDocRect(first)
|
|
97
|
-
: (pdfFirstPage ?? {
|
|
98
|
-
x: 0,
|
|
99
|
-
y: 0,
|
|
100
|
-
width: viewport.width,
|
|
101
|
-
height: viewport.height,
|
|
102
|
-
});
|
|
103
|
-
return fitRectToScreen(baseRect, width, height).zoom;
|
|
104
|
-
};
|
|
105
74
|
// Default leader length (doc units) for a placed measurement when no explicit
|
|
106
75
|
// length is given. A generous fraction of the document width, clamped, so the
|
|
107
76
|
// leader — and its draggable endcaps — stay clear of the value tile at
|
|
@@ -191,38 +160,9 @@ export const useAnnotationCanvasState = (props) => {
|
|
|
191
160
|
// the same area of the image the web user saw. The first mobile slider
|
|
192
161
|
// commit writes tileScaleFactorMobile and takes over for good.
|
|
193
162
|
const tileScalePlatformResolved = tileScalePlatform ?? 'web';
|
|
194
|
-
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
// equals the measurement factor (resolveHeaderTileScaleFactor's fallback) —
|
|
198
|
-
// the pre-split one-knob behavior.
|
|
199
|
-
let headerTileScaleFactor = resolveHeaderTileScaleFactor(effectiveCanvas, tileScalePlatformResolved);
|
|
200
|
-
// Object tiles share the measurement factor — their own knob was retired
|
|
201
|
-
// (see resolveFileTileScaleFactor), so this always equals tileScaleFactor
|
|
202
|
-
// and rides the same calibration below.
|
|
203
|
-
let fileTileScaleFactor = resolveFileTileScaleFactor(effectiveCanvas, tileScalePlatformResolved);
|
|
204
|
-
if (tileScalePlatformResolved === 'mobile' &&
|
|
205
|
-
effectiveCanvas.tileScaleFactorMobile == null &&
|
|
206
|
-
effectiveCanvas.tileDocSize != null &&
|
|
207
|
-
effectiveCanvas.tileDocSize > 0 &&
|
|
208
|
-
width > 0 &&
|
|
209
|
-
height > 0) {
|
|
210
|
-
const calibrated = tileScaleFromDocSize(effectiveCanvas.tileDocSize, baseFitZoom);
|
|
211
|
-
// Scale the header factor by the same calibration ratio so its relation
|
|
212
|
-
// to the measurement factor survives the override: a doc with no header
|
|
213
|
-
// knob keeps headers exactly at the calibrated measurement factor, and a
|
|
214
|
-
// doc whose web user set a header knob keeps the same header-to-tile
|
|
215
|
-
// proportion the web user saw.
|
|
216
|
-
headerTileScaleFactor =
|
|
217
|
-
tileScaleFactor > 0
|
|
218
|
-
? headerTileScaleFactor * (calibrated / tileScaleFactor)
|
|
219
|
-
: calibrated;
|
|
220
|
-
fileTileScaleFactor =
|
|
221
|
-
tileScaleFactor > 0
|
|
222
|
-
? fileTileScaleFactor * (calibrated / tileScaleFactor)
|
|
223
|
-
: calibrated;
|
|
224
|
-
tileScaleFactor = calibrated;
|
|
225
|
-
}
|
|
163
|
+
// Shared with the PDF export (tileCalibration.ts) so an exported page draws
|
|
164
|
+
// its tiles exactly as this screen does.
|
|
165
|
+
const { tileScaleFactor, headerTileScaleFactor, fileTileScaleFactor } = resolveTileFactors(effectiveCanvas, tileScalePlatformResolved, baseFitZoom, width > 0 && height > 0);
|
|
226
166
|
const ctx = useMemo(() => ({
|
|
227
167
|
document: canvas,
|
|
228
168
|
selection,
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import { applyPatch, createEmptyCanvasState, } from '../../../types/annotation.js';
|
|
3
|
-
import { canvasStateToPageState, pageStateToCanvasState, pdfCanvasKnobsEqual, pdfCanvasKnobsOf, pdfPageDisplaySize, rotatePageState, rotatePdfCanvasPage, } from '../../canvas/pdfCanvasPages.js';
|
|
3
|
+
import { canvasStateToPageState, pageStateToCanvasState, pdfCanvasKnobsEqual, pdfCanvasPagePlacements, pdfCanvasKnobsOf, pdfCanvasPageKnobs, pdfPageDisplaySize, rotatePageState, rotatePdfCanvasPage, } from '../../canvas/pdfCanvasPages.js';
|
|
4
4
|
import { useAnnotationData } from '../AnnotationDataContext.js';
|
|
5
5
|
import { annotationScopeKey, } from '../AnnotationDataProvider.js';
|
|
6
|
+
import { backgroundLayersOf } from '../../canvas/backgroundLayers.js';
|
|
6
7
|
import { createCoalescedRunner } from '../coalescedRunner.js';
|
|
7
8
|
import { useAnnotationDoc } from './useAnnotationDoc.js';
|
|
8
9
|
const makeClientId = () => `${Date.now().toString(36)}-${Math.floor(Math.random() * 0x100000000).toString(36)}`;
|
|
9
10
|
const hasContent = (canvas) => canvas.strokes.length > 0 ||
|
|
10
11
|
canvas.shapes.length > 0 ||
|
|
11
12
|
canvas.placedMeasurements.length > 0 ||
|
|
12
|
-
(canvas.planes?.length ?? 0) > 0
|
|
13
|
+
(canvas.planes?.length ?? 0) > 0 ||
|
|
14
|
+
// An expanded image tile is page content too (PdfCanvasPageState
|
|
15
|
+
// .backgroundImages) — a page holding only one must still turn with it.
|
|
16
|
+
backgroundLayersOf(canvas.viewport).length > 0;
|
|
13
17
|
// Drop undefined keys (Firestore — RN in particular — rejects them) and detach
|
|
14
18
|
// the persisted payload from the working state's object identities.
|
|
15
19
|
const jsonClone = (value) => JSON.parse(JSON.stringify(value));
|
|
@@ -120,11 +124,21 @@ export const usePdfCanvasDoc = (options) => {
|
|
|
120
124
|
values: [target.pageIndex],
|
|
121
125
|
};
|
|
122
126
|
}
|
|
127
|
+
// The page's measurement bindings, for the job grid's placed-in-file
|
|
128
|
+
// link (Asana 1218877420681569). Only this page's entry is written,
|
|
129
|
+
// and only when it changed.
|
|
130
|
+
const placements = pdfCanvasPagePlacements(state.placedMeasurements);
|
|
131
|
+
const pageKey = String(target.pageIndex);
|
|
132
|
+
const previous = target.pdfCanvas.placementsByPage?.[pageKey] ?? [];
|
|
133
|
+
if (JSON.stringify(placements) !== JSON.stringify(previous)) {
|
|
134
|
+
patch[`fileData.pdfCanvas.placementsByPage.${pageKey}`] = placements;
|
|
135
|
+
}
|
|
136
|
+
// Tile scale is per page (Asana 1218877420681571): write this page's
|
|
137
|
+
// complete knob set, only when it moved. The legacy file-wide knobs
|
|
138
|
+
// are left alone — they stay the fallback for pages never re-scaled.
|
|
123
139
|
const knobs = pdfCanvasKnobsOf(target.canvas);
|
|
124
|
-
if (!pdfCanvasKnobsEqual(knobs,
|
|
125
|
-
|
|
126
|
-
patch[`fileData.pdfCanvas.${key}`] = value;
|
|
127
|
-
}
|
|
140
|
+
if (!pdfCanvasKnobsEqual(knobs, pdfCanvasPageKnobs(target.pdfCanvas, target.pageIndex))) {
|
|
141
|
+
patch[`fileData.pdfCanvas.pageTileScales.${pageKey}`] = knobs;
|
|
128
142
|
}
|
|
129
143
|
if (Object.keys(patch).length > 0) {
|
|
130
144
|
await provider.update(currentScope, currentFileId, patch);
|
|
@@ -292,7 +306,10 @@ export const usePdfCanvasDoc = (options) => {
|
|
|
292
306
|
// Knobs the flush just wrote may not have echoed back yet; carry them.
|
|
293
307
|
const nextData = {
|
|
294
308
|
...data,
|
|
295
|
-
|
|
309
|
+
pageTileScales: {
|
|
310
|
+
...data.pageTileScales,
|
|
311
|
+
[String(index)]: pdfCanvasKnobsOf(canvas),
|
|
312
|
+
},
|
|
296
313
|
document: { ...data.document, pages },
|
|
297
314
|
};
|
|
298
315
|
setStatus('saving');
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// /Rotate and the page matrix.
|
|
13
13
|
import { EncryptedPDFError, PDFDocument, degrees, } from 'pdf-lib';
|
|
14
14
|
import { backgroundLayersOf } from '../../annotation/canvas/backgroundLayers.js';
|
|
15
|
-
import { effectivePageRotation, pdfPageDisplaySize, } from '../../annotation/canvas/pdfCanvasPages.js';
|
|
15
|
+
import { effectivePageRotation, pdfCanvasPageKnobs, pdfPageDisplaySize, } from '../../annotation/canvas/pdfCanvasPages.js';
|
|
16
16
|
import { fitRectToScreen } from '../../annotation/canvas/viewport.js';
|
|
17
17
|
import { STAMP_TILE_SIZE } from '../../annotation/canvas/stampLayout.js';
|
|
18
18
|
import { clipRectOps, withMatrix } from './emit.js';
|
|
@@ -174,7 +174,7 @@ const renderJobs = async (doc, jobs, options, skipped) => {
|
|
|
174
174
|
const onPage = (b) => b !== null && rectsIntersect(b, rect);
|
|
175
175
|
const hiddenLayerIds = new Set(job.layerDefs.filter((l) => l.visible === false).map((l) => l.id));
|
|
176
176
|
const visible = (layerId) => !hiddenLayerIds.has(layerId);
|
|
177
|
-
const footprintFor = (placed, content) => tileFootprint(placed, { tileDocSize: job.tileDocSize }, options.calibration, fallbackDocEdge, designBoxFor(placed, content));
|
|
177
|
+
const footprintFor = (placed, content) => tileFootprint(placed, { tileDocSize: job.tileDocSize }, job.calibration ?? options.calibration, fallbackDocEdge, designBoxFor(placed, content));
|
|
178
178
|
const contentOf = (placed) => tileContent.get(placed.id) ?? { kind: 'empty' };
|
|
179
179
|
if (options.mode === 'flatten') {
|
|
180
180
|
// Everything into the page's content stream, under one matrix + clip.
|
|
@@ -363,18 +363,20 @@ export const renderPdfCanvasToPdf = async (input) => {
|
|
|
363
363
|
box,
|
|
364
364
|
rotation: effective,
|
|
365
365
|
rect: { x: 0, y: 0, width: display.width, height: display.height },
|
|
366
|
-
layers
|
|
366
|
+
// The page's image layers (expanded image tiles), in page doc space.
|
|
367
|
+
layers: state?.backgroundImages ?? [],
|
|
367
368
|
layerDefs: state?.layers ?? [],
|
|
368
369
|
strokes: state?.strokes ?? [],
|
|
369
370
|
shapes: state?.shapes ?? [],
|
|
370
371
|
placed: state?.placedMeasurements ?? [],
|
|
371
|
-
tileDocSize: pdfCanvas.tileDocSize,
|
|
372
|
+
tileDocSize: pdfCanvasPageKnobs(pdfCanvas, i).tileDocSize,
|
|
373
|
+
calibration: input.pageCalibrations?.[i],
|
|
372
374
|
});
|
|
373
375
|
});
|
|
374
376
|
const skipped = [];
|
|
375
377
|
const annotationCount = await renderJobs(doc, jobs, {
|
|
376
378
|
resolveTile: input.resolveTile,
|
|
377
|
-
layerImages: {},
|
|
379
|
+
layerImages: input.layerImages ?? {},
|
|
378
380
|
calibration: input.calibration,
|
|
379
381
|
primaryFont: input.primaryFont,
|
|
380
382
|
mode: input.mode ?? 'annotations',
|
|
@@ -106,6 +106,17 @@ export interface RenderPdfCanvasToPdfInput {
|
|
|
106
106
|
/** Page docs by page index; a page without one is exported un-annotated. */
|
|
107
107
|
pageStates: Partial<Record<number, PdfCanvasPageState>>;
|
|
108
108
|
resolveTile: (ref: PlacedMeasurementRef) => ResolvedTileContent | undefined;
|
|
109
|
+
/**
|
|
110
|
+
* Decoded bytes per image layer id, across every page's
|
|
111
|
+
* `backgroundImages`. Missing → that layer is skipped.
|
|
112
|
+
*/
|
|
113
|
+
layerImages?: Record<string, EmbeddedImage>;
|
|
114
|
+
/**
|
|
115
|
+
* Per-page calibration (pdfCanvasPageTileDocSizes). Tile scale is per page,
|
|
116
|
+
* so a page's entry wins over `calibration`, which then only covers pages
|
|
117
|
+
* without one (and requests from clients that predate the split).
|
|
118
|
+
*/
|
|
119
|
+
pageCalibrations?: Partial<Record<number, PdfExportCalibration>>;
|
|
109
120
|
calibration?: PdfExportCalibration;
|
|
110
121
|
primaryFont: Uint8Array;
|
|
111
122
|
mode?: 'annotations' | 'flatten';
|
package/dist/exports.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './types/firestore.js';
|
|
|
7
7
|
export * from './types/layout.js';
|
|
8
8
|
export * from './types/annotation.js';
|
|
9
9
|
export * from './types/pdfCanvas.js';
|
|
10
|
+
export { computeBaseFitZoom, resolveTileFactors, tileDocSizesFor, pdfCanvasPageTileDocSizes, type ResolvedTileFactors, type TileDocSizes, } from './annotation/canvas/tileCalibration.js';
|
|
10
11
|
export { getToleranceColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, type ToleranceThreshold, type ToleranceConfig, } from './utils/tolerance.js';
|
|
11
12
|
export { GeneralColors, SecondaryColors, FormColors, TileColors, FormulaColors, YellowColors, RedColors, GreenColors, tailwindColors, } from './theme/colors.js';
|
|
12
13
|
export { DEFAULT_GROUP_INDEX, isDefaultGroup, findDefaultGroup, isFormGroupCompleted, } from './utils/groups.js';
|
|
@@ -39,7 +40,7 @@ export { STAMP_TILE_SIZE, GROUP_HEADER_TILE_WIDTH, GROUP_HEADER_TILE_HEIGHT, GRO
|
|
|
39
40
|
export { GROUP_HEADER_STYLE, describeGroupHeader, groupHeaderSignature, type GroupHeaderBadge, type GroupHeaderDescriptor, } from './annotation/canvas/groupHeaderLayout.js';
|
|
40
41
|
export { createViewportApi, fitToScreen, fitRectToScreen, fitDocRectViewport, imageDocRect, panBy, zoomAt, DEFAULT_VIEWPORT, DEFAULT_ZOOM_LIMITS, type ViewportApi, type ViewportState, type ZoomLimits, } from './annotation/canvas/viewport.js';
|
|
41
42
|
export { DEFAULT_PDF_PAGE_GAP, DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM, makePdfDocumentId, createPdfDocument, pdfPageDocRects, pdfDocumentExtent, pdfFirstPageDocRect, computeZoomFloor, type PdfDocRect, } from './annotation/canvas/pdfDocument.js';
|
|
42
|
-
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, emptyPdfCanvasPageState, pdfCanvasPageDocument, pdfCanvasKnobsOf, pdfCanvasKnobsEqual, pageStateToCanvasState, canvasStateToPageState, rotatePointInPage, rotatePageState, rotatePdfCanvasPage, type PdfPageDisplaySize, type PdfRotationDelta, } from './annotation/canvas/pdfCanvasPages.js';
|
|
43
|
+
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, emptyPdfCanvasPageState, pdfCanvasPageDocument, pdfCanvasKnobsOf, pdfCanvasKnobsEqual, pageStateToCanvasState, canvasStateToPageState, rotatePointInPage, rotatePageState, rotatePdfCanvasPage, pdfCanvasPagePlacements, pdfCanvasPlacementsOf, pdfCanvasPageKnobs, type PdfPageDisplaySize, type PdfRotationDelta, } from './annotation/canvas/pdfCanvasPages.js';
|
|
43
44
|
export { LEGACY_BACKGROUND_LAYER_ID, BACKGROUND_PLACEMENT_GAP_RATIO, backgroundLayersOf, backgroundLayerIsLocked, isBackgroundLayerLocked, defaultBackgroundLayerLocked, backgroundLayerDocRect, backgroundLayersUnionRect, placeNewBackgroundLayer, } from './annotation/canvas/backgroundLayers.js';
|
|
44
45
|
export { fileTileImageSource, expandFileTileToBackground, collapseBackgroundToFileTile, type FileTileImageSource, } from './annotation/canvas/fileTileSwap.js';
|
|
45
46
|
export { createPenTool, type PenToolOptions, } from './annotation/canvas/tools/penTool.js';
|
package/dist/exports.js
CHANGED
|
@@ -11,6 +11,7 @@ export * from './types/firestore.js';
|
|
|
11
11
|
export * from './types/layout.js';
|
|
12
12
|
export * from './types/annotation.js';
|
|
13
13
|
export * from './types/pdfCanvas.js';
|
|
14
|
+
export { computeBaseFitZoom, resolveTileFactors, tileDocSizesFor, pdfCanvasPageTileDocSizes, } from './annotation/canvas/tileCalibration.js';
|
|
14
15
|
export { getToleranceColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, } from './utils/tolerance.js';
|
|
15
16
|
// Shared color palette (canonical source for both apps' brand colors).
|
|
16
17
|
export { GeneralColors, SecondaryColors, FormColors, TileColors, FormulaColors, YellowColors, RedColors, GreenColors, tailwindColors, } from './theme/colors.js';
|
|
@@ -45,7 +46,7 @@ export { STAMP_TILE_SIZE, GROUP_HEADER_TILE_WIDTH, GROUP_HEADER_TILE_HEIGHT, GRO
|
|
|
45
46
|
export { GROUP_HEADER_STYLE, describeGroupHeader, groupHeaderSignature, } from './annotation/canvas/groupHeaderLayout.js';
|
|
46
47
|
export { createViewportApi, fitToScreen, fitRectToScreen, fitDocRectViewport, imageDocRect, panBy, zoomAt, DEFAULT_VIEWPORT, DEFAULT_ZOOM_LIMITS, } from './annotation/canvas/viewport.js';
|
|
47
48
|
export { DEFAULT_PDF_PAGE_GAP, DEFAULT_MIN_ZOOM, DEFAULT_MAX_ZOOM, makePdfDocumentId, createPdfDocument, pdfPageDocRects, pdfDocumentExtent, pdfFirstPageDocRect, computeZoomFloor, } from './annotation/canvas/pdfDocument.js';
|
|
48
|
-
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, emptyPdfCanvasPageState, pdfCanvasPageDocument, pdfCanvasKnobsOf, pdfCanvasKnobsEqual, pageStateToCanvasState, canvasStateToPageState, rotatePointInPage, rotatePageState, rotatePdfCanvasPage, } from './annotation/canvas/pdfCanvasPages.js';
|
|
49
|
+
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, emptyPdfCanvasPageState, pdfCanvasPageDocument, pdfCanvasKnobsOf, pdfCanvasKnobsEqual, pageStateToCanvasState, canvasStateToPageState, rotatePointInPage, rotatePageState, rotatePdfCanvasPage, pdfCanvasPagePlacements, pdfCanvasPlacementsOf, pdfCanvasPageKnobs, } from './annotation/canvas/pdfCanvasPages.js';
|
|
49
50
|
export { LEGACY_BACKGROUND_LAYER_ID, BACKGROUND_PLACEMENT_GAP_RATIO, backgroundLayersOf, backgroundLayerIsLocked, isBackgroundLayerLocked, defaultBackgroundLayerLocked, backgroundLayerDocRect, backgroundLayersUnionRect, placeNewBackgroundLayer, } from './annotation/canvas/backgroundLayers.js';
|
|
50
51
|
export { fileTileImageSource, expandFileTileToBackground, collapseBackgroundToFileTile, } from './annotation/canvas/fileTileSwap.js';
|
|
51
52
|
export { createPenTool, } from './annotation/canvas/tools/penTool.js';
|
package/dist/server.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ export * from './types/firestore.js';
|
|
|
6
6
|
export * from './types/layout.js';
|
|
7
7
|
export * from './types/annotation.js';
|
|
8
8
|
export * from './types/pdfCanvas.js';
|
|
9
|
-
export {
|
|
9
|
+
export { computeBaseFitZoom, resolveTileFactors, tileDocSizesFor, pdfCanvasPageTileDocSizes, type ResolvedTileFactors, type TileDocSizes, } from './annotation/canvas/tileCalibration.js';
|
|
10
|
+
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, pageStateToCanvasState, rotatePageState, pdfCanvasPagePlacements, pdfCanvasPlacementsOf, pdfCanvasPageKnobs, type PdfPageDisplaySize, type PdfRotationDelta, } from './annotation/canvas/pdfCanvasPages.js';
|
|
10
11
|
export { getToleranceColor, getToleranceSecondaryColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, DEFAULT_TOLERANCE_SECONDARY_COLORS, type ToleranceThreshold, type ToleranceConfig, } from './utils/tolerance.js';
|
|
11
12
|
export { DEFAULT_GROUP_INDEX, isDefaultGroup, findDefaultGroup, isFormGroupCompleted, } from './utils/groups.js';
|
|
12
13
|
export { ROLE_RANK, EMPTY_GRANTS, normalizeRole, roleAtLeast, effectiveRole, canView, canEdit, canManage, canManageOrg, isGuest, groupGrants, resolveAccess, type MaybeRole, type GroupedGrants, type ResolvedAccess, } from './utils/permissions.js';
|
package/dist/server.js
CHANGED
|
@@ -11,7 +11,8 @@ export * from './types/firestore.js';
|
|
|
11
11
|
export * from './types/layout.js';
|
|
12
12
|
export * from './types/annotation.js';
|
|
13
13
|
export * from './types/pdfCanvas.js';
|
|
14
|
-
export {
|
|
14
|
+
export { computeBaseFitZoom, resolveTileFactors, tileDocSizesFor, pdfCanvasPageTileDocSizes, } from './annotation/canvas/tileCalibration.js';
|
|
15
|
+
export { normalizePdfRotation, effectivePageRotation, pdfPageDisplaySize, pdfCanvasPageDocId, pageStateToCanvasState, rotatePageState, pdfCanvasPagePlacements, pdfCanvasPlacementsOf, pdfCanvasPageKnobs, } from './annotation/canvas/pdfCanvasPages.js';
|
|
15
16
|
export { getToleranceColor, getToleranceSecondaryColor, calculateDeviationPercentage, isWithinTolerance, generateToleranceGradient, createDefaultToleranceThresholds, DEFAULT_TOLERANCE_COLORS, DEFAULT_TOLERANCE_SECONDARY_COLORS, } from './utils/tolerance.js';
|
|
16
17
|
export { DEFAULT_GROUP_INDEX, isDefaultGroup, findDefaultGroup, isFormGroupCompleted, } from './utils/groups.js';
|
|
17
18
|
export { ROLE_RANK, EMPTY_GRANTS, normalizeRole, roleAtLeast, effectiveRole, canView, canEdit, canManage, canManageOrg, isGuest, groupGrants, resolveAccess, } from './utils/permissions.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnnotationLayer, AnnotationShape, AnnotationStroke, PlacedMeasurementRef, PlaneCalibration } from './annotation.js';
|
|
1
|
+
import type { AnnotationBackgroundLayer, AnnotationLayer, AnnotationShape, AnnotationStroke, PlacedMeasurementRef, PlaneCalibration } from './annotation.js';
|
|
2
2
|
export type PdfPageRotation = 0 | 90 | 180 | 270;
|
|
3
3
|
export interface PdfCanvasPage {
|
|
4
4
|
width: number;
|
|
@@ -23,8 +23,18 @@ export interface PdfCanvasData {
|
|
|
23
23
|
headerTileScaleFactor?: number;
|
|
24
24
|
headerTileScaleFactorMobile?: number;
|
|
25
25
|
tileDocSize?: number;
|
|
26
|
+
pageTileScales?: Record<string, PdfCanvasTileScales>;
|
|
26
27
|
annotatedPages: number[];
|
|
28
|
+
placementsByPage?: Record<string, PdfCanvasPlacement[]>;
|
|
27
29
|
}
|
|
30
|
+
export interface PdfCanvasTileScales {
|
|
31
|
+
tileScaleFactor?: number;
|
|
32
|
+
tileScaleFactorMobile?: number;
|
|
33
|
+
headerTileScaleFactor?: number;
|
|
34
|
+
headerTileScaleFactorMobile?: number;
|
|
35
|
+
tileDocSize?: number;
|
|
36
|
+
}
|
|
37
|
+
export type PdfCanvasPlacement = Pick<PlacedMeasurementRef, 'measurementId' | 'measurementPath' | 'groupId' | 'columnId'>;
|
|
28
38
|
export interface PdfCanvasPageState {
|
|
29
39
|
schemaVersion: 1;
|
|
30
40
|
pageIndex: number;
|
|
@@ -33,6 +43,7 @@ export interface PdfCanvasPageState {
|
|
|
33
43
|
shapes: AnnotationShape[];
|
|
34
44
|
placedMeasurements: PlacedMeasurementRef[];
|
|
35
45
|
planes?: PlaneCalibration[];
|
|
46
|
+
backgroundImages?: AnnotationBackgroundLayer[];
|
|
36
47
|
updatedAt: number;
|
|
37
48
|
rev?: PdfCanvasRev;
|
|
38
49
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { type ReactNode } from 'react';
|
|
2
|
-
import type { AnnotationCanvasInnerProps } from './AnnotationCanvasInner.js';
|
|
3
|
-
export type { AnnotationCanvasHandle, GestureConfig, PanTrigger, } from './AnnotationCanvasInner.js';
|
|
4
|
-
export interface CanvasKitOpts {
|
|
5
|
-
locateFile?: (file: string) => string;
|
|
6
|
-
}
|
|
7
|
-
export type AnnotationCanvasProps = AnnotationCanvasInnerProps & {
|
|
8
|
-
fallback?: ReactNode;
|
|
9
|
-
canvasKitOpts?: CanvasKitOpts;
|
|
10
|
-
};
|
|
11
|
-
export declare const AnnotationCanvas: ({ fallback, canvasKitOpts, ...rest }: AnnotationCanvasProps) => import("react/jsx-runtime").JSX.Element;
|