@reekon-tools/boldr-utils 1.26.1 → 1.27.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/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/nutrient/instantJsonToPdfCanvas.d.ts +39 -0
- package/dist/export/nutrient/instantJsonToPdfCanvas.js +631 -0
- package/dist/export/pdf/index.d.ts +1 -1
- package/dist/export/pdf/index.js +1 -1
- package/dist/export/pdf/marks.js +46 -4
- package/dist/export/pdf/renderCanvasToPdf.d.ts +9 -0
- package/dist/export/pdf/renderCanvasToPdf.js +21 -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 +3 -1
- package/dist/server.js +3 -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
package/dist/export/pdf/marks.js
CHANGED
|
@@ -9,8 +9,8 @@ import { DEFAULT_TEXT_FONT_SIZE, TEXT_BASELINE_FACTOR, TEXT_LINE_HEIGHT_FACTOR,
|
|
|
9
9
|
import { normalizeRect, placementOf, } from '../../annotation/canvas/measurementGeometry.js';
|
|
10
10
|
import { MEASUREMENT_LINE_COLOR, MEASUREMENT_LINE_WIDTH, MEASUREMENT_RECT_WIDTH, } from '../../annotation/canvas/measurementLineStyle.js';
|
|
11
11
|
import { parseHexColor } from './color.js';
|
|
12
|
-
import { circlePathOps, fillStateOps, flatPolylinePathOps, polylinePathOps, rectPathOps, strokeStateOps, } from './emit.js';
|
|
13
|
-
import { boundsToRect } from './pageMapping.js';
|
|
12
|
+
import { circlePathOps, fillStateOps, flatPolylinePathOps, polylinePathOps, rectPathOps, strokeStateOps, withMatrix, } from './emit.js';
|
|
13
|
+
import { boundsToRect, } from './pageMapping.js';
|
|
14
14
|
// Readable glyph colour over a highlight band — mirror of
|
|
15
15
|
// ShapeElement.highlightTextColor (which lives behind a Skia import).
|
|
16
16
|
const highlightTextColor = (hex) => {
|
|
@@ -118,10 +118,51 @@ export const strokeOps = (s, ctx) => {
|
|
|
118
118
|
/* ------------------------------------------------------------------ *
|
|
119
119
|
* Shapes
|
|
120
120
|
* ------------------------------------------------------------------ */
|
|
121
|
+
/**
|
|
122
|
+
* Doc-space rotation of a text shape: `geometry.rotation` degrees CLOCKWISE
|
|
123
|
+
* (y-down) about its origin, `points[0]`. Only set by converted Nutrient text
|
|
124
|
+
* so far — the Skia canvas still draws every text shape upright.
|
|
125
|
+
*/
|
|
126
|
+
const textRotationMatrix = (shape) => {
|
|
127
|
+
const deg = shape.geometry.rotation;
|
|
128
|
+
const origin = shape.geometry.points[0];
|
|
129
|
+
if (!deg || !origin || !Number.isFinite(deg) || deg % 360 === 0)
|
|
130
|
+
return null;
|
|
131
|
+
const t = (deg * Math.PI) / 180;
|
|
132
|
+
const c = Math.cos(t);
|
|
133
|
+
const s = Math.sin(t);
|
|
134
|
+
return [
|
|
135
|
+
c,
|
|
136
|
+
s,
|
|
137
|
+
-s,
|
|
138
|
+
c,
|
|
139
|
+
origin.x - c * origin.x + s * origin.y,
|
|
140
|
+
origin.y - s * origin.x - c * origin.y,
|
|
141
|
+
];
|
|
142
|
+
};
|
|
121
143
|
export const shapeBounds = (shape) => {
|
|
122
144
|
if (shape.kind === 'text') {
|
|
123
145
|
const b = textShapeBounds(shape);
|
|
124
|
-
|
|
146
|
+
if (!b)
|
|
147
|
+
return null;
|
|
148
|
+
const m = textRotationMatrix(shape);
|
|
149
|
+
if (!m)
|
|
150
|
+
return boundsToRect(b, 4);
|
|
151
|
+
const corners = [
|
|
152
|
+
[b.minX, b.minY],
|
|
153
|
+
[b.maxX, b.minY],
|
|
154
|
+
[b.minX, b.maxY],
|
|
155
|
+
[b.maxX, b.maxY],
|
|
156
|
+
].map(([x, y]) => ({
|
|
157
|
+
x: m[0] * x + m[2] * y + m[4],
|
|
158
|
+
y: m[1] * x + m[3] * y + m[5],
|
|
159
|
+
}));
|
|
160
|
+
return boundsToRect({
|
|
161
|
+
minX: Math.min(...corners.map((p) => p.x)),
|
|
162
|
+
minY: Math.min(...corners.map((p) => p.y)),
|
|
163
|
+
maxX: Math.max(...corners.map((p) => p.x)),
|
|
164
|
+
maxY: Math.max(...corners.map((p) => p.y)),
|
|
165
|
+
}, 4);
|
|
125
166
|
}
|
|
126
167
|
const b = visualShapeBounds(shape);
|
|
127
168
|
if (!b)
|
|
@@ -169,7 +210,8 @@ const textShapeOps = (shape, ctx) => {
|
|
|
169
210
|
reason: 'Some characters have no glyph in the export fonts and were dropped',
|
|
170
211
|
});
|
|
171
212
|
}
|
|
172
|
-
|
|
213
|
+
const rotation = textRotationMatrix(shape);
|
|
214
|
+
return rotation ? withMatrix(rotation, ops) : ops;
|
|
173
215
|
};
|
|
174
216
|
export const shapeOps = (shape, ctx) => {
|
|
175
217
|
const { kind, geometry, style } = shape;
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import type { PdfCanvasPage } from '../../types/pdfCanvas.js';
|
|
1
2
|
import { type RenderCanvasToPdfInput, type RenderCanvasToPdfResult, type RenderPdfCanvasToPdfInput } from './types.js';
|
|
2
3
|
export declare const renderCanvasToPdf: (input: RenderCanvasToPdfInput) => Promise<RenderCanvasToPdfResult>;
|
|
4
|
+
/**
|
|
5
|
+
* The `PdfCanvasDocument.pages` record for a PDF: each page's extents after
|
|
6
|
+
* its own /Rotate, measured exactly as renderPdfCanvasToPdf validates them,
|
|
7
|
+
* at user rotation 0. For building a PdfCanvas record server-side (e.g. when
|
|
8
|
+
* converting a legacy Nutrient file) without rasterizing. The PDF must be
|
|
9
|
+
* unencrypted (stripPdfEncryption).
|
|
10
|
+
*/
|
|
11
|
+
export declare const describePdfPages: (sourcePdf: Uint8Array) => Promise<PdfCanvasPage[]>;
|
|
3
12
|
/**
|
|
4
13
|
* Export a PdfCanvas file. Each page's state is drawn in that page's own doc
|
|
5
14
|
* space (the DISPLAYED page: rotated extents, origin top-left). A user
|
|
@@ -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.
|
|
@@ -334,6 +334,20 @@ export const renderCanvasToPdf = async (input) => {
|
|
|
334
334
|
const pdf = await doc.save({ useObjectStreams: false });
|
|
335
335
|
return { pdf, pageCount: pages.length, annotationCount, skipped };
|
|
336
336
|
};
|
|
337
|
+
/**
|
|
338
|
+
* The `PdfCanvasDocument.pages` record for a PDF: each page's extents after
|
|
339
|
+
* its own /Rotate, measured exactly as renderPdfCanvasToPdf validates them,
|
|
340
|
+
* at user rotation 0. For building a PdfCanvas record server-side (e.g. when
|
|
341
|
+
* converting a legacy Nutrient file) without rasterizing. The PDF must be
|
|
342
|
+
* unencrypted (stripPdfEncryption).
|
|
343
|
+
*/
|
|
344
|
+
export const describePdfPages = async (sourcePdf) => {
|
|
345
|
+
const doc = await loadSource(sourcePdf);
|
|
346
|
+
return doc.getPages().map((page) => {
|
|
347
|
+
const size = rotatedBoxSize(pageBox(page), normalizeRotation(page.getRotation().angle));
|
|
348
|
+
return { width: size.width, height: size.height, rotation: 0 };
|
|
349
|
+
});
|
|
350
|
+
};
|
|
337
351
|
/**
|
|
338
352
|
* Export a PdfCanvas file. Each page's state is drawn in that page's own doc
|
|
339
353
|
* space (the DISPLAYED page: rotated extents, origin top-left). A user
|
|
@@ -363,18 +377,20 @@ export const renderPdfCanvasToPdf = async (input) => {
|
|
|
363
377
|
box,
|
|
364
378
|
rotation: effective,
|
|
365
379
|
rect: { x: 0, y: 0, width: display.width, height: display.height },
|
|
366
|
-
layers
|
|
380
|
+
// The page's image layers (expanded image tiles), in page doc space.
|
|
381
|
+
layers: state?.backgroundImages ?? [],
|
|
367
382
|
layerDefs: state?.layers ?? [],
|
|
368
383
|
strokes: state?.strokes ?? [],
|
|
369
384
|
shapes: state?.shapes ?? [],
|
|
370
385
|
placed: state?.placedMeasurements ?? [],
|
|
371
|
-
tileDocSize: pdfCanvas.tileDocSize,
|
|
386
|
+
tileDocSize: pdfCanvasPageKnobs(pdfCanvas, i).tileDocSize,
|
|
387
|
+
calibration: input.pageCalibrations?.[i],
|
|
372
388
|
});
|
|
373
389
|
});
|
|
374
390
|
const skipped = [];
|
|
375
391
|
const annotationCount = await renderJobs(doc, jobs, {
|
|
376
392
|
resolveTile: input.resolveTile,
|
|
377
|
-
layerImages: {},
|
|
393
|
+
layerImages: input.layerImages ?? {},
|
|
378
394
|
calibration: input.calibration,
|
|
379
395
|
primaryFont: input.primaryFont,
|
|
380
396
|
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';
|
|
@@ -18,5 +19,6 @@ export { numberToLetterIndex, formGroupInputLabel, listGroupMeasurementLabel, }
|
|
|
18
19
|
export { toSelectedValues, formatSelectedValues, toStoredValue, } from './utils/selectValues.js';
|
|
19
20
|
export * from './calculator/index.js';
|
|
20
21
|
export * from './export/pdf/index.js';
|
|
22
|
+
export { instantJsonToPdfCanvas, NUTRIENT_TILE_DOC_SIZE, type InstantJsonConversion, type InstantJsonToPdfCanvasInput, type NutrientSkippedAnnotation, } from './export/nutrient/instantJsonToPdfCanvas.js';
|
|
21
23
|
export { applyGroupFormulaUm, groupFormulaExpression, unitNumberToMicrometers, type GroupFormulaFrame, } from './formulas/groupFormula.js';
|
|
22
24
|
export { MEASUREMENT_LINE_COLOR, MEASUREMENT_LINE_WIDTH, MEASUREMENT_RECT_WIDTH, } from './annotation/canvas/measurementLineStyle.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';
|
|
@@ -25,6 +26,7 @@ export * from './calculator/index.js';
|
|
|
25
26
|
// Canvas → annotated PDF export (Cloud Function renderer). Pure pdf-lib; no
|
|
26
27
|
// React or Skia anywhere in its import graph.
|
|
27
28
|
export * from './export/pdf/index.js';
|
|
29
|
+
export { instantJsonToPdfCanvas, NUTRIENT_TILE_DOC_SIZE, } from './export/nutrient/instantJsonToPdfCanvas.js';
|
|
28
30
|
// groupFormula's own micrometersToUnitNumber (integer constants, NaN on
|
|
29
31
|
// unknown units) stays module-local: the canonical export of that name is the
|
|
30
32
|
// mathjs-exact one from evaluateFormula.js above, and no consumer imported
|
|
@@ -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;
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { WithSkiaWeb } from '@shopify/react-native-skia/lib/module/web/index.js';
|
|
3
|
-
// Web-only entry point: lazy-loads CanvasKit wasm via WithSkiaWeb. Imperative
|
|
4
|
-
// API (undo/redo/zoom) is exposed through the `imperativeRef` prop rather
|
|
5
|
-
// than React refs, since WithSkiaWeb can't forward refs through its lazy
|
|
6
|
-
// component boundary. The native build sits in `AnnotationCanvas.native.tsx`
|
|
7
|
-
// and skips WithSkiaWeb entirely (no wasm to load).
|
|
8
|
-
export const AnnotationCanvas = ({ fallback, canvasKitOpts, ...rest }) => (_jsx(WithSkiaWeb, { getComponent: () => import('./AnnotationCanvasInner.js').then((m) => ({
|
|
9
|
-
default: m.AnnotationCanvasInner,
|
|
10
|
-
})), fallback: fallback ?? null, componentProps: rest, opts: canvasKitOpts }));
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { AnnotationCanvasInnerProps } from './AnnotationCanvasInner.native.js';
|
|
2
|
-
export type { AnnotationCanvasHandle, } from './useAnnotationCanvasState.js';
|
|
3
|
-
export type { GestureConfig, PanTrigger, } from './AnnotationCanvasInner.js';
|
|
4
|
-
export type AnnotationCanvasProps = AnnotationCanvasInnerProps & {
|
|
5
|
-
fallback?: unknown;
|
|
6
|
-
canvasKitOpts?: unknown;
|
|
7
|
-
};
|
|
8
|
-
export declare const AnnotationCanvas: (props: AnnotationCanvasProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { AnnotationCanvasInner } from './AnnotationCanvasInner.native.js';
|
|
3
|
-
export const AnnotationCanvas = (props) => {
|
|
4
|
-
const { fallback: _f, canvasKitOpts: _o, ...rest } = props;
|
|
5
|
-
return _jsx(AnnotationCanvasInner, { ...rest });
|
|
6
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { type CSSProperties, type MutableRefObject } from 'react';
|
|
2
|
-
import type { DecimalTolerance, FractionalTolerance, Measurement, Units } from '../types/firestore.js';
|
|
3
|
-
import type { AnnotationCanvasState, AnnotationDocumentPatch, Selection } from '../types/annotation.js';
|
|
4
|
-
import type { MeasurementRef } from './measurementPicker.js';
|
|
5
|
-
import type { Tool } from './Tool.js';
|
|
6
|
-
import { type AnnotationCanvasHandle } from './useAnnotationCanvasState.js';
|
|
7
|
-
import { type ViewportState } from './viewport.js';
|
|
8
|
-
import type { RenderMeasurementStamp } from './measurementStampOverlay.js';
|
|
9
|
-
export type { AnnotationCanvasHandle };
|
|
10
|
-
export interface AnnotationCanvasInnerProps {
|
|
11
|
-
canvas: AnnotationCanvasState;
|
|
12
|
-
onCommit(patch: AnnotationDocumentPatch): void;
|
|
13
|
-
tools: Tool[];
|
|
14
|
-
activeToolId: string;
|
|
15
|
-
selection: Selection | null;
|
|
16
|
-
onSelectionChange(selection: Selection | null): void;
|
|
17
|
-
measurements?: Measurement[];
|
|
18
|
-
fallbackUnit?: Units;
|
|
19
|
-
fractionalTolerance?: FractionalTolerance;
|
|
20
|
-
decimalTolerance?: DecimalTolerance;
|
|
21
|
-
resolveImageUrl?: (storagePath: string) => Promise<string>;
|
|
22
|
-
pickMeasurement?: () => Promise<MeasurementRef | null>;
|
|
23
|
-
renderMeasurementStamp?: RenderMeasurementStamp;
|
|
24
|
-
stampFontSource?: unknown;
|
|
25
|
-
stampValueFontSize?: number;
|
|
26
|
-
stampLabelFontSize?: number;
|
|
27
|
-
gestures?: GestureConfig;
|
|
28
|
-
width: number;
|
|
29
|
-
height: number;
|
|
30
|
-
initialViewport?: ViewportState;
|
|
31
|
-
style?: CSSProperties;
|
|
32
|
-
imperativeRef?: MutableRefObject<AnnotationCanvasHandle | null>;
|
|
33
|
-
}
|
|
34
|
-
export type PanTrigger = 'middleMouse' | 'rightMouse' | 'space';
|
|
35
|
-
export interface GestureConfig {
|
|
36
|
-
wheel?: 'zoom' | 'pan' | 'auto';
|
|
37
|
-
panTriggers?: PanTrigger[];
|
|
38
|
-
}
|
|
39
|
-
export declare const AnnotationCanvasInner: (props: AnnotationCanvasInnerProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useFont } from '@shopify/react-native-skia';
|
|
3
|
-
import { useCallback, useEffect, useRef, } from 'react';
|
|
4
|
-
import { AnnotationCanvasSkia } from './AnnotationCanvasSkia.js';
|
|
5
|
-
import { useAnnotationCanvasState, } from './useAnnotationCanvasState.js';
|
|
6
|
-
import { STAMP_TILE_SIZE } from './stampLayout.js';
|
|
7
|
-
const DEFAULT_PAN_TRIGGERS = ['middleMouse', 'space'];
|
|
8
|
-
export const AnnotationCanvasInner = (props) => {
|
|
9
|
-
const { fallbackUnit, fractionalTolerance, decimalTolerance, resolveImageUrl, stampFontSource, stampValueFontSize = 14, stampLabelFontSize = 11, gestures, width, height, style, activeToolId, tools, } = props;
|
|
10
|
-
const wheelMode = gestures?.wheel ?? 'auto';
|
|
11
|
-
const panTriggers = gestures?.panTriggers ?? DEFAULT_PAN_TRIGGERS;
|
|
12
|
-
const allowSpacePan = panTriggers.includes('space');
|
|
13
|
-
const allowMiddlePan = panTriggers.includes('middleMouse');
|
|
14
|
-
const allowRightPan = panTriggers.includes('rightMouse');
|
|
15
|
-
const valueFont = useFont(stampFontSource, stampValueFontSize);
|
|
16
|
-
const labelFont = useFont(stampFontSource, stampLabelFontSize);
|
|
17
|
-
const state = useAnnotationCanvasState(props);
|
|
18
|
-
const containerRef = useRef(null);
|
|
19
|
-
const panGestureRef = useRef(null);
|
|
20
|
-
const spaceDownRef = useRef(false);
|
|
21
|
-
const activeTool = tools.find((t) => t.id === activeToolId) ?? null;
|
|
22
|
-
const toCanvasPointer = useCallback((event) => {
|
|
23
|
-
const rect = containerRef.current?.getBoundingClientRect();
|
|
24
|
-
const screen = {
|
|
25
|
-
x: event.clientX - (rect?.left ?? 0),
|
|
26
|
-
y: event.clientY - (rect?.top ?? 0),
|
|
27
|
-
};
|
|
28
|
-
return {
|
|
29
|
-
pointerId: event.pointerId,
|
|
30
|
-
screen,
|
|
31
|
-
world: state.ctx.viewport.screenToWorld(screen),
|
|
32
|
-
pressure: event.pressure || undefined,
|
|
33
|
-
shiftKey: event.shiftKey,
|
|
34
|
-
altKey: event.altKey,
|
|
35
|
-
metaKey: event.metaKey,
|
|
36
|
-
ctrlKey: event.ctrlKey,
|
|
37
|
-
};
|
|
38
|
-
}, [state.ctx.viewport]);
|
|
39
|
-
const isPanTriggerDown = useCallback((event) => {
|
|
40
|
-
if (allowMiddlePan && event.button === 1)
|
|
41
|
-
return true;
|
|
42
|
-
if (allowRightPan && event.button === 2)
|
|
43
|
-
return true;
|
|
44
|
-
if (allowSpacePan && event.button === 0 && spaceDownRef.current)
|
|
45
|
-
return true;
|
|
46
|
-
return false;
|
|
47
|
-
}, [allowMiddlePan, allowRightPan, allowSpacePan]);
|
|
48
|
-
const handlePointerDown = useCallback((event) => {
|
|
49
|
-
const rect = containerRef.current?.getBoundingClientRect();
|
|
50
|
-
const screen = {
|
|
51
|
-
x: event.clientX - (rect?.left ?? 0),
|
|
52
|
-
y: event.clientY - (rect?.top ?? 0),
|
|
53
|
-
};
|
|
54
|
-
if (isPanTriggerDown(event)) {
|
|
55
|
-
panGestureRef.current = { pointerId: event.pointerId, lastScreen: screen };
|
|
56
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
57
|
-
event.preventDefault();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
event.currentTarget.setPointerCapture(event.pointerId);
|
|
61
|
-
state.dispatchPointerDown(toCanvasPointer(event));
|
|
62
|
-
}, [state, toCanvasPointer, isPanTriggerDown]);
|
|
63
|
-
const handlePointerMove = useCallback((event) => {
|
|
64
|
-
const pan = panGestureRef.current;
|
|
65
|
-
if (pan && event.pointerId === pan.pointerId) {
|
|
66
|
-
const rect = containerRef.current?.getBoundingClientRect();
|
|
67
|
-
const screen = {
|
|
68
|
-
x: event.clientX - (rect?.left ?? 0),
|
|
69
|
-
y: event.clientY - (rect?.top ?? 0),
|
|
70
|
-
};
|
|
71
|
-
state.pan({
|
|
72
|
-
x: screen.x - pan.lastScreen.x,
|
|
73
|
-
y: screen.y - pan.lastScreen.y,
|
|
74
|
-
});
|
|
75
|
-
panGestureRef.current = { pointerId: pan.pointerId, lastScreen: screen };
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
state.dispatchPointerMove(toCanvasPointer(event));
|
|
79
|
-
}, [state, toCanvasPointer]);
|
|
80
|
-
const handlePointerUp = useCallback((event) => {
|
|
81
|
-
const pan = panGestureRef.current;
|
|
82
|
-
if (pan && event.pointerId === pan.pointerId) {
|
|
83
|
-
panGestureRef.current = null;
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
state.dispatchPointerUp(toCanvasPointer(event));
|
|
87
|
-
}, [state, toCanvasPointer]);
|
|
88
|
-
const handlePointerCancel = useCallback(() => {
|
|
89
|
-
panGestureRef.current = null;
|
|
90
|
-
state.dispatchPointerCancel();
|
|
91
|
-
}, [state]);
|
|
92
|
-
const handleWheel = useCallback((event) => {
|
|
93
|
-
const rect = containerRef.current?.getBoundingClientRect();
|
|
94
|
-
const focal = {
|
|
95
|
-
x: event.clientX - (rect?.left ?? 0),
|
|
96
|
-
y: event.clientY - (rect?.top ?? 0),
|
|
97
|
-
};
|
|
98
|
-
if (event.ctrlKey || event.metaKey) {
|
|
99
|
-
const factor = Math.exp(-event.deltaY / 200);
|
|
100
|
-
state.zoom(focal, state.ctx.viewport.state.zoom * factor);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
if (wheelMode === 'zoom') {
|
|
104
|
-
const factor = Math.exp(-event.deltaY / 300);
|
|
105
|
-
state.zoom(focal, state.ctx.viewport.state.zoom * factor);
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
if (event.shiftKey) {
|
|
109
|
-
state.pan({ x: event.deltaY, y: event.deltaX });
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
state.pan({ x: event.deltaX, y: event.deltaY });
|
|
113
|
-
}, [state, wheelMode]);
|
|
114
|
-
const handleContextMenu = useCallback((event) => {
|
|
115
|
-
if (allowRightPan)
|
|
116
|
-
event.preventDefault();
|
|
117
|
-
}, [allowRightPan]);
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
const el = containerRef.current;
|
|
120
|
-
if (!el)
|
|
121
|
-
return;
|
|
122
|
-
const stop = (e) => {
|
|
123
|
-
if (e.target === el || el.contains(e.target)) {
|
|
124
|
-
e.preventDefault();
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
el.addEventListener('wheel', stop, { passive: false });
|
|
128
|
-
return () => el.removeEventListener('wheel', stop);
|
|
129
|
-
}, []);
|
|
130
|
-
useEffect(() => {
|
|
131
|
-
if (!allowSpacePan)
|
|
132
|
-
return;
|
|
133
|
-
const onKeyDown = (e) => {
|
|
134
|
-
if (e.code === 'Space' && !e.repeat) {
|
|
135
|
-
spaceDownRef.current = true;
|
|
136
|
-
if (containerRef.current)
|
|
137
|
-
containerRef.current.style.cursor = 'grab';
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
const onKeyUp = (e) => {
|
|
141
|
-
if (e.code === 'Space') {
|
|
142
|
-
spaceDownRef.current = false;
|
|
143
|
-
if (containerRef.current)
|
|
144
|
-
containerRef.current.style.cursor = '';
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
window.addEventListener('keydown', onKeyDown);
|
|
148
|
-
window.addEventListener('keyup', onKeyUp);
|
|
149
|
-
return () => {
|
|
150
|
-
window.removeEventListener('keydown', onKeyDown);
|
|
151
|
-
window.removeEventListener('keyup', onKeyUp);
|
|
152
|
-
};
|
|
153
|
-
}, [allowSpacePan]);
|
|
154
|
-
const containerStyle = {
|
|
155
|
-
position: 'relative',
|
|
156
|
-
width,
|
|
157
|
-
height,
|
|
158
|
-
overflow: 'hidden',
|
|
159
|
-
touchAction: 'none',
|
|
160
|
-
userSelect: 'none',
|
|
161
|
-
cursor: activeTool?.cursor ?? 'default',
|
|
162
|
-
...style,
|
|
163
|
-
};
|
|
164
|
-
const customPreview = activeTool?.renderPreview?.(state.customPreviewState, state.ctx);
|
|
165
|
-
const { renderMeasurementStamp, selection } = props;
|
|
166
|
-
return (_jsxs("div", { ref: containerRef, style: containerStyle, onPointerDown: handlePointerDown, onPointerMove: handlePointerMove, onPointerUp: handlePointerUp, onPointerCancel: handlePointerCancel, onWheel: handleWheel, onContextMenu: handleContextMenu, children: [AnnotationCanvasSkia({
|
|
167
|
-
width,
|
|
168
|
-
height,
|
|
169
|
-
effectiveCanvas: state.effectiveCanvas,
|
|
170
|
-
worldTransform: state.worldTransform,
|
|
171
|
-
measurementsById: state.measurementsById,
|
|
172
|
-
fallbackUnit,
|
|
173
|
-
fractionalTolerance,
|
|
174
|
-
decimalTolerance,
|
|
175
|
-
resolveImageUrl,
|
|
176
|
-
valueFont,
|
|
177
|
-
labelFont,
|
|
178
|
-
hideMeasurementStamps: !!renderMeasurementStamp,
|
|
179
|
-
penDrawingStroke: state.penDrawingStroke,
|
|
180
|
-
customPreview,
|
|
181
|
-
}), renderMeasurementStamp && (_jsx("div", { style: {
|
|
182
|
-
position: 'absolute',
|
|
183
|
-
inset: 0,
|
|
184
|
-
pointerEvents: 'none',
|
|
185
|
-
}, children: state.effectiveCanvas.placedMeasurements.map((placed) => {
|
|
186
|
-
const size = STAMP_TILE_SIZE * (placed.scale ?? 1);
|
|
187
|
-
const cx = (placed.anchor.x - state.viewport.pan.x) * state.viewport.zoom;
|
|
188
|
-
const cy = (placed.anchor.y - state.viewport.pan.y) * state.viewport.zoom;
|
|
189
|
-
const isSelected = selection?.ids.includes(placed.id) ?? false;
|
|
190
|
-
return (_jsxs("div", { style: {
|
|
191
|
-
position: 'absolute',
|
|
192
|
-
left: 0,
|
|
193
|
-
top: 0,
|
|
194
|
-
width: size,
|
|
195
|
-
height: size,
|
|
196
|
-
transform: `translate(${cx - size / 2}px, ${cy - size / 2}px)`,
|
|
197
|
-
}, children: [renderMeasurementStamp({
|
|
198
|
-
placed,
|
|
199
|
-
measurement: state.measurementsById.get(placed.measurementId) ?? null,
|
|
200
|
-
selected: isSelected,
|
|
201
|
-
size,
|
|
202
|
-
zoom: state.viewport.zoom,
|
|
203
|
-
}), isSelected && (_jsx("div", { role: "button", "aria-label": "Remove measurement", onPointerDown: (e) => {
|
|
204
|
-
e.stopPropagation();
|
|
205
|
-
state.ctx.commit({
|
|
206
|
-
ops: [{ op: 'removeMeasurement', id: placed.id }],
|
|
207
|
-
});
|
|
208
|
-
state.ctx.setSelection(null);
|
|
209
|
-
}, style: {
|
|
210
|
-
position: 'absolute',
|
|
211
|
-
top: -10,
|
|
212
|
-
right: -10,
|
|
213
|
-
width: 40,
|
|
214
|
-
height: 40,
|
|
215
|
-
cursor: 'pointer',
|
|
216
|
-
pointerEvents: 'auto',
|
|
217
|
-
} }))] }, placed.id));
|
|
218
|
-
}) }))] }));
|
|
219
|
-
};
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { type MutableRefObject } from 'react';
|
|
2
|
-
import { type ViewStyle } from 'react-native';
|
|
3
|
-
import type { RenderMeasurementStamp } from './measurementStampOverlay.js';
|
|
4
|
-
import type { DecimalTolerance, FractionalTolerance, Measurement, Units } from '../types/firestore.js';
|
|
5
|
-
import type { AnnotationCanvasState, AnnotationDocumentPatch, Selection } from '../types/annotation.js';
|
|
6
|
-
import type { MeasurementRef } from './measurementPicker.js';
|
|
7
|
-
import type { Tool } from './Tool.js';
|
|
8
|
-
import { type AnnotationCanvasHandle } from './useAnnotationCanvasState.js';
|
|
9
|
-
import type { ViewportState } from './viewport.js';
|
|
10
|
-
export type { AnnotationCanvasHandle };
|
|
11
|
-
export interface AnnotationCanvasInnerProps {
|
|
12
|
-
canvas: AnnotationCanvasState;
|
|
13
|
-
onCommit(patch: AnnotationDocumentPatch): void;
|
|
14
|
-
tools: Tool[];
|
|
15
|
-
activeToolId: string;
|
|
16
|
-
selection: Selection | null;
|
|
17
|
-
onSelectionChange(selection: Selection | null): void;
|
|
18
|
-
measurements?: Measurement[];
|
|
19
|
-
fallbackUnit?: Units;
|
|
20
|
-
fractionalTolerance?: FractionalTolerance;
|
|
21
|
-
decimalTolerance?: DecimalTolerance;
|
|
22
|
-
resolveImageUrl?: (storagePath: string) => Promise<string>;
|
|
23
|
-
pickMeasurement?: () => Promise<MeasurementRef | null>;
|
|
24
|
-
renderMeasurementStamp?: RenderMeasurementStamp;
|
|
25
|
-
stampFontSource?: unknown;
|
|
26
|
-
stampValueFontSize?: number;
|
|
27
|
-
stampLabelFontSize?: number;
|
|
28
|
-
gestures?: unknown;
|
|
29
|
-
width: number;
|
|
30
|
-
height: number;
|
|
31
|
-
initialViewport?: ViewportState;
|
|
32
|
-
style?: ViewStyle;
|
|
33
|
-
imperativeRef?: MutableRefObject<AnnotationCanvasHandle | null>;
|
|
34
|
-
}
|
|
35
|
-
export declare const AnnotationCanvasInner: (props: AnnotationCanvasInnerProps) => import("react/jsx-runtime").JSX.Element;
|