Module: shapeImport

Pure helpers used by the "Import shapes" pipeline to translate parsed vector shapes (see module:svgImport) into the data the scene objects expect.

Constructing scene objects, pushing them onto the scene graph, and refreshing the simulator stay in app.js; this module builds the payloads (prepareImportedPaths, buildImportedObjectSpecs) those steps consume.

Source:

Methods

(static) adjustColorForBackground(color, background, contrastThresholdopt)

If the stroke color's luminance is too close to the background's to stay visible, blend the RGB toward white (dark theme) or toward black (light theme) until luminance separation exceeds the threshold. Unlike rgb → 1-rgb inversion, this preserves hue — only lightness moves.

Parameters:
Name Type Attributes Default Description
color Object | null
background Object | null
contrastThreshold number <optional>
0.2
Source:

(static) boundingBoxFromImportedSpecs(specs) → {Object|null}

Bounding box of geometry described by imported specs (mirrors scene-object bbox logic used for handle placement).

Parameters:
Name Type Description
specs Array.<{type: string, props: Object}>
Source:
Returns:
Type
Object | null

(static) buildCurvePoints(start, segments, closed)

Build the points array expected by CurveObjMixin from a parsed path whose arcs have already been flattened to L / C segments.

Each entry has the shape {a1, c1, c2} where a1 is the anchor and c1/c2 are the two outgoing control points leading to the next anchor. Open curves append a trailing {a1} (no outgoing controls).

Straight L segments are expressed as cubics with collinear control points so the resulting curve stays exactly a line.

For a closed path:

  • If the last segment already returns to the starting anchor, we drop the redundant entry (the mixin closes the loop implicitly).
  • Otherwise we append a straight wrap-around segment.
Parameters:
Name Type Description
start Object
segments Array.<{type: ('L'|'C'), c1: *, c2: *, end: *}>
closed boolean
Source:

(static) buildImportedObjectSpecs(simplifiedPaths, opts) → {Array.<{type: string, props: Object}>}

Turn simplified scene-space paths into constructor payloads for scene objects.

Parameters:
Name Type Description
simplifiedPaths Array

Output of prepareImportedPaths.

opts Object
Source:
Returns:
Type
Array.<{type: string, props: Object}>

(static) collectShapeColors(paths) → {Object}

Collect the distinct stroke / fill color keys used by a list of parsed paths, keeping an exemplar {r, g, b, a} for each so the UI can show a proper swatch and (later) apply reversal if needed. Fill colors are only collected for closed paths, since open paths don't receive a fill in the importer.

Entries are sorted by usage count, most-used first. Ties keep their insertion order (i.e. the order in which colors were first seen).

Parameters:
Name Type Description
paths Array.<{stroke: any, fill: any, closed: boolean}>
Source:
Returns:
Type
Object

(static) colorToKey(color) → {string|null}

Compute a stable RGB hex key for a color object (alpha is intentionally ignored: the user groups paths by RGB only).

Parameters:
Name Type Description
color Object | null
Source:
Returns:
Type
string | null

(static) computeImportPlacement(bbox, viewport) → {Object}

Given the imported SVG bounding box and the current viewport metrics, derive {scale, offsetX, offsetY} that centers the imported geometry in the visible viewport and has it occupy roughly fillRatio of the shorter viewport dimension. Mirrors how the observer and the crop box initialize themselves.

The caller is responsible for feeding in the current viewport width / height / origin / scale (this keeps the helper fully pure).

Parameters:
Name Type Description
bbox Object | null
viewport Object
Source:
Returns:
Type
Object

(static) computeImportShapesDefaults(paths, viewport) → {Object}

Scale / offset defaults for the import modal from parsed paths and viewport metrics (same math as before in app.js, without reading window or scene).

Parameters:
Name Type Description
paths Array

Parsed paths (pre-placement SVG space).

viewport Object
Source:
Returns:
Type
Object

(static) importedHandleOffsetBelowBBox(scene)

Vertical gap from the bottom of the imported bbox to the handle anchor (p1.y). Uses twice the scene-space “handle radius” implied by the theme — same scaling as Handle#checkMouseOver: (handleArrow.size / 24) * 20 * scene.lengthScale.

Parameters:
Name Type Description
scene Object | null
Source:

(static) prepareImportedPaths(paths, opts)

Placement, arc flattening, and cubic merge — same order as the live import.

Parameters:
Name Type Description
paths Array

Parsed paths from module:svgImport.parseShapesFile.

opts Object
Source:

(static) relativeLuminance()

Relative luminance per ITU-R BT.709 of a normalized RGB color.

Source:

(static) transformPathToScene(path, opts)

Apply the affine {scale, offsetX, offsetY} chosen in the import modal to a parsed path, returning a new path in scene coordinates.

  • Line (L) and cubic (C) segments are simply mapped point-wise.
  • Elliptical arc (A) segments survive exactly: the 2×2 shape matrix scales with the uniform factor, and the center / endpoint are mapped with the full affine. No flattening happens here — the caller should run module:svgImport.flattenArcSegments afterwards with the desired scene-space tolerance.
Parameters:
Name Type Description
path ParsedPath
opts Object
Source:

(inner) mixRgbToward()

Linear RGB mix toward target; hue is preserved compared to photographic inversion.

Source: