fix snapshot export metadata

This commit is contained in:
2026-03-29 20:23:38 -07:00
parent 2846dbc3af
commit dc0d01b8aa
7 changed files with 45 additions and 3 deletions

View File

@@ -1,5 +1,7 @@
import React, { useRef, useState, useCallback } from 'react';
export const CAPTURE_SELECTOR = '.angle-overlay';
import {
getAngleLabelBasePosition,
getAngleLabelPosition,

View File

@@ -1,5 +1,7 @@
import React, { useRef, useState, useCallback } from 'react';
export const CAPTURE_SELECTOR = '.crop-overlay';
export default function CropBoxOverlay({
image, x1, y1, x2, y2,
aLocked, bLocked,

View File

@@ -1,5 +1,7 @@
import React, { useRef, useState, useCallback } from 'react';
export const CAPTURE_SELECTOR = '.cs-overlay';
/**
* Image preview with two endpoint markers for cross-section line control.
* Markers are draggable when unlocked (no COORD input connected),

View File

@@ -1,9 +1,18 @@
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { getAxisScale } from './valueFormatting';
export const CAPTURE_SELECTOR = '.lineplot-overlay';
const ASPECT_RATIO = 3.2 / 2.2;
const MARGINS = { top: 18, right: 16, bottom: 34, left: 56 };
// Hardcoded marker colors so SVG elements render correctly in canvas exports,
// where CSS custom properties (var(--marker) etc.) are not resolved.
const MARKER_FILL = '#ffd700';
const MARKER_STROKE = '#ffffff';
const MARKER_LOCKED_COLOR = '#e91e63';
const MARKER_LABEL_FILL = '#0f172a';
function clamp(v, min, max) {
return Math.max(min, Math.min(max, v));
}
@@ -263,6 +272,8 @@ export default function LinePlotOverlay({
cy={cursorA.y}
r={markerRadius}
className={`lineplot-marker ${aLocked ? 'lineplot-marker-locked' : ''}`}
fill={aLocked ? MARKER_LOCKED_COLOR : MARKER_FILL}
stroke={aLocked ? MARKER_LOCKED_COLOR : MARKER_STROKE}
/>
<text
x={cursorA.x}
@@ -271,6 +282,7 @@ export default function LinePlotOverlay({
dominantBaseline="middle"
fontSize={markerLabelSize}
className="lineplot-marker-label"
fill={MARKER_LABEL_FILL}
pointerEvents="none"
>
A
@@ -282,6 +294,8 @@ export default function LinePlotOverlay({
cy={cursorB.y}
r={markerRadius}
className={`lineplot-marker ${bLocked ? 'lineplot-marker-locked' : ''}`}
fill={bLocked ? MARKER_LOCKED_COLOR : MARKER_FILL}
stroke={bLocked ? MARKER_LOCKED_COLOR : MARKER_STROKE}
/>
<text
x={cursorB.x}
@@ -290,6 +304,7 @@ export default function LinePlotOverlay({
dominantBaseline="middle"
fontSize={markerLabelSize}
className="lineplot-marker-label"
fill={MARKER_LABEL_FILL}
pointerEvents="none"
>
B

View File

@@ -1,4 +1,6 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
export const CAPTURE_SELECTOR = '.markup-overlay';
import {
getArrowGeometry,
MARKUP_DEFAULT_COLOR,

View File

@@ -1,9 +1,18 @@
import React, { useEffect, useRef, useState, useCallback } from 'react';
import { getAxisScale } from './valueFormatting';
export const CAPTURE_SELECTOR = '.lineplot-overlay';
const ASPECT_RATIO = 3.2 / 2.2;
const MARGINS = { top: 18, right: 16, bottom: 34, left: 56 };
// Hardcoded marker colors so SVG elements render correctly in canvas exports,
// where CSS custom properties (var(--marker) etc.) are not resolved.
const MARKER_FILL = '#ffd700';
const MARKER_STROKE = '#ffffff';
const MARKER_LOCKED_COLOR = '#e91e63';
const MARKER_LABEL_FILL = '#0f172a';
function clamp(v, min, max) { return Math.max(min, Math.min(max, v)); }
function round4(v) { return parseFloat(v.toFixed(4)); }
function trimZeros(t) { return t.replace(/(?:\.0+|(\.\d+?)0+)$/, '$1'); }
@@ -201,6 +210,8 @@ export default function ThresholdHistogram({ overlay, threshold, thresholdConnec
cy={markerY}
r={markerRadius}
className={`lineplot-marker ${locked ? 'lineplot-marker-locked' : ''}`}
fill={locked ? MARKER_LOCKED_COLOR : MARKER_FILL}
stroke={locked ? MARKER_LOCKED_COLOR : MARKER_STROKE}
/>
<text
x={markerX}
@@ -209,6 +220,7 @@ export default function ThresholdHistogram({ overlay, threshold, thresholdConnec
dominantBaseline="middle"
fontSize={markerLabelSize}
className="lineplot-marker-label"
fill={MARKER_LABEL_FILL}
pointerEvents="none"
>
T

View File

@@ -1,10 +1,17 @@
import { toBlob } from 'html-to-image';
import { CANVAS_COLORS } from './constants.js';
import { CAPTURE_SELECTOR as linePlotSelector } from './LinePlotOverlay';
import { CAPTURE_SELECTOR as thresholdSelector } from './ThresholdHistogram';
import { CAPTURE_SELECTOR as csSelector } from './CrossSectionOverlay';
import { CAPTURE_SELECTOR as cropSelector } from './CropBoxOverlay';
import { CAPTURE_SELECTOR as markupSelector } from './MarkupOverlay';
import { CAPTURE_SELECTOR as angleSelector } from './AngleMeasureOverlay';
// Assembled from each overlay component's CAPTURE_SELECTOR export.
// To register a new overlay: export CAPTURE_SELECTOR from its file and add
// an import + entry here. Missing entries produce corrupt ~68-byte PNG output.
export const OVERLAY_CAPTURE_SELECTORS = [
'.lineplot-overlay',
'.cs-overlay',
'.crop-overlay',
...new Set([linePlotSelector, thresholdSelector, csSelector, cropSelector, markupSelector, angleSelector]),
];
function encodeBase64(bytes) {