electron-snapora 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.es.md +79 -0
- package/README.ja.md +79 -0
- package/README.ko.md +79 -0
- package/README.md +392 -0
- package/README.zh-CN.md +79 -0
- package/dist/core/index.cjs +184 -0
- package/dist/core/index.cjs.map +1 -0
- package/dist/core/index.d.cts +97 -0
- package/dist/core/index.d.ts +97 -0
- package/dist/core/index.mjs +150 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/main/index.cjs +1637 -0
- package/dist/main/index.cjs.map +1 -0
- package/dist/main/index.d.cts +283 -0
- package/dist/main/index.d.ts +283 -0
- package/dist/main/index.mjs +1599 -0
- package/dist/main/index.mjs.map +1 -0
- package/dist/messages-DYY0MpGh.d.ts +76 -0
- package/dist/messages-ifub9bae.d.cts +76 -0
- package/dist/overlay/assets/index-7dVRGn83.css +1 -0
- package/dist/overlay/assets/index-CJf5iC1U.js +2 -0
- package/dist/overlay/assets/index-CJf5iC1U.js.map +1 -0
- package/dist/overlay/index.html +316 -0
- package/dist/overlay/preload.cjs +97 -0
- package/dist/overlay/preload.cjs.map +1 -0
- package/dist/overlay/preload.d.cts +16 -0
- package/dist/overlay/preload.d.ts +16 -0
- package/dist/overlay/preload.mjs +80 -0
- package/dist/overlay/preload.mjs.map +1 -0
- package/dist/preload/auto.cjs +24 -0
- package/dist/preload/auto.cjs.map +1 -0
- package/dist/preload/auto.d.cts +2 -0
- package/dist/preload/auto.d.ts +2 -0
- package/dist/preload/auto.mjs +22 -0
- package/dist/preload/auto.mjs.map +1 -0
- package/dist/preload/index.cjs +46 -0
- package/dist/preload/index.cjs.map +1 -0
- package/dist/preload/index.d.cts +18 -0
- package/dist/preload/index.d.ts +18 -0
- package/dist/preload/index.mjs +19 -0
- package/dist/preload/index.mjs.map +1 -0
- package/dist/types/index.cjs +19 -0
- package/dist/types/index.cjs.map +1 -0
- package/dist/types/index.d.cts +92 -0
- package/dist/types/index.d.ts +92 -0
- package/dist/types/index.mjs +1 -0
- package/dist/types/index.mjs.map +1 -0
- package/package.json +158 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-CJf5iC1U.js","sources":["../../../src/core/geometry/rect.ts","../../../src/overlay/annotation-elements.ts","../../../src/overlay/annotation-renderer.ts","../../../src/core/history/command-stack.ts","../../../src/core/history/document-commands.ts","../../../src/overlay/annotation-store.ts","../../../src/overlay/export-selection.ts","../../../src/overlay/presentation.ts","../../../src/overlay/selection-geometry.ts","../../../src/overlay/selection-store.ts","../../../src/overlay/main.ts"],"sourcesContent":["export interface Point {\n x: number;\n y: number;\n}\n\nexport interface Size {\n width: number;\n height: number;\n}\n\nexport type Rect = Point & Size;\n\nexport function normalizeRect(start: Point, end: Point): Rect {\n return {\n x: Math.min(start.x, end.x),\n y: Math.min(start.y, end.y),\n width: Math.abs(end.x - start.x),\n height: Math.abs(end.y - start.y),\n };\n}\n\nexport function clampRect(rect: Rect, bounds: Rect): Rect {\n const left = Math.max(bounds.x, rect.x);\n const top = Math.max(bounds.y, rect.y);\n const right = Math.min(bounds.x + bounds.width, rect.x + rect.width);\n const bottom = Math.min(bounds.y + bounds.height, rect.y + rect.height);\n\n return {\n x: left,\n y: top,\n width: Math.max(0, right - left),\n height: Math.max(0, bottom - top),\n };\n}\n\nexport function isRectValid(rect: Rect, minimumSize = 1): boolean {\n return rect.width >= minimumSize && rect.height >= minimumSize;\n}\n\nexport function viewportPointToImagePoint(\n point: Point,\n viewportSize: Size,\n imageSize: Size\n): Point {\n if (viewportSize.width <= 0 || viewportSize.height <= 0) {\n throw new RangeError('Viewport dimensions must be greater than zero.');\n }\n\n return {\n x: point.x * (imageSize.width / viewportSize.width),\n y: point.y * (imageSize.height / viewportSize.height),\n };\n}\n","import { normalizeRect, type Point, type Rect } from '../core/geometry/rect.js';\nimport type {\n AnnotationElement,\n ArrowElement,\n BrushElement,\n EllipseElement,\n MosaicElement,\n RectangleElement,\n TextLayoutMetrics,\n} from '../core/model/document.js';\nimport type { ScreenshotTool } from '../types.js';\nimport type { ResizeHandle } from './selection-geometry.js';\n\nexport interface AnnotationStyle {\n color: string;\n lineWidth: number;\n fontSize: number;\n}\n\nexport type AnnotationElementStyle = Partial<AnnotationStyle>;\n\nexport const TEXT_LINE_HEIGHT = 1.3;\n\ntype TextBaselineMetrics = Pick<TextLayoutMetrics, 'ascent' | 'descent'> &\n Partial<Pick<TextLayoutMetrics, 'width'>>;\n\n/**\n * 将 textarea 外框左上角换算为 Canvas fillText 使用的首行基线。\n * DOM 会在内容区内平均分配行高留白,因此需要同时补偿边框、内边距和半行留白。\n */\nexport function calculateTextBaselinePosition(\n editorOrigin: Point,\n metrics: TextBaselineMetrics,\n contentOffset: Point,\n lineHeight: number\n): Point {\n const fontBoxHeight = metrics.ascent + metrics.descent;\n const leadingBeforeBaseline = Math.max(0, lineHeight - fontBoxHeight) / 2;\n return {\n x: editorOrigin.x + contentOffset.x,\n y: editorOrigin.y + contentOffset.y + leadingBeforeBaseline + metrics.ascent,\n };\n}\n\n/**\n * textarea 按字体框排版,而元素边界使用实际字形边界;提交时单独读取字体框指标,\n * 避免 Windows 等平台的字体上升部差异让 Canvas 文字相对输入位置上移。\n */\nexport function measureTextBaselineMetrics(\n context: Pick<CanvasRenderingContext2D, 'font' | 'measureText'>,\n fontSize: number\n): TextBaselineMetrics {\n const previousFont = context.font;\n context.font = getTextCanvasFont(fontSize);\n try {\n const metrics = context.measureText('Mg国');\n return {\n ascent: positiveMetric(\n metrics.fontBoundingBoxAscent,\n metrics.actualBoundingBoxAscent,\n fontSize * 0.8\n ),\n descent: positiveMetric(\n metrics.fontBoundingBoxDescent,\n metrics.actualBoundingBoxDescent,\n fontSize * 0.2\n ),\n };\n } finally {\n context.font = previousFont;\n }\n}\n\nfunction positiveMetric(...values: number[]): number {\n return values.find((value) => Number.isFinite(value) && value > 0) ?? 0;\n}\n\nexport function splitTextLines(value: string): string[] {\n return value.split(/\\r?\\n/);\n}\n\nexport function getTextCanvasFont(fontSize: number): string {\n return `600 ${fontSize}px system-ui, sans-serif`;\n}\n\n/** 使用与 Canvas 渲染一致的字体测量文字,避免中文等全角字符被固定比例低估。 */\nexport function measureTextLayout(\n context: Pick<CanvasRenderingContext2D, 'font' | 'measureText'>,\n value: string,\n fontSize: number\n): TextLayoutMetrics {\n const previousFont = context.font;\n context.font = getTextCanvasFont(fontSize);\n try {\n const lineMetrics = splitTextLines(value).map((line) => context.measureText(line));\n const referenceMetrics = context.measureText('Mg国');\n return {\n width: Math.max(1, ...lineMetrics.map((metrics) => metrics.width)),\n ascent: Math.max(\n fontSize * 0.8,\n referenceMetrics.actualBoundingBoxAscent,\n ...lineMetrics.map((metrics) => metrics.actualBoundingBoxAscent)\n ),\n descent: Math.max(\n fontSize * 0.2,\n referenceMetrics.actualBoundingBoxDescent,\n ...lineMetrics.map((metrics) => metrics.actualBoundingBoxDescent)\n ),\n };\n } finally {\n context.font = previousFont;\n }\n}\n\ninterface ElementIdentity {\n id: string;\n zIndex: number;\n createdAt: number;\n}\n\nexport function createDrawableElement(\n tool: Exclude<ScreenshotTool, 'text'>,\n point: Point,\n style: AnnotationStyle,\n identity: ElementIdentity\n): Exclude<AnnotationElement, { type: 'text' }> {\n const base = {\n ...identity,\n color: style.color,\n };\n\n switch (tool) {\n case 'rectangle':\n return {\n ...base,\n type: 'rectangle',\n bounds: { ...point, width: 0, height: 0 },\n lineWidth: style.lineWidth,\n } satisfies RectangleElement;\n case 'ellipse':\n return {\n ...base,\n type: 'ellipse',\n bounds: { ...point, width: 0, height: 0 },\n lineWidth: style.lineWidth,\n } satisfies EllipseElement;\n case 'arrow':\n return {\n ...base,\n type: 'arrow',\n start: point,\n end: point,\n lineWidth: style.lineWidth,\n } satisfies ArrowElement;\n case 'brush':\n return {\n ...base,\n type: 'brush',\n points: [point],\n lineWidth: style.lineWidth,\n } satisfies BrushElement;\n case 'mosaic':\n return {\n ...base,\n type: 'mosaic',\n bounds: { ...point, width: 0, height: 0 },\n } satisfies MosaicElement;\n }\n}\n\nexport function updateDrawableElement(\n element: Exclude<AnnotationElement, { type: 'text' }>,\n origin: Point,\n point: Point\n): Exclude<AnnotationElement, { type: 'text' }> {\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'mosaic':\n return { ...element, bounds: normalizeRect(origin, point) };\n case 'arrow':\n return { ...element, end: point };\n case 'brush':\n return shouldAppendPoint(element.points, point)\n ? { ...element, points: [...element.points, point] }\n : element;\n }\n}\n\nexport function isDrawableElementValid(element: AnnotationElement): boolean {\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'mosaic':\n return element.bounds.width >= 2 && element.bounds.height >= 2;\n case 'arrow':\n return distance(element.start, element.end) >= 2;\n case 'brush':\n return element.points.length >= 2;\n case 'text':\n return element.value.trim().length > 0;\n }\n}\n\nexport function getElementBounds(element: AnnotationElement): Rect {\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'mosaic':\n return element.bounds;\n case 'arrow':\n return paddedBounds([element.start, element.end], element.lineWidth * 2);\n case 'brush':\n return paddedBounds(element.points, element.lineWidth);\n case 'text': {\n const lines = splitTextLines(element.value);\n return {\n x: element.position.x,\n y: element.position.y - element.metrics.ascent,\n width: element.metrics.width,\n height:\n element.metrics.ascent +\n element.metrics.descent +\n element.fontSize * TEXT_LINE_HEIGHT * Math.max(0, lines.length - 1),\n };\n }\n }\n}\n\n/** 将工具栏样式应用到已选元素;传入值使用元素模型的 Image Pixel 单位。 */\nexport function updateElementStyle(\n element: AnnotationElement,\n style: AnnotationElementStyle\n): AnnotationElement {\n const color = style.color ?? element.color;\n\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'arrow':\n case 'brush': {\n const lineWidth = style.lineWidth ?? element.lineWidth;\n return color === element.color && lineWidth === element.lineWidth\n ? element\n : { ...element, color, lineWidth };\n }\n case 'text': {\n const fontSize = style.fontSize ?? element.fontSize;\n const scale = fontSize / element.fontSize;\n return color === element.color && fontSize === element.fontSize\n ? element\n : {\n ...element,\n color,\n fontSize,\n metrics: scaleTextMetrics(element.metrics, scale),\n };\n }\n case 'mosaic':\n return element;\n }\n}\n\nexport function hitTestElement(\n elements: AnnotationElement[],\n point: Point,\n tolerance: number\n): AnnotationElement | undefined {\n return [...elements]\n .sort((left, right) => right.zIndex - left.zIndex)\n .find((element) => isPointNearElement(element, point, tolerance));\n}\n\nexport function getResizeHandleAtPoint(\n element: AnnotationElement,\n point: Point,\n tolerance: number\n): ResizeHandle | undefined {\n const handles = getResizeHandlePoints(getElementBounds(element));\n return (Object.entries(handles) as Array<[ResizeHandle, Point]>).find(\n ([, handlePoint]) => distance(handlePoint, point) <= tolerance\n )?.[0];\n}\n\nexport function getResizeHandlePoints(bounds: Rect): Record<ResizeHandle, Point> {\n const centerX = bounds.x + bounds.width / 2;\n const centerY = bounds.y + bounds.height / 2;\n const right = bounds.x + bounds.width;\n const bottom = bounds.y + bounds.height;\n\n return {\n nw: { x: bounds.x, y: bounds.y },\n n: { x: centerX, y: bounds.y },\n ne: { x: right, y: bounds.y },\n e: { x: right, y: centerY },\n se: { x: right, y: bottom },\n s: { x: centerX, y: bottom },\n sw: { x: bounds.x, y: bottom },\n w: { x: bounds.x, y: centerY },\n };\n}\n\nexport function translateElement(\n element: AnnotationElement,\n delta: Point,\n bounds: Rect\n): AnnotationElement {\n const elementBounds = getElementBounds(element);\n const minimumX = bounds.x - elementBounds.x;\n const maximumX = bounds.x + bounds.width - (elementBounds.x + elementBounds.width);\n const minimumY = bounds.y - elementBounds.y;\n const maximumY = bounds.y + bounds.height - (elementBounds.y + elementBounds.height);\n const boundedDelta = {\n x: Math.min(Math.max(delta.x, minimumX), maximumX),\n y: Math.min(Math.max(delta.y, minimumY), maximumY),\n };\n\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'mosaic':\n return {\n ...element,\n bounds: {\n ...element.bounds,\n x: element.bounds.x + boundedDelta.x,\n y: element.bounds.y + boundedDelta.y,\n },\n };\n case 'arrow':\n return {\n ...element,\n start: addPoint(element.start, boundedDelta),\n end: addPoint(element.end, boundedDelta),\n };\n case 'brush':\n return {\n ...element,\n points: element.points.map((point) => addPoint(point, boundedDelta)),\n };\n case 'text':\n return { ...element, position: addPoint(element.position, boundedDelta) };\n }\n}\n\nexport function scaleElementToBounds(\n element: AnnotationElement,\n nextBounds: Rect\n): AnnotationElement {\n const previousBounds = getElementBounds(element);\n const mapPoint = (point: Point): Point => ({\n x:\n nextBounds.x +\n ((point.x - previousBounds.x) / Math.max(previousBounds.width, 1)) *\n nextBounds.width,\n y:\n nextBounds.y +\n ((point.y - previousBounds.y) / Math.max(previousBounds.height, 1)) *\n nextBounds.height,\n });\n\n switch (element.type) {\n case 'rectangle':\n case 'ellipse':\n case 'mosaic':\n return { ...element, bounds: nextBounds };\n case 'arrow':\n return { ...element, start: mapPoint(element.start), end: mapPoint(element.end) };\n case 'brush':\n return { ...element, points: element.points.map(mapPoint) };\n case 'text': {\n const scale = nextBounds.height / Math.max(previousBounds.height, 1);\n const fontSize = Math.max(8, element.fontSize * scale);\n const actualScale = fontSize / element.fontSize;\n return {\n ...element,\n position: mapPoint(element.position),\n fontSize,\n metrics: scaleTextMetrics(element.metrics, actualScale),\n };\n }\n }\n}\n\nfunction scaleTextMetrics(\n metrics: TextLayoutMetrics,\n scale: number\n): TextLayoutMetrics {\n return {\n width: metrics.width * scale,\n ascent: metrics.ascent * scale,\n descent: metrics.descent * scale,\n };\n}\n\nfunction isPointNearElement(\n element: AnnotationElement,\n point: Point,\n tolerance: number\n): boolean {\n if (element.type === 'arrow' || element.type === 'brush') {\n const points =\n element.type === 'arrow' ? [element.start, element.end] : element.points;\n return points.some((current, index) => {\n const next = points[index + 1];\n return next\n ? distanceToSegment(point, current, next) <= tolerance\n : distance(point, current) <= tolerance;\n });\n }\n\n const bounds = getElementBounds(element);\n return (\n point.x >= bounds.x - tolerance &&\n point.x <= bounds.x + bounds.width + tolerance &&\n point.y >= bounds.y - tolerance &&\n point.y <= bounds.y + bounds.height + tolerance\n );\n}\n\nfunction paddedBounds(points: Point[], padding: number): Rect {\n const xValues = points.map((point) => point.x);\n const yValues = points.map((point) => point.y);\n const left = Math.min(...xValues) - padding;\n const top = Math.min(...yValues) - padding;\n const right = Math.max(...xValues) + padding;\n const bottom = Math.max(...yValues) + padding;\n return { x: left, y: top, width: right - left, height: bottom - top };\n}\n\nfunction shouldAppendPoint(points: Point[], point: Point): boolean {\n const previous = points.at(-1);\n return !previous || distance(previous, point) >= 0.75;\n}\n\nfunction distance(left: Point, right: Point): number {\n return Math.hypot(left.x - right.x, left.y - right.y);\n}\n\nfunction distanceToSegment(point: Point, start: Point, end: Point): number {\n const lengthSquared = (end.x - start.x) ** 2 + (end.y - start.y) ** 2;\n if (lengthSquared === 0) {\n return distance(point, start);\n }\n\n const ratio = Math.max(\n 0,\n Math.min(\n 1,\n ((point.x - start.x) * (end.x - start.x) +\n (point.y - start.y) * (end.y - start.y)) /\n lengthSquared\n )\n );\n return distance(point, {\n x: start.x + ratio * (end.x - start.x),\n y: start.y + ratio * (end.y - start.y),\n });\n}\n\nfunction addPoint(point: Point, delta: Point): Point {\n return { x: point.x + delta.x, y: point.y + delta.y };\n}\n","import type { Rect, Size } from '../core/geometry/rect.js';\nimport type { AnnotationElement, MosaicElement } from '../core/model/document.js';\nimport {\n getElementBounds,\n getResizeHandlePoints,\n getTextCanvasFont,\n splitTextLines,\n TEXT_LINE_HEIGHT,\n} from './annotation-elements.js';\n\nexport type AnnotationDrawingContext =\n CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;\n\nconst MOSAIC_BLOCK_SIZE = 8;\n\nexport interface DrawAnnotationsOptions {\n clipBounds?: Rect;\n imageSize: Size;\n mosaicSource?: CanvasImageSource;\n draftElementId?: string | null;\n selectedElementId?: string | null;\n selectionHandleSize?: number;\n}\n\nexport function drawAnnotations(\n context: AnnotationDrawingContext,\n elements: AnnotationElement[],\n options: DrawAnnotationsOptions\n): void {\n context.save();\n if (options.clipBounds) {\n context.beginPath();\n context.rect(\n options.clipBounds.x,\n options.clipBounds.y,\n options.clipBounds.width,\n options.clipBounds.height\n );\n context.clip();\n }\n\n for (const element of [...elements].sort(\n (left, right) => left.zIndex - right.zIndex\n )) {\n drawElement(context, element, options);\n }\n context.restore();\n\n const draft = elements.find((element) => element.id === options.draftElementId);\n if (draft?.type === 'mosaic') {\n drawDraftOutline(\n context,\n getElementBounds(draft),\n options.selectionHandleSize ?? 8\n );\n }\n\n const selected = elements.find((element) => element.id === options.selectedElementId);\n if (selected) {\n drawSelectionOutline(\n context,\n getElementBounds(selected),\n options.selectionHandleSize ?? 8\n );\n }\n}\n\nfunction drawElement(\n context: AnnotationDrawingContext,\n element: AnnotationElement,\n options: DrawAnnotationsOptions\n): void {\n context.save();\n context.strokeStyle = element.color;\n context.fillStyle = element.color;\n context.lineCap = 'round';\n context.lineJoin = 'round';\n\n switch (element.type) {\n case 'rectangle':\n context.lineWidth = element.lineWidth;\n context.strokeRect(\n element.bounds.x,\n element.bounds.y,\n element.bounds.width,\n element.bounds.height\n );\n break;\n case 'ellipse':\n context.lineWidth = element.lineWidth;\n context.beginPath();\n context.ellipse(\n element.bounds.x + element.bounds.width / 2,\n element.bounds.y + element.bounds.height / 2,\n element.bounds.width / 2,\n element.bounds.height / 2,\n 0,\n 0,\n Math.PI * 2\n );\n context.stroke();\n break;\n case 'arrow':\n drawArrow(\n context,\n element.start.x,\n element.start.y,\n element.end.x,\n element.end.y,\n element.lineWidth\n );\n break;\n case 'brush':\n context.lineWidth = element.lineWidth;\n drawPolyline(context, element.points);\n break;\n case 'text':\n context.font = getTextCanvasFont(element.fontSize);\n context.textBaseline = 'alphabetic';\n splitTextLines(element.value).forEach((line, index) => {\n context.fillText(\n line,\n element.position.x,\n element.position.y + index * element.fontSize * TEXT_LINE_HEIGHT\n );\n });\n break;\n case 'mosaic':\n if (options.mosaicSource) {\n drawMosaic(context, element, options.mosaicSource, options.imageSize);\n }\n break;\n }\n context.restore();\n}\n\nfunction drawArrow(\n context: AnnotationDrawingContext,\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n lineWidth: number\n): void {\n const angle = Math.atan2(endY - startY, endX - startX);\n const headLength = Math.max(12, lineWidth * 4);\n context.lineWidth = lineWidth;\n context.beginPath();\n context.moveTo(startX, startY);\n context.lineTo(endX, endY);\n context.lineTo(\n endX - headLength * Math.cos(angle - Math.PI / 6),\n endY - headLength * Math.sin(angle - Math.PI / 6)\n );\n context.moveTo(endX, endY);\n context.lineTo(\n endX - headLength * Math.cos(angle + Math.PI / 6),\n endY - headLength * Math.sin(angle + Math.PI / 6)\n );\n context.stroke();\n}\n\nfunction drawPolyline(\n context: AnnotationDrawingContext,\n points: Array<{ x: number; y: number }>\n): void {\n const first = points[0];\n if (!first) {\n return;\n }\n context.beginPath();\n context.moveTo(first.x, first.y);\n for (const point of points.slice(1)) {\n context.lineTo(point.x, point.y);\n }\n context.stroke();\n}\n\nfunction drawMosaic(\n context: AnnotationDrawingContext,\n element: MosaicElement,\n source: CanvasImageSource,\n imageSize: Size\n): void {\n // 只采样马赛克周边,并将网格对齐到整张图片,移动或缩放后块不会漂移。\n const sourceX = Math.max(\n 0,\n Math.floor(element.bounds.x / MOSAIC_BLOCK_SIZE) * MOSAIC_BLOCK_SIZE\n );\n const sourceY = Math.max(\n 0,\n Math.floor(element.bounds.y / MOSAIC_BLOCK_SIZE) * MOSAIC_BLOCK_SIZE\n );\n const sourceRight = Math.min(\n imageSize.width,\n Math.ceil((element.bounds.x + element.bounds.width) / MOSAIC_BLOCK_SIZE) *\n MOSAIC_BLOCK_SIZE\n );\n const sourceBottom = Math.min(\n imageSize.height,\n Math.ceil((element.bounds.y + element.bounds.height) / MOSAIC_BLOCK_SIZE) *\n MOSAIC_BLOCK_SIZE\n );\n const sourceWidth = sourceRight - sourceX;\n const sourceHeight = sourceBottom - sourceY;\n if (sourceWidth <= 0 || sourceHeight <= 0) {\n return;\n }\n const sampleWidth = Math.max(1, Math.ceil(sourceWidth / MOSAIC_BLOCK_SIZE));\n const sampleHeight = Math.max(1, Math.ceil(sourceHeight / MOSAIC_BLOCK_SIZE));\n const sampleCanvas = createRasterCanvas(sampleWidth, sampleHeight);\n const sampleContext = sampleCanvas.getContext('2d');\n if (!sampleContext) {\n return;\n }\n\n // 缩小时使用高质量平均色,避免单点取样把一整块错误放大成纯白或纯灰。\n sampleContext.imageSmoothingEnabled = true;\n sampleContext.imageSmoothingQuality = 'high';\n sampleContext.drawImage(\n source,\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight,\n 0,\n 0,\n sampleWidth,\n sampleHeight\n );\n\n context.save();\n context.beginPath();\n context.rect(\n element.bounds.x,\n element.bounds.y,\n element.bounds.width,\n element.bounds.height\n );\n context.clip();\n context.imageSmoothingEnabled = false;\n context.drawImage(\n sampleCanvas,\n 0,\n 0,\n sampleWidth,\n sampleHeight,\n sourceX,\n sourceY,\n sourceWidth,\n sourceHeight\n );\n context.restore();\n}\n\n/** 绘制过程中用半透明底色和双层边框强调范围,不提前暴露移动和缩放控制点。 */\nfunction drawDraftOutline(\n context: AnnotationDrawingContext,\n bounds: Rect,\n handleSize: number\n): void {\n context.save();\n context.fillStyle = 'rgba(10, 132, 255, 0.24)';\n context.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);\n context.strokeStyle = 'rgba(0, 0, 0, 0.78)';\n context.lineWidth = Math.max(3.5, handleSize / 2);\n context.setLineDash([]);\n context.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height);\n context.strokeStyle = '#53b5ff';\n context.lineWidth = Math.max(1.5, handleSize / 5);\n context.setLineDash([handleSize * 0.75, handleSize * 0.5]);\n context.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height);\n context.setLineDash([]);\n context.restore();\n}\n\nfunction drawSelectionOutline(\n context: AnnotationDrawingContext,\n bounds: Rect,\n handleSize: number\n): void {\n context.save();\n context.strokeStyle = '#ffffff';\n context.fillStyle = '#35a7ff';\n context.lineWidth = Math.max(1, handleSize / 8);\n context.setLineDash([handleSize, handleSize / 2]);\n context.strokeRect(bounds.x, bounds.y, bounds.width, bounds.height);\n context.setLineDash([]);\n\n for (const point of Object.values(getResizeHandlePoints(bounds))) {\n context.fillRect(\n point.x - handleSize / 2,\n point.y - handleSize / 2,\n handleSize,\n handleSize\n );\n context.strokeRect(\n point.x - handleSize / 2,\n point.y - handleSize / 2,\n handleSize,\n handleSize\n );\n }\n context.restore();\n}\n\nfunction createRasterCanvas(\n width: number,\n height: number\n): OffscreenCanvas | HTMLCanvasElement {\n if (typeof OffscreenCanvas !== 'undefined') {\n return new OffscreenCanvas(width, height);\n }\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n}\n","export interface ScreenshotCommand<TDocument> {\n execute(document: TDocument): TDocument;\n undo(document: TDocument): TDocument;\n}\n\nexport class CommandStack<TDocument> {\n readonly #undoStack: ScreenshotCommand<TDocument>[] = [];\n readonly #redoStack: ScreenshotCommand<TDocument>[] = [];\n\n execute(command: ScreenshotCommand<TDocument>, document: TDocument): TDocument {\n const nextDocument = command.execute(document);\n this.#undoStack.push(command);\n this.#redoStack.length = 0;\n return nextDocument;\n }\n\n undo(document: TDocument): TDocument {\n const command = this.#undoStack.pop();\n if (!command) return document;\n\n const previousDocument = command.undo(document);\n this.#redoStack.push(command);\n return previousDocument;\n }\n\n redo(document: TDocument): TDocument {\n const command = this.#redoStack.pop();\n if (!command) return document;\n\n const nextDocument = command.execute(document);\n this.#undoStack.push(command);\n return nextDocument;\n }\n\n clear(): void {\n this.#undoStack.length = 0;\n this.#redoStack.length = 0;\n }\n\n get canUndo(): boolean {\n return this.#undoStack.length > 0;\n }\n\n get canRedo(): boolean {\n return this.#redoStack.length > 0;\n }\n}\n","import type { AnnotationElement, ScreenshotDocument } from '../model/document.js';\nimport type { ScreenshotCommand } from './command-stack.js';\n\nexport class AddElementCommand implements ScreenshotCommand<ScreenshotDocument> {\n readonly #element: AnnotationElement;\n\n constructor(element: AnnotationElement) {\n this.#element = element;\n }\n\n execute(document: ScreenshotDocument): ScreenshotDocument {\n if (document.elements.some((element) => element.id === this.#element.id)) {\n return document;\n }\n\n return { ...document, elements: [...document.elements, this.#element] };\n }\n\n undo(document: ScreenshotDocument): ScreenshotDocument {\n return {\n ...document,\n elements: document.elements.filter((element) => element.id !== this.#element.id),\n };\n }\n}\n\nexport class UpdateElementCommand implements ScreenshotCommand<ScreenshotDocument> {\n readonly #before: AnnotationElement;\n readonly #after: AnnotationElement;\n\n constructor(before: AnnotationElement, after: AnnotationElement) {\n if (before.id !== after.id) {\n throw new Error('An annotation update must preserve the element id.');\n }\n this.#before = before;\n this.#after = after;\n }\n\n execute(document: ScreenshotDocument): ScreenshotDocument {\n return replaceElement(document, this.#after);\n }\n\n undo(document: ScreenshotDocument): ScreenshotDocument {\n return replaceElement(document, this.#before);\n }\n}\n\nexport class RemoveElementCommand implements ScreenshotCommand<ScreenshotDocument> {\n readonly #element: AnnotationElement;\n readonly #index: number;\n\n constructor(element: AnnotationElement, index: number) {\n this.#element = element;\n this.#index = index;\n }\n\n execute(document: ScreenshotDocument): ScreenshotDocument {\n return {\n ...document,\n elements: document.elements.filter((element) => element.id !== this.#element.id),\n };\n }\n\n undo(document: ScreenshotDocument): ScreenshotDocument {\n if (document.elements.some((element) => element.id === this.#element.id)) {\n return document;\n }\n\n const elements = [...document.elements];\n elements.splice(Math.min(this.#index, elements.length), 0, this.#element);\n return { ...document, elements };\n }\n}\n\nfunction replaceElement(\n document: ScreenshotDocument,\n replacement: AnnotationElement\n): ScreenshotDocument {\n let found = false;\n const elements = document.elements.map((element) => {\n if (element.id !== replacement.id) {\n return element;\n }\n found = true;\n return replacement;\n });\n\n return found ? { ...document, elements } : document;\n}\n","import { CommandStack } from '../core/history/command-stack.js';\nimport {\n AddElementCommand,\n RemoveElementCommand,\n UpdateElementCommand,\n} from '../core/history/document-commands.js';\nimport type { Rect } from '../core/geometry/rect.js';\nimport type { AnnotationElement, ScreenshotDocument } from '../core/model/document.js';\nimport type { ScreenshotTool } from '../types.js';\nimport type { AnnotationStyle } from './annotation-elements.js';\n\nexport type AnnotationTool = 'select' | ScreenshotTool;\n\nexport interface AnnotationState {\n document: ScreenshotDocument | null;\n activeTool: AnnotationTool;\n selectedElementId: string | null;\n draft: AnnotationElement | null;\n preview: AnnotationElement | null;\n style: AnnotationStyle;\n canUndo: boolean;\n canRedo: boolean;\n}\n\nexport interface AnnotationStore {\n getState(): AnnotationState;\n initialize(selection: Rect, activeTool?: AnnotationTool): void;\n setSelection(selection: Rect): void;\n setTool(tool: AnnotationTool): void;\n setStyle(style: Partial<AnnotationStyle>): void;\n setDraft(element: AnnotationElement | null): void;\n commitDraft(select?: boolean): void;\n select(elementId: string | null): void;\n preview(element: AnnotationElement | null): void;\n commitUpdate(before: AnnotationElement, after: AnnotationElement): void;\n deleteSelected(): void;\n undo(): void;\n redo(): void;\n subscribe(listener: (state: AnnotationState) => void): () => void;\n}\n\nconst defaultStyle: AnnotationStyle = {\n color: '#ff3b30',\n lineWidth: 4,\n fontSize: 24,\n};\n\nexport function createAnnotationStore(): AnnotationStore {\n const history = new CommandStack<ScreenshotDocument>();\n const listeners = new Set<(state: AnnotationState) => void>();\n let state: AnnotationState = {\n document: null,\n activeTool: 'select',\n selectedElementId: null,\n draft: null,\n preview: null,\n style: defaultStyle,\n canUndo: false,\n canRedo: false,\n };\n\n const update = (patch: Partial<AnnotationState>): void => {\n state = { ...state, ...patch };\n listeners.forEach((listener) => listener(state));\n };\n const updateDocument = (document: ScreenshotDocument): void => {\n update({ document, canUndo: history.canUndo, canRedo: history.canRedo });\n };\n\n return {\n getState: () => state,\n initialize(selection, activeTool = 'select') {\n history.clear();\n update({\n document: { selection, elements: [] },\n activeTool,\n selectedElementId: null,\n draft: null,\n preview: null,\n canUndo: false,\n canRedo: false,\n });\n },\n setSelection(selection) {\n if (state.document) {\n update({ document: { ...state.document, selection } });\n }\n },\n setTool(activeTool) {\n update({ activeTool, selectedElementId: null, draft: null, preview: null });\n },\n setStyle(style) {\n update({ style: { ...state.style, ...style } });\n },\n setDraft(draft) {\n update({ draft });\n },\n commitDraft(select = true) {\n if (!state.document || !state.draft) {\n return;\n }\n const draft = state.draft;\n updateDocument(history.execute(new AddElementCommand(draft), state.document));\n update({ draft: null, selectedElementId: select ? draft.id : null });\n },\n select(selectedElementId) {\n update({ selectedElementId, preview: null });\n },\n preview(preview) {\n update({ preview });\n },\n commitUpdate(before, after) {\n if (!state.document) {\n return;\n }\n updateDocument(\n history.execute(new UpdateElementCommand(before, after), state.document)\n );\n update({ preview: null, selectedElementId: after.id });\n },\n deleteSelected() {\n if (!state.document || !state.selectedElementId) {\n return;\n }\n const index = state.document.elements.findIndex(\n (element) => element.id === state.selectedElementId\n );\n const element = state.document.elements[index];\n if (!element) {\n return;\n }\n updateDocument(\n history.execute(new RemoveElementCommand(element, index), state.document)\n );\n update({ selectedElementId: null, preview: null });\n },\n undo() {\n if (state.document) {\n updateDocument(history.undo(state.document));\n update({ selectedElementId: null, preview: null, draft: null });\n }\n },\n redo() {\n if (state.document) {\n updateDocument(history.redo(state.document));\n update({ selectedElementId: null, preview: null, draft: null });\n }\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\nexport function getRenderableElements(state: AnnotationState): AnnotationElement[] {\n if (!state.document) {\n return state.draft ? [state.draft] : [];\n }\n\n const elements = state.preview\n ? state.document.elements.map((element) =>\n element.id === state.preview?.id ? state.preview : element\n )\n : state.document.elements;\n return state.draft ? [...elements, state.draft] : elements;\n}\n","import type { Rect } from '../core/geometry/rect.js';\nimport type { AnnotationElement } from '../core/model/document.js';\nimport { drawAnnotations } from './annotation-renderer.js';\n\n/** 使用不挂载到页面的 Canvas 裁剪捕获帧,工具栏和遮罩不会进入输出图片。 */\nexport async function exportSelectionPng(\n source: CanvasImageSource,\n imageRect: Rect,\n elements: AnnotationElement[] = [],\n imageSize: { width: number; height: number } = imageRect\n): Promise<Uint8Array> {\n const width = Math.round(imageRect.width);\n const height = Math.round(imageRect.height);\n if (width <= 0 || height <= 0) {\n throw new RangeError('The exported screenshot selection must not be empty.');\n }\n\n if (typeof OffscreenCanvas !== 'undefined') {\n const canvas = new OffscreenCanvas(width, height);\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Unable to create a 2D canvas context.');\n }\n\n drawSelection(context, source, imageRect, width, height, elements, imageSize);\n const blob = await canvas.convertToBlob({ type: 'image/png' });\n return new Uint8Array(await blob.arrayBuffer());\n }\n\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Unable to create a 2D canvas context.');\n }\n\n drawSelection(context, source, imageRect, width, height, elements, imageSize);\n const blob = await new Promise<Blob>((resolve, reject) => {\n canvas.toBlob((value) => {\n if (value) {\n resolve(value);\n } else {\n reject(new Error('Unable to encode the screenshot selection as PNG.'));\n }\n }, 'image/png');\n });\n return new Uint8Array(await blob.arrayBuffer());\n}\n\nfunction drawSelection(\n context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n source: CanvasImageSource,\n imageRect: Rect,\n width: number,\n height: number,\n elements: AnnotationElement[],\n imageSize: { width: number; height: number }\n): void {\n context.drawImage(\n source,\n imageRect.x,\n imageRect.y,\n imageRect.width,\n imageRect.height,\n 0,\n 0,\n width,\n height\n );\n\n if (elements.length > 0) {\n context.save();\n context.translate(-imageRect.x, -imageRect.y);\n drawAnnotations(context, elements, {\n clipBounds: imageRect,\n imageSize,\n mosaicSource: source,\n });\n context.restore();\n }\n}\n","import type {\n ScreenshotLocale,\n ScreenshotMessageOverrides,\n ScreenshotMessages,\n ScreenshotTheme,\n} from '../types.js';\n\nexport const DEFAULT_SCREENSHOT_LOCALE: ScreenshotLocale = 'en-US';\n\nconst ENGLISH_MESSAGES: ScreenshotMessages = {\n preparing: 'Preparing screenshot…',\n instruction: 'Drag to select an area · Esc to cancel',\n exporting: 'Exporting screenshot…',\n copied: 'Copied to clipboard',\n saveCancelled: 'Save cancelled',\n cancel: 'Cancel',\n save: 'Save',\n confirm: 'Copy & Done',\n select: 'Select',\n rectangle: 'Rectangle',\n ellipse: 'Ellipse',\n arrow: 'Arrow',\n brush: 'Brush',\n text: 'Text',\n mosaic: 'Mosaic',\n undo: 'Undo',\n redo: 'Redo',\n color: 'Color',\n lineWidth: 'Line width',\n fontSize: 'Font size',\n annotationCanvas: 'Screenshot annotations',\n selection: 'Screenshot selection',\n actions: 'Screenshot actions',\n annotationTools: 'Annotation tools',\n history: 'History',\n annotationStyle: 'Annotation style',\n outputActions: 'Output actions',\n annotationText: 'Annotation text',\n};\n\nconst LOCALE_MESSAGES: Record<ScreenshotLocale, Partial<ScreenshotMessages>> = {\n 'en-US': ENGLISH_MESSAGES,\n 'zh-CN': {\n preparing: '正在准备截图…',\n instruction: '拖动选择截图区域 · Esc 取消',\n exporting: '正在生成截图…',\n copied: '已复制到剪贴板',\n saveCancelled: '已取消保存',\n cancel: '取消',\n save: '保存',\n confirm: '复制并完成',\n select: '选择',\n rectangle: '矩形',\n ellipse: '椭圆',\n arrow: '箭头',\n brush: '画笔',\n text: '文字',\n mosaic: '马赛克',\n undo: '撤销',\n redo: '重做',\n color: '颜色',\n lineWidth: '线宽',\n fontSize: '字号',\n annotationCanvas: '截图标注画布',\n selection: '截图选区',\n actions: '截图操作',\n annotationTools: '标注工具',\n history: '操作历史',\n annotationStyle: '标注样式',\n outputActions: '输出操作',\n annotationText: '标注文字',\n },\n};\n\nconst THEME_TOKEN_MAP = {\n accentColor: '--snapora-color-accent',\n accentForegroundColor: '--snapora-color-on-accent',\n maskColor: '--snapora-color-mask',\n toolbarBackground: '--snapora-color-surface',\n toolbarForeground: '--snapora-color-on-surface',\n toolbarBorderColor: '--snapora-color-border',\n toolbarHoverBackground: '--snapora-color-hover',\n tooltipBackground: '--snapora-color-tooltip',\n tooltipForeground: '--snapora-color-on-tooltip',\n destructiveColor: '--snapora-color-danger',\n warningColor: '--snapora-color-warning',\n warningForegroundColor: '--snapora-color-on-warning',\n selectionHandleColor: '--snapora-color-handle',\n} as const satisfies Record<Exclude<keyof ScreenshotTheme, 'mode'>, string>;\n\nexport interface ResolvedScreenshotTheme {\n mode: NonNullable<ScreenshotTheme['mode']>;\n tokens: Readonly<Record<string, string>>;\n}\n\n/** 宿主只覆盖语义 Token,组件层继续引用稳定别名,避免公共 API 绑定具体 DOM。 */\nexport function resolveScreenshotTheme(\n theme: ScreenshotTheme | undefined\n): ResolvedScreenshotTheme {\n const tokens: Record<string, string> = {};\n for (const [key, token] of Object.entries(THEME_TOKEN_MAP)) {\n const value = theme?.[key as keyof typeof THEME_TOKEN_MAP];\n if (value) {\n tokens[token] = value;\n }\n }\n return { mode: theme?.mode ?? 'dark', tokens };\n}\n\n/** 文案按英文基线、所选语言、宿主覆盖三层合并,局部翻译不会产生 undefined。 */\nexport function resolveScreenshotMessages(\n locale: ScreenshotLocale = DEFAULT_SCREENSHOT_LOCALE,\n overrides: ScreenshotMessageOverrides = {}\n): ScreenshotMessages {\n return {\n ...ENGLISH_MESSAGES,\n ...LOCALE_MESSAGES[locale],\n ...overrides,\n };\n}\n","import type { Point, Rect, Size } from '../core/geometry/rect.js';\n\nexport type ResizeHandle = 'n' | 'ne' | 'e' | 'se' | 's' | 'sw' | 'w' | 'nw';\n\nexport interface ToolbarPosition extends Point {\n placement: 'above' | 'below' | 'inside';\n}\n\nexport function clampPoint(point: Point, bounds: Rect): Point {\n return {\n x: Math.min(Math.max(point.x, bounds.x), bounds.x + bounds.width),\n y: Math.min(Math.max(point.y, bounds.y), bounds.y + bounds.height),\n };\n}\n\nexport function createSelection(start: Point, end: Point, bounds: Rect): Rect {\n const boundedStart = clampPoint(start, bounds);\n const boundedEnd = clampPoint(end, bounds);\n\n return {\n x: Math.min(boundedStart.x, boundedEnd.x),\n y: Math.min(boundedStart.y, boundedEnd.y),\n width: Math.abs(boundedEnd.x - boundedStart.x),\n height: Math.abs(boundedEnd.y - boundedStart.y),\n };\n}\n\nexport function moveSelection(selection: Rect, delta: Point, bounds: Rect): Rect {\n const maximumX = bounds.x + Math.max(0, bounds.width - selection.width);\n const maximumY = bounds.y + Math.max(0, bounds.height - selection.height);\n\n return {\n ...selection,\n x: Math.min(Math.max(selection.x + delta.x, bounds.x), maximumX),\n y: Math.min(Math.max(selection.y + delta.y, bounds.y), maximumY),\n };\n}\n\nexport function resizeSelection(\n selection: Rect,\n handle: ResizeHandle,\n point: Point,\n bounds: Rect,\n minimumSize: number\n): Rect {\n const boundedPoint = clampPoint(point, bounds);\n let left = selection.x;\n let top = selection.y;\n let right = selection.x + selection.width;\n let bottom = selection.y + selection.height;\n\n if (handle.includes('w')) {\n left = Math.min(boundedPoint.x, right - minimumSize);\n left = Math.max(left, bounds.x);\n }\n if (handle.includes('e')) {\n right = Math.max(boundedPoint.x, left + minimumSize);\n right = Math.min(right, bounds.x + bounds.width);\n }\n if (handle.includes('n')) {\n top = Math.min(boundedPoint.y, bottom - minimumSize);\n top = Math.max(top, bounds.y);\n }\n if (handle.includes('s')) {\n bottom = Math.max(boundedPoint.y, top + minimumSize);\n bottom = Math.min(bottom, bounds.y + bounds.height);\n }\n\n return {\n x: left,\n y: top,\n width: right - left,\n height: bottom - top,\n };\n}\n\n/**\n * 选区使用 CSS Pixel 交互,导出时按捕获帧的真实像素尺寸映射边缘。\n * 左上向下取整、右下向上取整,避免缩放比不是整数时丢失选区边缘像素。\n */\nexport function viewportRectToImageRect(\n selection: Rect,\n viewportSize: Size,\n imageSize: Size\n): Rect {\n assertPositiveSize(viewportSize, 'Viewport');\n assertPositiveSize(imageSize, 'Image');\n\n const scaleX = imageSize.width / viewportSize.width;\n const scaleY = imageSize.height / viewportSize.height;\n const left = Math.max(0, Math.floor(selection.x * scaleX));\n const top = Math.max(0, Math.floor(selection.y * scaleY));\n const right = Math.min(\n imageSize.width,\n Math.ceil((selection.x + selection.width) * scaleX)\n );\n const bottom = Math.min(\n imageSize.height,\n Math.ceil((selection.y + selection.height) * scaleY)\n );\n\n return {\n x: left,\n y: top,\n width: Math.max(0, right - left),\n height: Math.max(0, bottom - top),\n };\n}\n\n/** 将 Overlay CSS 坐标换算为 Electron screen 模块使用的全局 DIP 坐标。 */\nexport function viewportRectToScreenRect(\n selection: Rect,\n viewportSize: Size,\n displayBounds: Rect\n): Rect {\n assertPositiveSize(viewportSize, 'Viewport');\n\n const scaleX = displayBounds.width / viewportSize.width;\n const scaleY = displayBounds.height / viewportSize.height;\n\n return {\n x: displayBounds.x + selection.x * scaleX,\n y: displayBounds.y + selection.y * scaleY,\n width: selection.width * scaleX,\n height: selection.height * scaleY,\n };\n}\n\nexport function calculateToolbarPosition(\n selection: Rect,\n viewportSize: Size,\n toolbarSize: Size,\n gap = 10,\n edgePadding = 8\n): ToolbarPosition {\n const maximumX = Math.max(\n edgePadding,\n viewportSize.width - toolbarSize.width - edgePadding\n );\n const x = Math.min(\n Math.max(selection.x + selection.width - toolbarSize.width, edgePadding),\n maximumX\n );\n const belowY = selection.y + selection.height + gap;\n if (belowY + toolbarSize.height <= viewportSize.height - edgePadding) {\n return { x, y: belowY, placement: 'below' };\n }\n\n const aboveY = selection.y - toolbarSize.height - gap;\n if (aboveY >= edgePadding) {\n return { x, y: aboveY, placement: 'above' };\n }\n\n return {\n x,\n y: Math.min(\n Math.max(selection.y + gap, edgePadding),\n Math.max(edgePadding, viewportSize.height - toolbarSize.height - edgePadding)\n ),\n placement: 'inside',\n };\n}\n\nfunction assertPositiveSize(size: Size, label: string): void {\n if (size.width <= 0 || size.height <= 0) {\n throw new RangeError(`${label} dimensions must be greater than zero.`);\n }\n}\n","import { isRectValid, type Point, type Rect } from '../core/geometry/rect.js';\nimport type { ScreenshotInitializePayload } from '../electron/protocol/messages.js';\nimport {\n createSelection,\n moveSelection,\n resizeSelection,\n type ResizeHandle,\n} from './selection-geometry.js';\n\nexport const MINIMUM_SELECTION_SIZE = 4;\n\nexport type OverlayPhase =\n 'waiting' | 'ready' | 'creating' | 'selected' | 'moving' | 'resizing' | 'exporting';\n\ntype OverlayInteraction =\n | { kind: 'create'; pointerId: number; origin: Point }\n | { kind: 'move'; pointerId: number; origin: Point; initialSelection: Rect }\n | {\n kind: 'resize';\n pointerId: number;\n handle: ResizeHandle;\n initialSelection: Rect;\n };\n\nexport interface OverlayState {\n phase: OverlayPhase;\n payload: ScreenshotInitializePayload | null;\n selection: Rect | null;\n interaction: OverlayInteraction | null;\n}\n\nexport type OverlayAction =\n | { type: 'initialize'; payload: ScreenshotInitializePayload }\n | { type: 'image-ready' }\n | { type: 'begin-create'; pointerId: number; point: Point; bounds: Rect }\n | { type: 'begin-move'; pointerId: number; point: Point }\n | { type: 'begin-resize'; pointerId: number; handle: ResizeHandle }\n | { type: 'pointer-move'; pointerId: number; point: Point; bounds: Rect }\n | { type: 'end-interaction'; pointerId: number }\n | { type: 'begin-export' }\n | { type: 'export-failed' };\n\nexport interface OverlayStore {\n getState(): OverlayState;\n dispatch(action: OverlayAction): void;\n subscribe(listener: (state: OverlayState) => void): () => void;\n}\n\nexport const initialOverlayState: OverlayState = {\n phase: 'waiting',\n payload: null,\n selection: null,\n interaction: null,\n};\n\nexport function createOverlayStore(\n initialState: OverlayState = initialOverlayState\n): OverlayStore {\n let state = initialState;\n const listeners = new Set<(nextState: OverlayState) => void>();\n\n return {\n getState: () => state,\n dispatch(action) {\n const nextState = reduceOverlayState(state, action);\n if (nextState === state) {\n return;\n }\n\n state = nextState;\n listeners.forEach((listener) => listener(state));\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => listeners.delete(listener);\n },\n };\n}\n\nexport function reduceOverlayState(\n state: OverlayState,\n action: OverlayAction\n): OverlayState {\n switch (action.type) {\n case 'initialize':\n return {\n phase: 'waiting',\n payload: action.payload,\n selection: null,\n interaction: null,\n };\n case 'image-ready':\n return state.payload ? { ...state, phase: 'ready' } : state;\n case 'begin-create':\n if (!state.payload || state.phase === 'exporting') {\n return state;\n }\n return {\n ...state,\n phase: 'creating',\n selection: createSelection(action.point, action.point, action.bounds),\n interaction: {\n kind: 'create',\n pointerId: action.pointerId,\n origin: action.point,\n },\n };\n case 'begin-move':\n if (!state.selection || state.phase === 'exporting') {\n return state;\n }\n return {\n ...state,\n phase: 'moving',\n interaction: {\n kind: 'move',\n pointerId: action.pointerId,\n origin: action.point,\n initialSelection: state.selection,\n },\n };\n case 'begin-resize':\n if (!state.selection || state.phase === 'exporting') {\n return state;\n }\n return {\n ...state,\n phase: 'resizing',\n interaction: {\n kind: 'resize',\n pointerId: action.pointerId,\n handle: action.handle,\n initialSelection: state.selection,\n },\n };\n case 'pointer-move':\n return updatePointerInteraction(\n state,\n action.pointerId,\n action.point,\n action.bounds\n );\n case 'end-interaction':\n if (!state.interaction || state.interaction.pointerId !== action.pointerId) {\n return state;\n }\n return {\n ...state,\n phase:\n state.selection && isRectValid(state.selection, MINIMUM_SELECTION_SIZE)\n ? 'selected'\n : 'ready',\n selection:\n state.selection && isRectValid(state.selection, MINIMUM_SELECTION_SIZE)\n ? state.selection\n : null,\n interaction: null,\n };\n case 'begin-export':\n return state.selection && state.phase === 'selected'\n ? { ...state, phase: 'exporting' }\n : state;\n case 'export-failed':\n return state.selection ? { ...state, phase: 'selected' } : state;\n }\n}\n\nfunction updatePointerInteraction(\n state: OverlayState,\n pointerId: number,\n point: Point,\n bounds: Rect\n): OverlayState {\n const interaction = state.interaction;\n if (!interaction || interaction.pointerId !== pointerId) {\n return state;\n }\n\n if (interaction.kind === 'create') {\n return {\n ...state,\n selection: createSelection(interaction.origin, point, bounds),\n };\n }\n\n if (interaction.kind === 'move') {\n return {\n ...state,\n selection: moveSelection(\n interaction.initialSelection,\n { x: point.x - interaction.origin.x, y: point.y - interaction.origin.y },\n bounds\n ),\n };\n }\n\n return {\n ...state,\n selection: resizeSelection(\n interaction.initialSelection,\n interaction.handle,\n point,\n bounds,\n MINIMUM_SELECTION_SIZE\n ),\n };\n}\n","import './styles.css';\n\nimport {\n viewportPointToImagePoint,\n type Point,\n type Rect,\n type Size,\n} from '../core/geometry/rect.js';\nimport type { AnnotationElement, TextElement } from '../core/model/document.js';\nimport type { ScreenshotInitializePayload } from '../electron/protocol/messages.js';\nimport type {\n ScreenshotMessages,\n ScreenshotOptions,\n ScreenshotTool,\n} from '../types.js';\nimport {\n calculateTextBaselinePosition,\n createDrawableElement,\n getElementBounds,\n getResizeHandleAtPoint,\n hitTestElement,\n isDrawableElementValid,\n measureTextBaselineMetrics,\n measureTextLayout,\n scaleElementToBounds,\n translateElement,\n updateDrawableElement,\n updateElementStyle,\n TEXT_LINE_HEIGHT,\n type AnnotationElementStyle,\n} from './annotation-elements.js';\nimport { drawAnnotations } from './annotation-renderer.js';\nimport {\n createAnnotationStore,\n getRenderableElements,\n type AnnotationTool,\n} from './annotation-store.js';\nimport { exportSelectionPng } from './export-selection.js';\nimport { resolveScreenshotMessages, resolveScreenshotTheme } from './presentation.js';\nimport {\n calculateToolbarPosition,\n clampPoint,\n resizeSelection,\n viewportRectToImageRect,\n viewportRectToScreenRect,\n type ResizeHandle,\n} from './selection-geometry.js';\nimport { createOverlayStore } from './selection-store.js';\n\ntype DrawingElement = Exclude<AnnotationElement, TextElement>;\n\ntype PointerInteraction =\n | { kind: 'draw'; pointerId: number; origin: Point; element: DrawingElement }\n | {\n kind: 'move-element';\n pointerId: number;\n origin: Point;\n before: AnnotationElement;\n }\n | {\n kind: 'resize-element';\n pointerId: number;\n before: AnnotationElement;\n handle: ResizeHandle;\n }\n | { kind: 'selection'; pointerId: number };\n\nfunction requireElement<T extends HTMLElement>(selector: string): T {\n const element = document.querySelector<T>(selector);\n if (!element) {\n throw new Error(`Electron Snapora overlay element is missing: ${selector}`);\n }\n return element;\n}\n\nfunction requireCanvasContext(canvas: HTMLCanvasElement): CanvasRenderingContext2D {\n const context = canvas.getContext('2d');\n if (!context) {\n throw new Error('Electron Snapora could not create the annotation canvas.');\n }\n return context;\n}\n\nconst surface = requireElement('.capture-surface');\nconst status = requireElement('.status');\nconst copyFeedback = requireElement('.copy-feedback');\nconst copyFeedbackText = requireElement('.copy-feedback-text');\nconst screenFrame = requireElement<HTMLImageElement>('.screen-frame');\nconst screenMask = requireElement('.screen-mask');\nconst annotationCanvas = requireElement<HTMLCanvasElement>('.annotation-canvas');\nconst annotationContext = requireCanvasContext(annotationCanvas);\nconst selectionElement = requireElement('.selection');\nconst sizeHint = requireElement<HTMLOutputElement>('.size-hint');\nconst toolbar = requireElement('.selection-toolbar');\nconst textEditor = requireElement<HTMLTextAreaElement>('.text-editor');\nconst cancelButton = requireElement<HTMLButtonElement>('.cancel-button');\nconst saveButton = requireElement<HTMLButtonElement>('.save-button');\nconst confirmButton = requireElement<HTMLButtonElement>('.confirm-button');\nconst undoButton = requireElement<HTMLButtonElement>('.undo-button');\nconst redoButton = requireElement<HTMLButtonElement>('.redo-button');\nconst colorInput = requireElement<HTMLInputElement>('.color-input');\nconst lineWidthSelect = requireElement<HTMLSelectElement>('.line-width-select');\nconst fontSizeSelect = requireElement<HTMLSelectElement>('.font-size-select');\nconst colorControl = requireElement<HTMLElement>('.color-control');\nconst lineControl = requireElement<HTMLElement>('.line-control');\nconst fontControl = requireElement<HTMLElement>('.font-control');\nconst toolGroup = requireElement<HTMLElement>('.tool-group');\nconst historyGroup = requireElement<HTMLElement>('.history-group');\nconst styleGroup = requireElement<HTMLElement>('.style-group');\nconst actionGroup = requireElement<HTMLElement>('.action-group');\nconst toolButtons = Array.from(\n document.querySelectorAll<HTMLButtonElement>('[data-tool]')\n);\n\nconst selectionStore = createOverlayStore();\nconst annotationStore = createAnnotationStore();\nlet pointerInteraction: PointerInteraction | null = null;\nlet resetAnnotationsAfterSelection = true;\nlet configuredDefaultTool: AnnotationTool = 'select';\nlet pendingTextPoint: Point | null = null;\nlet outputFeedback: string | null = null;\nlet exportProgressVisible = false;\nlet exportProgressTimer: number | undefined;\nlet currentMessages: ScreenshotMessages = resolveScreenshotMessages();\n\nconst EXPORT_PROGRESS_DELAY_MS = 180;\n\n/** 捕获帧加载完成后才开放选区和标注,确保三套坐标使用同一实际图片尺寸。 */\nfunction initializeOverlay(payload: ScreenshotInitializePayload): void {\n const frame = payload.frames[0];\n if (!frame) {\n window.snaporaOverlay.reportError({\n jobId: payload.jobId,\n code: 'CAPTURE_FAILED',\n message: 'The screenshot overlay received no captured frame.',\n });\n return;\n }\n\n configuredDefaultTool = payload.options.defaultTool ?? 'select';\n selectionStore.dispatch({ type: 'initialize', payload });\n applyTheme(payload.options);\n applyLocale(payload.options);\n applyToolAvailability(payload.options.tools);\n screenFrame.onload = async () => {\n annotationCanvas.width = frame.pixelSize.width;\n annotationCanvas.height = frame.pixelSize.height;\n selectionStore.dispatch({ type: 'image-ready' });\n // 图片解码后保留两次合成机会,但共享一个截止时间,避免透明窗口被节流时串行等待。\n screenFrame.getBoundingClientRect();\n await waitForCompositeFrames();\n window.snaporaOverlay.prepared(payload.jobId);\n };\n screenFrame.onerror = () => {\n window.snaporaOverlay.reportError({\n jobId: payload.jobId,\n code: 'CAPTURE_FAILED',\n message: 'The captured screen image could not be loaded.',\n });\n };\n screenFrame.src = frame.dataUrl;\n}\n\nwindow.snaporaOverlay.onInitialize(initializeOverlay);\nwindow.snaporaOverlay.onFeedback((payload) => {\n if (payload.kind !== 'copy') {\n return;\n }\n clearExportProgress();\n applyTheme(payload.options);\n applyLocale(payload.options);\n document.documentElement.dataset.snaporaFeedback = 'copy';\n surface.dataset.state = 'copied';\n copyFeedbackText.textContent = localize('copied');\n copyFeedback.hidden = false;\n // 隐藏窗口先完成 Toast 合成再通知主进程显示,避免露出加载前的状态帧。\n void waitForCompositeFrames().then(() => window.snaporaOverlay.feedbackReady());\n});\nselectionStore.subscribe(render);\nannotationStore.subscribe(render);\n\nannotationCanvas.addEventListener('pointerdown', handleCanvasPointerDown);\nannotationCanvas.addEventListener('pointermove', handleCanvasPointerMove);\nannotationCanvas.addEventListener('pointerup', handleCanvasPointerEnd);\nannotationCanvas.addEventListener('pointercancel', handleCanvasPointerEnd);\nannotationCanvas.addEventListener('dblclick', handleCanvasDoubleClick);\n\nselectionElement.addEventListener('pointerdown', (event) => {\n if (event.button !== 0) {\n return;\n }\n const handle = (event.target as HTMLElement).dataset.handle as\n ResizeHandle | undefined;\n if (!handle || annotationStore.getState().activeTool !== 'select') {\n return;\n }\n\n event.stopPropagation();\n surface.setPointerCapture(event.pointerId);\n pointerInteraction = { kind: 'selection', pointerId: event.pointerId };\n selectionStore.dispatch({ type: 'begin-resize', pointerId: event.pointerId, handle });\n});\n\nsurface.addEventListener('pointermove', (event) => {\n if (pointerInteraction?.kind !== 'selection') {\n return;\n }\n selectionStore.dispatch({\n type: 'pointer-move',\n pointerId: event.pointerId,\n point: toSurfacePoint(event),\n bounds: getSurfaceBounds(),\n });\n});\nsurface.addEventListener('pointerup', endSelectionPointer);\nsurface.addEventListener('pointercancel', endSelectionPointer);\n\nfor (const button of toolButtons) {\n button.addEventListener('click', () => {\n const tool = button.dataset.tool as AnnotationTool;\n annotationStore.setTool(tool);\n });\n}\nundoButton.addEventListener('click', () => annotationStore.undo());\nredoButton.addEventListener('click', () => annotationStore.redo());\ncolorInput.addEventListener('input', () => {\n annotationStore.setStyle({ color: colorInput.value });\n});\ncolorInput.addEventListener('change', () => {\n commitSelectedElementStyle({ color: colorInput.value });\n});\nlineWidthSelect.addEventListener('change', () => {\n const lineWidth = Number(lineWidthSelect.value);\n annotationStore.setStyle({ lineWidth });\n const imageScale = getImageScale();\n commitSelectedElementStyle({ lineWidth: lineWidth * imageScale });\n});\nfontSizeSelect.addEventListener('change', () => {\n const fontSize = Number(fontSizeSelect.value);\n annotationStore.setStyle({ fontSize });\n commitSelectedElementStyle({ fontSize: fontSize * getImageScale() });\n});\ncancelButton.addEventListener('click', cancelCapture);\nconfirmButton.addEventListener('click', () => void confirmCapture());\nsaveButton.addEventListener('click', () => void confirmCapture('save'));\n\ntextEditor.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {\n event.stopPropagation();\n closeTextEditor(false);\n } else if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n event.stopPropagation();\n closeTextEditor(true);\n }\n});\ntextEditor.addEventListener('blur', () => closeTextEditor(true));\ntextEditor.addEventListener('input', resizeTextEditor);\n\nwindow.addEventListener('keydown', (event) => {\n if (!textEditor.hidden) {\n return;\n }\n const commandKey = event.ctrlKey || event.metaKey;\n if (commandKey && event.key.toLowerCase() === 'z') {\n event.preventDefault();\n if (event.shiftKey) {\n annotationStore.redo();\n } else {\n annotationStore.undo();\n }\n return;\n }\n if (commandKey && event.key.toLowerCase() === 'y') {\n event.preventDefault();\n annotationStore.redo();\n return;\n }\n if (commandKey && event.key.toLowerCase() === 'c') {\n event.preventDefault();\n void confirmCapture('copy');\n return;\n }\n if (commandKey && event.key.toLowerCase() === 's') {\n event.preventDefault();\n void confirmCapture('save');\n return;\n }\n if (!commandKey && !event.altKey) {\n const toolShortcuts: Partial<Record<string, AnnotationTool>> = {\n v: 'select',\n r: 'rectangle',\n o: 'ellipse',\n a: 'arrow',\n p: 'brush',\n t: 'text',\n m: 'mosaic',\n };\n const tool = toolShortcuts[event.key.toLowerCase()];\n const button = toolButtons.find(\n (candidate) => candidate.dataset.tool === tool && !candidate.hidden\n );\n if (tool && button) {\n event.preventDefault();\n annotationStore.setTool(tool);\n return;\n }\n }\n if (event.key === 'Delete' || event.key === 'Backspace') {\n event.preventDefault();\n annotationStore.deleteSelected();\n return;\n }\n if (event.key === 'Escape') {\n cancelCapture();\n } else if (event.key === 'Enter') {\n event.preventDefault();\n void confirmCapture();\n }\n});\nwindow.snaporaOverlay.ready();\n\nfunction handleCanvasPointerDown(event: PointerEvent): void {\n if (event.button !== 0 || selectionStore.getState().phase === 'waiting') {\n return;\n }\n // textarea 会被下一次文字点击复用,必须在清空并移动它之前提交当前内容。\n if (!textEditor.hidden) {\n closeTextEditor(true);\n }\n event.stopPropagation();\n annotationCanvas.setPointerCapture(event.pointerId);\n\n const viewportPoint = toSurfacePoint(event);\n const selection = selectionStore.getState().selection;\n if (!selection || !containsPoint(selection, viewportPoint)) {\n beginSelection(event.pointerId, viewportPoint);\n return;\n }\n\n const imagePoint = toImagePoint(viewportPoint);\n const annotationState = annotationStore.getState();\n if (annotationState.activeTool === 'select') {\n beginSelectInteraction(event.pointerId, imagePoint, viewportPoint);\n } else if (annotationState.activeTool === 'text') {\n // Canvas 的默认聚焦发生在 pointerdown 处理之后,会让刚打开的文字编辑框立即 blur。\n event.preventDefault();\n annotationCanvas.releasePointerCapture(event.pointerId);\n openTextEditor(viewportPoint, imagePoint);\n } else {\n beginDrawInteraction(event.pointerId, imagePoint, annotationState.activeTool);\n }\n}\n\nfunction handleCanvasPointerMove(event: PointerEvent): void {\n const interaction = pointerInteraction;\n if (!interaction || interaction.pointerId !== event.pointerId) {\n return;\n }\n const viewportPoint = toSurfacePoint(event);\n if (interaction.kind === 'selection') {\n selectionStore.dispatch({\n type: 'pointer-move',\n pointerId: event.pointerId,\n point: viewportPoint,\n bounds: getSurfaceBounds(),\n });\n return;\n }\n\n const annotationDocument = annotationStore.getState().document;\n if (!annotationDocument) {\n return;\n }\n const imagePoint = clampPoint(\n toImagePoint(viewportPoint),\n annotationDocument.selection\n );\n if (interaction.kind === 'draw') {\n const currentDraft = annotationStore.getState().draft;\n annotationStore.setDraft(\n updateDrawableElement(\n currentDraft && currentDraft.type !== 'text'\n ? currentDraft\n : interaction.element,\n interaction.origin,\n imagePoint\n )\n );\n } else if (interaction.kind === 'move-element') {\n annotationStore.preview(\n translateElement(\n interaction.before,\n {\n x: imagePoint.x - interaction.origin.x,\n y: imagePoint.y - interaction.origin.y,\n },\n annotationDocument.selection\n )\n );\n } else {\n const nextBounds = resizeSelection(\n getElementBounds(interaction.before),\n interaction.handle,\n imagePoint,\n annotationDocument.selection,\n 8\n );\n annotationStore.preview(scaleElementToBounds(interaction.before, nextBounds));\n }\n}\n\nfunction handleCanvasPointerEnd(event: PointerEvent): void {\n const interaction = pointerInteraction;\n if (!interaction || interaction.pointerId !== event.pointerId) {\n return;\n }\n\n if (interaction.kind === 'selection') {\n finishSelection(event.pointerId);\n } else if (interaction.kind === 'draw') {\n const draft = annotationStore.getState().draft;\n if (draft && isDrawableElementValid(draft)) {\n annotationStore.commitDraft(draft.type !== 'mosaic' && draft.type !== 'brush');\n } else {\n annotationStore.setDraft(null);\n }\n } else {\n const preview = annotationStore.getState().preview;\n if (preview) {\n annotationStore.commitUpdate(interaction.before, preview);\n }\n }\n pointerInteraction = null;\n if (annotationCanvas.hasPointerCapture(event.pointerId)) {\n annotationCanvas.releasePointerCapture(event.pointerId);\n }\n}\n\nfunction handleCanvasDoubleClick(event: MouseEvent): void {\n if (event.button !== 0) {\n return;\n }\n\n const state = selectionStore.getState();\n if (\n state.phase !== 'selected' ||\n !state.selection ||\n !containsPoint(state.selection, toSurfacePoint(event))\n ) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n void confirmCapture('copy');\n}\n\nfunction beginSelection(pointerId: number, point: Point): void {\n resetAnnotationsAfterSelection = true;\n pointerInteraction = { kind: 'selection', pointerId };\n selectionStore.dispatch({\n type: 'begin-create',\n pointerId,\n point,\n bounds: getSurfaceBounds(),\n });\n}\n\nfunction beginSelectInteraction(\n pointerId: number,\n imagePoint: Point,\n viewportPoint: Point\n): void {\n const state = annotationStore.getState();\n const elements = getRenderableElements(state);\n const selected = elements.find((element) => element.id === state.selectedElementId);\n const tolerance = getImageScale() * 8;\n const handle = selected\n ? getResizeHandleAtPoint(selected, imagePoint, tolerance)\n : undefined;\n if (selected && handle) {\n pointerInteraction = {\n kind: 'resize-element',\n pointerId,\n before: selected,\n handle,\n };\n return;\n }\n\n const hit = hitTestElement(elements, imagePoint, tolerance);\n if (hit) {\n annotationStore.select(hit.id);\n pointerInteraction = {\n kind: 'move-element',\n pointerId,\n origin: imagePoint,\n before: hit,\n };\n return;\n }\n\n annotationStore.select(null);\n selectionStore.dispatch({ type: 'begin-move', pointerId, point: viewportPoint });\n pointerInteraction = { kind: 'selection', pointerId };\n resetAnnotationsAfterSelection = false;\n}\n\nfunction beginDrawInteraction(\n pointerId: number,\n imagePoint: Point,\n tool: ScreenshotTool\n): void {\n if (tool === 'text') {\n return;\n }\n const state = annotationStore.getState();\n const imageScale = getImageScale();\n const element = createDrawableElement(\n tool,\n imagePoint,\n {\n ...state.style,\n lineWidth: state.style.lineWidth * imageScale,\n fontSize: state.style.fontSize * imageScale,\n },\n {\n id: crypto.randomUUID(),\n zIndex: getNextZIndex(),\n createdAt: Date.now(),\n }\n );\n annotationStore.select(null);\n annotationStore.setDraft(element);\n pointerInteraction = { kind: 'draw', pointerId, origin: imagePoint, element };\n}\n\nfunction endSelectionPointer(event: PointerEvent): void {\n if (pointerInteraction?.kind !== 'selection') {\n return;\n }\n finishSelection(event.pointerId);\n pointerInteraction = null;\n if (surface.hasPointerCapture(event.pointerId)) {\n surface.releasePointerCapture(event.pointerId);\n }\n}\n\nfunction finishSelection(pointerId: number): void {\n selectionStore.dispatch({ type: 'end-interaction', pointerId });\n const selection = selectionStore.getState().selection;\n const frame = selectionStore.getState().payload?.frames[0];\n if (!selection || !frame) {\n return;\n }\n const imageSelection = viewportRectToImageRect(\n selection,\n getSurfaceSize(),\n frame.pixelSize\n );\n if (resetAnnotationsAfterSelection || !annotationStore.getState().document) {\n annotationStore.initialize(imageSelection, configuredDefaultTool);\n } else {\n annotationStore.setSelection(imageSelection);\n }\n resetAnnotationsAfterSelection = false;\n}\n\nfunction openTextEditor(viewportPoint: Point, imagePoint: Point): void {\n pendingTextPoint = imagePoint;\n textEditor.value = '';\n textEditor.hidden = false;\n textEditor.style.transform = `translate(${viewportPoint.x}px, ${viewportPoint.y}px)`;\n textEditor.style.color = annotationStore.getState().style.color;\n textEditor.style.fontSize = `${Math.max(\n 14,\n annotationStore.getState().style.fontSize\n )}px`;\n resizeTextEditor();\n textEditor.focus();\n}\n\nfunction resizeTextEditor(): void {\n textEditor.style.height = 'auto';\n const borderHeight = textEditor.offsetHeight - textEditor.clientHeight;\n textEditor.style.height = `${Math.max(textEditor.scrollHeight + borderHeight, 42)}px`;\n}\n\nfunction closeTextEditor(commit: boolean): void {\n if (textEditor.hidden) {\n return;\n }\n const value = textEditor.value.trim();\n if (commit && value && pendingTextPoint) {\n const state = annotationStore.getState();\n const imageScale = getImageScale();\n const fontSize = state.style.fontSize * imageScale;\n const metrics = measureTextLayout(annotationContext, value, fontSize);\n const baselineMetrics = measureTextBaselineMetrics(annotationContext, fontSize);\n const editorStyle = window.getComputedStyle(textEditor);\n // textarea 的点击坐标指向外框左上角;提交时转换到内容区的真实文字基线。\n const contentOffset = {\n x:\n (parseCssPixels(editorStyle.borderLeftWidth) +\n parseCssPixels(editorStyle.paddingLeft)) *\n imageScale,\n y:\n (parseCssPixels(editorStyle.borderTopWidth) +\n parseCssPixels(editorStyle.paddingTop)) *\n imageScale,\n };\n const measuredLineHeight = parseCssPixels(editorStyle.lineHeight) * imageScale;\n const position = calculateTextBaselinePosition(\n pendingTextPoint,\n baselineMetrics,\n contentOffset,\n measuredLineHeight || fontSize * TEXT_LINE_HEIGHT\n );\n const element: TextElement = {\n id: crypto.randomUUID(),\n type: 'text',\n zIndex: getNextZIndex(),\n createdAt: Date.now(),\n color: state.style.color,\n position,\n value,\n fontSize,\n metrics,\n };\n annotationStore.setDraft(element);\n annotationStore.commitDraft(false);\n }\n pendingTextPoint = null;\n textEditor.hidden = true;\n textEditor.value = '';\n}\n\nfunction parseCssPixels(value: string): number {\n const parsed = Number.parseFloat(value);\n return Number.isFinite(parsed) ? parsed : 0;\n}\n\nfunction cancelCapture(): void {\n const jobId = selectionStore.getState().payload?.jobId;\n if (jobId) {\n window.snaporaOverlay.cancel(jobId);\n }\n}\n\nasync function confirmCapture(outputAction: 'save' | 'copy' = 'copy'): Promise<void> {\n const state = selectionStore.getState();\n const frame = state.payload?.frames[0];\n if (!state.payload || !frame || !state.selection || state.phase !== 'selected') {\n return;\n }\n\n outputFeedback = null;\n clearExportProgress();\n selectionStore.dispatch({ type: 'begin-export' });\n scheduleExportProgress();\n try {\n const viewportSize = getSurfaceSize();\n const imageRect = viewportRectToImageRect(\n state.selection,\n viewportSize,\n frame.pixelSize\n );\n const screenBounds = viewportRectToScreenRect(\n state.selection,\n viewportSize,\n frame.display.bounds\n );\n const elements = annotationStore.getState().document?.elements ?? [];\n const data = await exportSelectionPng(\n screenFrame,\n imageRect,\n elements,\n frame.pixelSize\n );\n\n const result = {\n status: 'completed' as const,\n data,\n mimeType: 'image/png' as const,\n bounds: screenBounds,\n displayId: frame.display.id,\n };\n const response = await window.snaporaOverlay.output({\n jobId: state.payload.jobId,\n action: outputAction,\n result,\n });\n if (response.status !== 'completed') {\n clearExportProgress();\n selectionStore.dispatch({ type: 'export-failed' });\n outputFeedback =\n response.status === 'cancelled' ? localize('saveCancelled') : response.message;\n render();\n return;\n }\n\n const output =\n response.action === 'save'\n ? { action: 'save' as const, filePath: response.filePath }\n : { action: 'copy' as const };\n clearExportProgress();\n window.snaporaOverlay.confirm({\n jobId: state.payload.jobId,\n result: { ...result, output },\n });\n } catch (error) {\n clearExportProgress();\n selectionStore.dispatch({ type: 'export-failed' });\n window.snaporaOverlay.reportError({\n jobId: state.payload.jobId,\n code: 'EXPORT_FAILED',\n message: error instanceof Error ? error.message : 'Screenshot export failed.',\n });\n }\n}\n\n/** 快速复制不显示瞬时 loading,只有导出确实耗时时才呈现进度。 */\nfunction scheduleExportProgress(): void {\n exportProgressTimer = window.setTimeout(() => {\n exportProgressTimer = undefined;\n if (selectionStore.getState().phase === 'exporting') {\n exportProgressVisible = true;\n render();\n }\n }, EXPORT_PROGRESS_DELAY_MS);\n}\n\nfunction clearExportProgress(): void {\n if (exportProgressTimer !== undefined) {\n window.clearTimeout(exportProgressTimer);\n exportProgressTimer = undefined;\n }\n exportProgressVisible = false;\n}\n\nfunction render(): void {\n const selectionState = selectionStore.getState();\n const annotationState = annotationStore.getState();\n const selection = selectionState.selection;\n surface.dataset.state = selectionState.phase;\n surface.dataset.tool = annotationState.activeTool;\n const selectedElement = annotationState.document?.elements.find(\n (element) => element.id === annotationState.selectedElementId\n );\n if (selectedElement) {\n surface.dataset.selectedType = selectedElement.type;\n } else {\n delete surface.dataset.selectedType;\n }\n screenMask.hidden = selection !== null;\n selectionElement.hidden = selection === null;\n toolbar.hidden = selectionState.phase !== 'selected';\n\n const showPhaseStatus =\n selectionState.phase === 'waiting' ||\n selectionState.phase === 'ready' ||\n (selectionState.phase === 'exporting' && exportProgressVisible);\n status.hidden = !showPhaseStatus && !outputFeedback;\n if (selectionState.phase === 'waiting') {\n status.textContent = localize('preparing');\n } else if (selectionState.phase === 'ready') {\n status.textContent = localize('instruction');\n } else if (selectionState.phase === 'exporting') {\n status.textContent = localize('exporting');\n } else if (outputFeedback) {\n status.textContent = outputFeedback;\n }\n\n if (selection) {\n setRectStyle(selectionElement, selection);\n const frame = selectionState.payload?.frames[0];\n const imageRect = frame\n ? viewportRectToImageRect(selection, getSurfaceSize(), frame.pixelSize)\n : selection;\n sizeHint.value = `${imageRect.width} × ${imageRect.height}`;\n if (!toolbar.hidden) {\n positionToolbar(selection);\n }\n }\n\n for (const button of toolButtons) {\n const active = button.dataset.tool === annotationState.activeTool;\n button.dataset.active = String(active);\n button.setAttribute('aria-pressed', String(active));\n }\n undoButton.disabled = !annotationState.canUndo;\n redoButton.disabled = !annotationState.canRedo;\n renderAnnotationCanvas();\n}\n\nfunction renderAnnotationCanvas(): void {\n annotationContext.clearRect(0, 0, annotationCanvas.width, annotationCanvas.height);\n const frame = selectionStore.getState().payload?.frames[0];\n const state = annotationStore.getState();\n if (!frame || !state.document) {\n return;\n }\n drawAnnotations(annotationContext, getRenderableElements(state), {\n clipBounds: state.document.selection,\n imageSize: frame.pixelSize,\n mosaicSource: screenFrame,\n draftElementId: state.draft?.id ?? null,\n selectedElementId: state.selectedElementId,\n selectionHandleSize: getImageScale() * 8,\n });\n}\n\nfunction positionToolbar(selection: Rect): void {\n const toolbarSize: Size = {\n width: toolbar.offsetWidth,\n height: toolbar.offsetHeight,\n };\n const position = calculateToolbarPosition(selection, getSurfaceSize(), toolbarSize);\n toolbar.style.transform = `translate(${position.x}px, ${position.y}px)`;\n toolbar.dataset.placement = position.placement;\n}\n\nfunction setRectStyle(element: HTMLElement, rect: Rect): void {\n element.style.transform = `translate(${rect.x}px, ${rect.y}px)`;\n element.style.width = `${rect.width}px`;\n element.style.height = `${rect.height}px`;\n}\n\nfunction toSurfacePoint(event: MouseEvent): Point {\n const bounds = surface.getBoundingClientRect();\n return { x: event.clientX - bounds.left, y: event.clientY - bounds.top };\n}\n\nfunction toImagePoint(point: Point): Point {\n const frame = selectionStore.getState().payload?.frames[0];\n return frame\n ? viewportPointToImagePoint(point, getSurfaceSize(), frame.pixelSize)\n : point;\n}\n\nfunction getImageScale(): number {\n const frame = selectionStore.getState().payload?.frames[0];\n return frame ? frame.pixelSize.width / Math.max(getSurfaceSize().width, 1) : 1;\n}\n\nfunction getSurfaceBounds(): Rect {\n return { x: 0, y: 0, ...getSurfaceSize() };\n}\n\nfunction getSurfaceSize(): Size {\n return { width: surface.clientWidth, height: surface.clientHeight };\n}\n\nfunction waitForCompositeFrames(frameCount = 2, maximumWaitMs = 48): Promise<void> {\n return new Promise((resolve) => {\n let settled = false;\n let remainingFrames = frameCount;\n const finish = (): void => {\n if (settled) {\n return;\n }\n settled = true;\n window.clearTimeout(timeoutId);\n resolve();\n };\n const handleFrame = (): void => {\n remainingFrames -= 1;\n if (remainingFrames <= 0) {\n finish();\n return;\n }\n requestAnimationFrame(handleFrame);\n };\n const timeoutId = window.setTimeout(finish, maximumWaitMs);\n requestAnimationFrame(handleFrame);\n });\n}\n\nfunction containsPoint(rect: Rect, point: Point): boolean {\n return (\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height\n );\n}\n\nfunction getNextZIndex(): number {\n const elements = annotationStore.getState().document?.elements ?? [];\n return (\n elements.reduce((maximum, element) => Math.max(maximum, element.zIndex), -1) + 1\n );\n}\n\nfunction commitSelectedElementStyle(style: AnnotationElementStyle): void {\n const state = annotationStore.getState();\n const selected = state.document?.elements.find(\n (element) => element.id === state.selectedElementId\n );\n if (!selected) {\n return;\n }\n\n const updated = updateElementStyle(selected, style);\n if (updated !== selected) {\n annotationStore.commitUpdate(selected, updated);\n }\n}\n\nfunction applyToolAvailability(tools: ScreenshotTool[] | undefined): void {\n const enabled = new Set(\n tools ?? ['rectangle', 'ellipse', 'arrow', 'brush', 'text', 'mosaic']\n );\n for (const button of toolButtons) {\n const tool = button.dataset.tool as AnnotationTool;\n button.hidden = tool !== 'select' && !enabled.has(tool as ScreenshotTool);\n }\n}\n\nfunction applyTheme(options: ScreenshotOptions): void {\n const theme = resolveScreenshotTheme(options.theme);\n document.documentElement.dataset.snaporaTheme = theme.mode;\n for (const [token, value] of Object.entries(theme.tokens)) {\n setColorToken(token, value);\n }\n}\n\nfunction setColorToken(token: string, value: string | undefined): void {\n if (value && CSS.supports('color', value)) {\n document.documentElement.style.setProperty(token, value);\n }\n}\n\nfunction applyLocale(options: ScreenshotOptions): void {\n const locale = options.locale ?? 'en-US';\n currentMessages = resolveScreenshotMessages(locale, options.messages);\n const localized = currentMessages;\n const toolLabels: Record<AnnotationTool, string> = {\n select: localized.select,\n rectangle: localized.rectangle,\n ellipse: localized.ellipse,\n arrow: localized.arrow,\n brush: localized.brush,\n text: localized.text,\n mosaic: localized.mosaic,\n };\n document.documentElement.lang = locale;\n for (const button of toolButtons) {\n setControlLabel(button, toolLabels[button.dataset.tool as AnnotationTool]);\n }\n setControlLabel(undoButton, localized.undo);\n setControlLabel(redoButton, localized.redo);\n setControlLabel(saveButton, localized.save);\n setControlLabel(cancelButton, localized.cancel);\n setControlLabel(confirmButton, localized.confirm);\n setControlLabel(colorControl, localized.color);\n setControlLabel(lineControl, localized.lineWidth);\n setControlLabel(fontControl, localized.fontSize);\n annotationCanvas.setAttribute('aria-label', localized.annotationCanvas);\n selectionElement.setAttribute('aria-label', localized.selection);\n toolbar.setAttribute('aria-label', localized.actions);\n toolGroup.setAttribute('aria-label', localized.annotationTools);\n historyGroup.setAttribute('aria-label', localized.history);\n styleGroup.setAttribute('aria-label', localized.annotationStyle);\n actionGroup.setAttribute('aria-label', localized.outputActions);\n textEditor.setAttribute('aria-label', localized.annotationText);\n colorInput.setAttribute('aria-label', localized.color);\n lineWidthSelect.setAttribute('aria-label', localized.lineWidth);\n fontSizeSelect.setAttribute('aria-label', localized.fontSize);\n}\n\nfunction setControlLabel(element: HTMLElement, label: string): void {\n element.dataset.tooltip = label;\n element.setAttribute('aria-label', label);\n}\n\nfunction localize(\n key: 'preparing' | 'instruction' | 'exporting' | 'copied' | 'saveCancelled'\n): string {\n return currentMessages[key];\n}\n"],"names":["normalizeRect","start","end","isRectValid","rect","minimumSize","viewportPointToImagePoint","point","viewportSize","imageSize","TEXT_LINE_HEIGHT","calculateTextBaselinePosition","editorOrigin","metrics","contentOffset","lineHeight","fontBoxHeight","leadingBeforeBaseline","measureTextBaselineMetrics","context","fontSize","previousFont","getTextCanvasFont","positiveMetric","values","value","splitTextLines","measureTextLayout","lineMetrics","line","referenceMetrics","createDrawableElement","tool","style","identity","base","updateDrawableElement","element","origin","shouldAppendPoint","isDrawableElementValid","distance","getElementBounds","paddedBounds","lines","updateElementStyle","color","lineWidth","scale","scaleTextMetrics","hitTestElement","elements","tolerance","left","right","isPointNearElement","getResizeHandleAtPoint","handles","getResizeHandlePoints","handlePoint","bounds","centerX","centerY","bottom","translateElement","delta","elementBounds","minimumX","maximumX","minimumY","maximumY","boundedDelta","addPoint","scaleElementToBounds","nextBounds","previousBounds","mapPoint","actualScale","points","current","index","next","distanceToSegment","padding","xValues","yValues","top","previous","lengthSquared","ratio","MOSAIC_BLOCK_SIZE","drawAnnotations","options","drawElement","draft","drawDraftOutline","selected","drawSelectionOutline","drawArrow","drawPolyline","drawMosaic","startX","startY","endX","endY","angle","headLength","first","source","sourceX","sourceY","sourceRight","sourceBottom","sourceWidth","sourceHeight","sampleWidth","sampleHeight","sampleCanvas","createRasterCanvas","sampleContext","handleSize","width","height","canvas","CommandStack","#undoStack","#redoStack","command","document","nextDocument","previousDocument","AddElementCommand","#element","UpdateElementCommand","#before","#after","before","after","replaceElement","RemoveElementCommand","#index","replacement","found","defaultStyle","createAnnotationStore","history","listeners","state","update","patch","listener","updateDocument","selection","activeTool","select","selectedElementId","preview","getRenderableElements","exportSelectionPng","imageRect","drawSelection","blob","resolve","reject","DEFAULT_SCREENSHOT_LOCALE","ENGLISH_MESSAGES","LOCALE_MESSAGES","THEME_TOKEN_MAP","resolveScreenshotTheme","theme","tokens","key","token","resolveScreenshotMessages","locale","overrides","clampPoint","createSelection","boundedStart","boundedEnd","moveSelection","resizeSelection","handle","boundedPoint","viewportRectToImageRect","assertPositiveSize","scaleX","scaleY","viewportRectToScreenRect","displayBounds","calculateToolbarPosition","toolbarSize","gap","edgePadding","x","belowY","aboveY","size","label","MINIMUM_SELECTION_SIZE","initialOverlayState","createOverlayStore","initialState","action","nextState","reduceOverlayState","updatePointerInteraction","pointerId","interaction","requireElement","selector","requireCanvasContext","surface","status","copyFeedback","copyFeedbackText","screenFrame","screenMask","annotationCanvas","annotationContext","selectionElement","sizeHint","toolbar","textEditor","cancelButton","saveButton","confirmButton","undoButton","redoButton","colorInput","lineWidthSelect","fontSizeSelect","colorControl","lineControl","fontControl","toolGroup","historyGroup","styleGroup","actionGroup","toolButtons","selectionStore","annotationStore","pointerInteraction","resetAnnotationsAfterSelection","configuredDefaultTool","pendingTextPoint","outputFeedback","exportProgressVisible","exportProgressTimer","currentMessages","EXPORT_PROGRESS_DELAY_MS","initializeOverlay","payload","frame","applyTheme","applyLocale","applyToolAvailability","waitForCompositeFrames","clearExportProgress","localize","render","handleCanvasPointerDown","handleCanvasPointerMove","handleCanvasPointerEnd","handleCanvasDoubleClick","event","toSurfacePoint","getSurfaceBounds","endSelectionPointer","button","commitSelectedElementStyle","imageScale","getImageScale","cancelCapture","confirmCapture","closeTextEditor","resizeTextEditor","commandKey","candidate","viewportPoint","containsPoint","beginSelection","imagePoint","toImagePoint","annotationState","beginSelectInteraction","openTextEditor","beginDrawInteraction","annotationDocument","currentDraft","finishSelection","hit","getNextZIndex","imageSelection","getSurfaceSize","borderHeight","commit","baselineMetrics","editorStyle","parseCssPixels","measuredLineHeight","position","parsed","jobId","outputAction","scheduleExportProgress","screenBounds","result","response","output","error","selectionState","selectedElement","showPhaseStatus","setRectStyle","positionToolbar","active","renderAnnotationCanvas","frameCount","maximumWaitMs","settled","remainingFrames","finish","timeoutId","handleFrame","maximum","updated","tools","enabled","setColorToken","localized","toolLabels","setControlLabel"],"mappings":"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"}
|