supervision 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +11 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1158 -97
- package/dist/index.js.map +1 -1
- package/dist/mask-preparation.worker.js +43 -9
- package/dist/mask-preparation.worker.js.map +1 -1
- package/dist/render-preparation/mask-frame-artifact.d.ts +6 -0
- package/dist/render-preparation/mask-frame-artifact.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-compositor.d.ts +1 -0
- package/dist/render-preparation/mask-frame-compositor.d.ts.map +1 -1
- package/dist/render-preparation/mask-frame-preparer.d.ts.map +1 -1
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts +1 -0
- package/dist/render-preparation/mask-preparation-worker-protocol.d.ts.map +1 -1
- package/dist/renderers/annotation-shape-styles.d.ts +17 -0
- package/dist/renderers/annotation-shape-styles.d.ts.map +1 -0
- package/dist/renderers/media-renderer-core.d.ts.map +1 -1
- package/dist/renderers/media-renderer-scene.d.ts +17 -2
- package/dist/renderers/media-renderer-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-annotation-overlay-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-focus-layer.d.ts +1 -0
- package/dist/renderers/pixi-focus-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-layer.d.ts +2 -0
- package/dist/renderers/pixi-interaction-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-interaction-presentation-layer.d.ts +2 -1
- package/dist/renderers/pixi-interaction-presentation-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-mask-halo.d.ts +94 -0
- package/dist/renderers/pixi-mask-halo.d.ts.map +1 -0
- package/dist/renderers/pixi-mask-layer.d.ts +10 -1
- package/dist/renderers/pixi-mask-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-media-scene.d.ts.map +1 -1
- package/dist/renderers/pixi-path.d.ts +13 -7
- package/dist/renderers/pixi-path.d.ts.map +1 -1
- package/dist/renderers/pixi-polygon-layer.d.ts.map +1 -1
- package/dist/renderers/pixi-region-layer.d.ts +42 -0
- package/dist/renderers/pixi-region-layer.d.ts.map +1 -0
- package/dist/renderers/pixi-scene-layer-slot.d.ts +1 -0
- package/dist/renderers/pixi-scene-layer-slot.d.ts.map +1 -1
- package/dist/renderers/pixi-vector-layer.d.ts +3 -1
- package/dist/renderers/pixi-vector-layer.d.ts.map +1 -1
- package/dist/sessions/media-session.d.ts.map +1 -1
- package/dist/types/media-renderer.d.ts +1 -1
- package/dist/types/media-renderer.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.d.ts +17 -3
- package/node_modules/supervision-js-core/dist/index.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/index.js +708 -74
- package/node_modules/supervision-js-core/dist/index.js.map +1 -1
- package/node_modules/supervision-js-core/dist/interactions/detection-picker.d.ts +18 -0
- package/node_modules/supervision-js-core/dist/interactions/detection-picker.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/annotation-renderer-presentation.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/annotation-renderer-registry.d.ts +13 -6
- package/node_modules/supervision-js-core/dist/styles/annotation-renderer-registry.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/box-corner-style.d.ts +14 -0
- package/node_modules/supervision-js-core/dist/styles/box-corner-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/styles/box-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/default-annotation-presentation.d.ts +19 -0
- package/node_modules/supervision-js-core/dist/styles/default-annotation-presentation.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/interaction-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/keypoint-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/marker-style.d.ts +14 -0
- package/node_modules/supervision-js-core/dist/styles/marker-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/styles/polygon-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/polyline-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/source-presentation.d.ts +8 -0
- package/node_modules/supervision-js-core/dist/styles/source-presentation.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/styles/stroke-style.d.ts +12 -0
- package/node_modules/supervision-js-core/dist/styles/stroke-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts +124 -4
- package/node_modules/supervision-js-core/dist/types/annotation-renderer.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/box-corner-style.d.ts +31 -0
- package/node_modules/supervision-js-core/dist/types/box-corner-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/box-style.d.ts +4 -17
- package/node_modules/supervision-js-core/dist/types/box-style.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/ellipse-style.d.ts +30 -0
- package/node_modules/supervision-js-core/dist/types/ellipse-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/interaction.d.ts +12 -0
- package/node_modules/supervision-js-core/dist/types/interaction.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/marker-style.d.ts +46 -0
- package/node_modules/supervision-js-core/dist/types/marker-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/mask-halo-style.d.ts +29 -0
- package/node_modules/supervision-js-core/dist/types/mask-halo-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts +18 -2
- package/node_modules/supervision-js-core/dist/types/media-rendering.d.ts.map +1 -1
- package/node_modules/supervision-js-core/dist/types/paint-style.d.ts +36 -0
- package/node_modules/supervision-js-core/dist/types/paint-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/types/shape-style.d.ts +112 -0
- package/node_modules/supervision-js-core/dist/types/shape-style.d.ts.map +1 -0
- package/node_modules/supervision-js-core/dist/utils/shape-geometry.d.ts +50 -0
- package/node_modules/supervision-js-core/dist/utils/shape-geometry.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -1928,6 +1928,29 @@ function createDetectionPickKey(pick) {
|
|
|
1928
1928
|
pick.geometryIndex ?? "geometry",
|
|
1929
1929
|
].join(":");
|
|
1930
1930
|
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Compares the frame-independent membership of two ordered selections.
|
|
1933
|
+
*
|
|
1934
|
+
* Detection ids retain their runtime type, so numeric `1` and string `"1"`
|
|
1935
|
+
* remain distinct identities. Anonymous detections keep their frame-local
|
|
1936
|
+
* index identity.
|
|
1937
|
+
*/
|
|
1938
|
+
function haveSameDetectionPickIdentities(current, next) {
|
|
1939
|
+
if (current.length !== next.length) {
|
|
1940
|
+
return false;
|
|
1941
|
+
}
|
|
1942
|
+
return current.every((pick, index) => {
|
|
1943
|
+
const nextPick = next[index];
|
|
1944
|
+
if (!nextPick) {
|
|
1945
|
+
return false;
|
|
1946
|
+
}
|
|
1947
|
+
const id = pick.detection.id;
|
|
1948
|
+
const nextId = nextPick.detection.id;
|
|
1949
|
+
return id === undefined || nextId === undefined
|
|
1950
|
+
? id === nextId && pick.detectionIndex === nextPick.detectionIndex
|
|
1951
|
+
: typeof id === typeof nextId && id === nextId;
|
|
1952
|
+
});
|
|
1953
|
+
}
|
|
1931
1954
|
function rebaseDetectionPickToFrame(pick, frame) {
|
|
1932
1955
|
if (!pick || !frame) {
|
|
1933
1956
|
return null;
|
|
@@ -1953,13 +1976,55 @@ function rebaseDetectionPickToFrame(pick, frame) {
|
|
|
1953
1976
|
? rebasedPick
|
|
1954
1977
|
: null;
|
|
1955
1978
|
}
|
|
1979
|
+
/**
|
|
1980
|
+
* Carries a pick forward onto a different frame of the same timeline.
|
|
1981
|
+
*
|
|
1982
|
+
* Same-frame rebases behave exactly like `rebaseDetectionPickToFrame`. Across
|
|
1983
|
+
* frames, the pick follows its detection only when the detection id is defined
|
|
1984
|
+
* and unique in both frames, so anonymous and duplicate-id detections keep the
|
|
1985
|
+
* per-frame lifetime they have today. Returns `null` when the detection has no
|
|
1986
|
+
* followable identity or has left the frame.
|
|
1987
|
+
*/
|
|
1988
|
+
function followDetectionPickAcrossFrames(pick, frame) {
|
|
1989
|
+
const rebasedPick = rebaseDetectionPickToFrame(pick, frame);
|
|
1990
|
+
if (rebasedPick || !pick || !frame) {
|
|
1991
|
+
return rebasedPick;
|
|
1992
|
+
}
|
|
1993
|
+
const id = pick.detection.id;
|
|
1994
|
+
if (id === undefined ||
|
|
1995
|
+
!hasUniqueDetectionId(pick.frame, id) ||
|
|
1996
|
+
!hasUniqueDetectionId(frame, id)) {
|
|
1997
|
+
return null;
|
|
1998
|
+
}
|
|
1999
|
+
const detectionIndex = frame.detections.findIndex((detection) => detection.id === id);
|
|
2000
|
+
const detection = frame.detections[detectionIndex];
|
|
2001
|
+
if (!detection) {
|
|
2002
|
+
return null;
|
|
2003
|
+
}
|
|
2004
|
+
return {
|
|
2005
|
+
detection,
|
|
2006
|
+
detectionIndex,
|
|
2007
|
+
frame,
|
|
2008
|
+
geometryIndex: pick.geometryIndex,
|
|
2009
|
+
mediaTime: frame.mediaTime,
|
|
2010
|
+
point: pick.point,
|
|
2011
|
+
target: pick.target,
|
|
2012
|
+
};
|
|
2013
|
+
}
|
|
1956
2014
|
function detectionPickKey(pick) {
|
|
1957
2015
|
if (pick.detection.id === undefined) {
|
|
1958
2016
|
return ["anonymous", pick.detectionIndex];
|
|
1959
2017
|
}
|
|
2018
|
+
const idType = typeof pick.detection.id;
|
|
1960
2019
|
return hasUniqueDetectionId(pick.frame, pick.detection.id)
|
|
1961
|
-
? ["id", String(pick.detection.id)]
|
|
1962
|
-
: [
|
|
2020
|
+
? ["id", idType, String(pick.detection.id)]
|
|
2021
|
+
: [
|
|
2022
|
+
"duplicate-id",
|
|
2023
|
+
idType,
|
|
2024
|
+
String(pick.detection.id),
|
|
2025
|
+
"index",
|
|
2026
|
+
pick.detectionIndex,
|
|
2027
|
+
];
|
|
1963
2028
|
}
|
|
1964
2029
|
function hasUniqueDetectionId(frame, id) {
|
|
1965
2030
|
let count = 0;
|
|
@@ -2652,17 +2717,46 @@ function resolveStyleValue(value, detection, context) {
|
|
|
2652
2717
|
: value;
|
|
2653
2718
|
}
|
|
2654
2719
|
|
|
2720
|
+
/**
|
|
2721
|
+
* Resolves the renderer-neutral stroke contract without dropping optional
|
|
2722
|
+
* geometry controls as styles move from public configuration to draw
|
|
2723
|
+
* instructions.
|
|
2724
|
+
*
|
|
2725
|
+
* Keep this as the single normalization point for every built-in style. That
|
|
2726
|
+
* makes additions to `StrokeStyle` deliberate instead of relying on each style
|
|
2727
|
+
* implementation to copy a growing property list correctly.
|
|
2728
|
+
*/
|
|
2729
|
+
function resolveStrokeStyle(stroke, defaults) {
|
|
2730
|
+
const alignment = stroke?.alignment ?? defaults.alignment;
|
|
2731
|
+
const cap = stroke?.cap ?? defaults.cap;
|
|
2732
|
+
const dash = stroke?.dash ?? defaults.dash;
|
|
2733
|
+
const join = stroke?.join ?? defaults.join;
|
|
2734
|
+
const miterLimit = stroke?.miterLimit ?? defaults.miterLimit;
|
|
2735
|
+
return {
|
|
2736
|
+
alpha: stroke?.alpha ?? defaults.alpha,
|
|
2737
|
+
color: stroke?.color ?? defaults.color,
|
|
2738
|
+
width: stroke?.width ?? defaults.width,
|
|
2739
|
+
...(alignment === undefined ? {} : { alignment }),
|
|
2740
|
+
...(cap === undefined ? {} : { cap }),
|
|
2741
|
+
...(dash === undefined ? {} : { dash }),
|
|
2742
|
+
...(join === undefined ? {} : { join }),
|
|
2743
|
+
...(miterLimit === undefined ? {} : { miterLimit }),
|
|
2744
|
+
};
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
/** Alignment for strokes applied to closed rendered geometry. */
|
|
2748
|
+
var StrokeAlignment;
|
|
2749
|
+
(function (StrokeAlignment) {
|
|
2750
|
+
StrokeAlignment["Inside"] = "inside";
|
|
2751
|
+
StrokeAlignment["Center"] = "center";
|
|
2752
|
+
StrokeAlignment["Outside"] = "outside";
|
|
2753
|
+
})(StrokeAlignment || (StrokeAlignment = {}));
|
|
2754
|
+
|
|
2655
2755
|
var BoxShape;
|
|
2656
2756
|
(function (BoxShape) {
|
|
2657
2757
|
BoxShape["Rect"] = "rect";
|
|
2658
2758
|
BoxShape["RoundedRect"] = "roundedRect";
|
|
2659
2759
|
})(BoxShape || (BoxShape = {}));
|
|
2660
|
-
var BoxStrokeAlignment;
|
|
2661
|
-
(function (BoxStrokeAlignment) {
|
|
2662
|
-
BoxStrokeAlignment["Inside"] = "inside";
|
|
2663
|
-
BoxStrokeAlignment["Center"] = "center";
|
|
2664
|
-
BoxStrokeAlignment["Outside"] = "outside";
|
|
2665
|
-
})(BoxStrokeAlignment || (BoxStrokeAlignment = {}));
|
|
2666
2760
|
|
|
2667
2761
|
const DEFAULT_BOX_STROKE_ALPHA = 1;
|
|
2668
2762
|
const DEFAULT_BOX_STROKE_COLOR = 0x00ff66;
|
|
@@ -2716,22 +2810,12 @@ class BaseBoxStyle {
|
|
|
2716
2810
|
if (stroke === null) {
|
|
2717
2811
|
return undefined;
|
|
2718
2812
|
}
|
|
2719
|
-
|
|
2720
|
-
alpha:
|
|
2721
|
-
color:
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
...resolvedStroke,
|
|
2726
|
-
...(stroke?.alignment === undefined
|
|
2727
|
-
? {}
|
|
2728
|
-
: { alignment: stroke.alignment }),
|
|
2729
|
-
...(stroke?.dash === undefined
|
|
2730
|
-
? context.ephemeral
|
|
2731
|
-
? { dash: [6, 4] }
|
|
2732
|
-
: {}
|
|
2733
|
-
: { dash: stroke.dash }),
|
|
2734
|
-
};
|
|
2813
|
+
return resolveStrokeStyle(stroke, {
|
|
2814
|
+
alpha: DEFAULT_BOX_STROKE_ALPHA,
|
|
2815
|
+
color: DEFAULT_BOX_STROKE_COLOR,
|
|
2816
|
+
...(context.ephemeral ? { dash: [6, 4] } : {}),
|
|
2817
|
+
width: DEFAULT_BOX_STROKE_WIDTH,
|
|
2818
|
+
});
|
|
2735
2819
|
}
|
|
2736
2820
|
resolveFill(detection, context) {
|
|
2737
2821
|
const fill = resolveStyleValue(this.options.fill, detection, context);
|
|
@@ -2745,6 +2829,83 @@ class BaseBoxStyle {
|
|
|
2745
2829
|
}
|
|
2746
2830
|
}
|
|
2747
2831
|
|
|
2832
|
+
const DEFAULT_CORNER_LENGTH = 20;
|
|
2833
|
+
const DEFAULT_CORNER_STROKE = {
|
|
2834
|
+
alpha: 1,
|
|
2835
|
+
cap: "round",
|
|
2836
|
+
color: 0x00ff66,
|
|
2837
|
+
join: "round",
|
|
2838
|
+
width: 2,
|
|
2839
|
+
};
|
|
2840
|
+
/**
|
|
2841
|
+
* Configurable four-corner decoration derived from a detection rectangle.
|
|
2842
|
+
*
|
|
2843
|
+
* This is the BoxCornerAnnotator-style facade: it keeps the rectangle semantic
|
|
2844
|
+
* and draws only its four open corner segments.
|
|
2845
|
+
*/
|
|
2846
|
+
class BaseBoxCornerStyle {
|
|
2847
|
+
options;
|
|
2848
|
+
constructor(options = {}) {
|
|
2849
|
+
this.options = options;
|
|
2850
|
+
}
|
|
2851
|
+
resolve(detection, context) {
|
|
2852
|
+
if (!detection.rect ||
|
|
2853
|
+
context.hidden ||
|
|
2854
|
+
this.options.shouldRender?.(detection, context) === false) {
|
|
2855
|
+
return undefined;
|
|
2856
|
+
}
|
|
2857
|
+
const resolvedLength = resolveStyleValue(this.options.length, detection, context) ??
|
|
2858
|
+
DEFAULT_CORNER_LENGTH;
|
|
2859
|
+
const viewportScale = context.viewportScale && context.viewportScale > 0
|
|
2860
|
+
? context.viewportScale
|
|
2861
|
+
: 1;
|
|
2862
|
+
const length = Math.min(Math.max(0, resolvedLength / viewportScale), detection.rect.width / 2, detection.rect.height / 2);
|
|
2863
|
+
const stroke = resolveStyleValue(this.options.stroke, detection, context);
|
|
2864
|
+
if (length <= 0 || stroke === null)
|
|
2865
|
+
return undefined;
|
|
2866
|
+
const { height, width, x, y } = detection.rect;
|
|
2867
|
+
const left = x - width / 2;
|
|
2868
|
+
const right = x + width / 2;
|
|
2869
|
+
const top = y - height / 2;
|
|
2870
|
+
const bottom = y + height / 2;
|
|
2871
|
+
const resolvedStroke = resolveStrokeStyle(stroke, DEFAULT_CORNER_STROKE);
|
|
2872
|
+
const openStroke = {
|
|
2873
|
+
alpha: resolvedStroke.alpha,
|
|
2874
|
+
cap: resolvedStroke.cap,
|
|
2875
|
+
color: resolvedStroke.color,
|
|
2876
|
+
dash: resolvedStroke.dash,
|
|
2877
|
+
join: resolvedStroke.join,
|
|
2878
|
+
miterLimit: resolvedStroke.miterLimit,
|
|
2879
|
+
width: resolvedStroke.width,
|
|
2880
|
+
};
|
|
2881
|
+
return {
|
|
2882
|
+
segments: [
|
|
2883
|
+
[
|
|
2884
|
+
{ x: left + length, y: top },
|
|
2885
|
+
{ x: left, y: top },
|
|
2886
|
+
{ x: left, y: top + length },
|
|
2887
|
+
],
|
|
2888
|
+
[
|
|
2889
|
+
{ x: right - length, y: top },
|
|
2890
|
+
{ x: right, y: top },
|
|
2891
|
+
{ x: right, y: top + length },
|
|
2892
|
+
],
|
|
2893
|
+
[
|
|
2894
|
+
{ x: left + length, y: bottom },
|
|
2895
|
+
{ x: left, y: bottom },
|
|
2896
|
+
{ x: left, y: bottom - length },
|
|
2897
|
+
],
|
|
2898
|
+
[
|
|
2899
|
+
{ x: right - length, y: bottom },
|
|
2900
|
+
{ x: right, y: bottom },
|
|
2901
|
+
{ x: right, y: bottom - length },
|
|
2902
|
+
],
|
|
2903
|
+
],
|
|
2904
|
+
stroke: openStroke,
|
|
2905
|
+
};
|
|
2906
|
+
}
|
|
2907
|
+
}
|
|
2908
|
+
|
|
2748
2909
|
var FocusTargetMode;
|
|
2749
2910
|
(function (FocusTargetMode) {
|
|
2750
2911
|
FocusTargetMode["Hovered"] = "hovered";
|
|
@@ -2943,18 +3104,11 @@ class BaseInteractionStyle {
|
|
|
2943
3104
|
return undefined;
|
|
2944
3105
|
}
|
|
2945
3106
|
const defaults = getStateDefaults(context.state);
|
|
2946
|
-
|
|
2947
|
-
alpha:
|
|
2948
|
-
color:
|
|
2949
|
-
width:
|
|
2950
|
-
};
|
|
2951
|
-
if (stroke?.alignment !== undefined) {
|
|
2952
|
-
return {
|
|
2953
|
-
...resolvedStroke,
|
|
2954
|
-
alignment: stroke.alignment,
|
|
2955
|
-
};
|
|
2956
|
-
}
|
|
2957
|
-
return resolvedStroke;
|
|
3107
|
+
return resolveStrokeStyle(stroke, {
|
|
3108
|
+
alpha: defaults.strokeAlpha,
|
|
3109
|
+
color: defaults.strokeColor,
|
|
3110
|
+
width: defaults.strokeWidth,
|
|
3111
|
+
});
|
|
2958
3112
|
}
|
|
2959
3113
|
resolveFill(detection, context) {
|
|
2960
3114
|
const fill = resolveStyleValue(this.options.fill, detection, context);
|
|
@@ -3206,6 +3360,115 @@ function createArtifactKey(options) {
|
|
|
3206
3360
|
return `base:${color}:${fillAlpha}:${mode}:${serializeStroke(resolveStroke(options.stroke, color, mode))}`;
|
|
3207
3361
|
}
|
|
3208
3362
|
|
|
3363
|
+
/**
|
|
3364
|
+
* Discriminator for renderer-neutral shape draw instructions.
|
|
3365
|
+
*/
|
|
3366
|
+
var ShapeInstructionKind;
|
|
3367
|
+
(function (ShapeInstructionKind) {
|
|
3368
|
+
ShapeInstructionKind["Ellipse"] = "ellipse";
|
|
3369
|
+
ShapeInstructionKind["Marker"] = "marker";
|
|
3370
|
+
ShapeInstructionKind["Path"] = "path";
|
|
3371
|
+
})(ShapeInstructionKind || (ShapeInstructionKind = {}));
|
|
3372
|
+
var MarkerShape;
|
|
3373
|
+
(function (MarkerShape) {
|
|
3374
|
+
MarkerShape["Circle"] = "circle";
|
|
3375
|
+
MarkerShape["Cross"] = "cross";
|
|
3376
|
+
MarkerShape["Square"] = "square";
|
|
3377
|
+
MarkerShape["Triangle"] = "triangle";
|
|
3378
|
+
})(MarkerShape || (MarkerShape = {}));
|
|
3379
|
+
/**
|
|
3380
|
+
* Coordinate space for marker sizing. Media sizes scale with the viewport;
|
|
3381
|
+
* screen sizes stay constant on screen, matching stroke-width semantics.
|
|
3382
|
+
*/
|
|
3383
|
+
var MarkerSizeSpace;
|
|
3384
|
+
(function (MarkerSizeSpace) {
|
|
3385
|
+
MarkerSizeSpace["Media"] = "media";
|
|
3386
|
+
MarkerSizeSpace["Screen"] = "screen";
|
|
3387
|
+
})(MarkerSizeSpace || (MarkerSizeSpace = {}));
|
|
3388
|
+
|
|
3389
|
+
const DEFAULT_FILL = { alpha: 1, color: 0x00ff66 };
|
|
3390
|
+
const DEFAULT_STROKE = { alpha: 1, color: 0xffffff, width: 1 };
|
|
3391
|
+
const DEFAULT_SIZE = 12;
|
|
3392
|
+
/**
|
|
3393
|
+
* Configurable marker renderer style anchored to semantic detection geometry.
|
|
3394
|
+
*
|
|
3395
|
+
* Use `center` for any domain-specific anchor (keypoint, centroid, or custom
|
|
3396
|
+
* metadata). Without it, the marker lands at the detection rectangle center.
|
|
3397
|
+
*/
|
|
3398
|
+
class BaseMarkerStyle {
|
|
3399
|
+
options;
|
|
3400
|
+
constructor(options = {}) {
|
|
3401
|
+
this.options = options;
|
|
3402
|
+
}
|
|
3403
|
+
resolve(detection, context) {
|
|
3404
|
+
if (context.hidden ||
|
|
3405
|
+
this.options.shouldRender?.(detection, context) === false) {
|
|
3406
|
+
return undefined;
|
|
3407
|
+
}
|
|
3408
|
+
const center = resolveStyleValue(this.options.center, detection, context) ??
|
|
3409
|
+
(detection.rect
|
|
3410
|
+
? { x: detection.rect.x, y: detection.rect.y }
|
|
3411
|
+
: undefined);
|
|
3412
|
+
const shape = resolveStyleValue(this.options.shape, detection, context) ??
|
|
3413
|
+
MarkerShape.Circle;
|
|
3414
|
+
const size = resolveStyleValue(this.options.size, detection, context) ?? DEFAULT_SIZE;
|
|
3415
|
+
const sizeSpace = resolveStyleValue(this.options.sizeSpace, detection, context) ??
|
|
3416
|
+
MarkerSizeSpace.Screen;
|
|
3417
|
+
const rotation = resolveStyleValue(this.options.rotation, detection, context);
|
|
3418
|
+
const stroke = resolveStyleValue(this.options.stroke, detection, context);
|
|
3419
|
+
if (!center || !Number.isFinite(size) || size <= 0) {
|
|
3420
|
+
return undefined;
|
|
3421
|
+
}
|
|
3422
|
+
if (shape === MarkerShape.Cross) {
|
|
3423
|
+
if (stroke === null) {
|
|
3424
|
+
return undefined;
|
|
3425
|
+
}
|
|
3426
|
+
const resolvedStroke = resolveStrokeStyle(stroke, DEFAULT_STROKE);
|
|
3427
|
+
const openStroke = {
|
|
3428
|
+
alpha: resolvedStroke.alpha,
|
|
3429
|
+
cap: resolvedStroke.cap,
|
|
3430
|
+
color: resolvedStroke.color,
|
|
3431
|
+
dash: resolvedStroke.dash,
|
|
3432
|
+
join: resolvedStroke.join,
|
|
3433
|
+
miterLimit: resolvedStroke.miterLimit,
|
|
3434
|
+
width: resolvedStroke.width,
|
|
3435
|
+
};
|
|
3436
|
+
return {
|
|
3437
|
+
center,
|
|
3438
|
+
shape,
|
|
3439
|
+
size,
|
|
3440
|
+
sizeSpace,
|
|
3441
|
+
...(rotation === undefined ? {} : { rotation }),
|
|
3442
|
+
stroke: openStroke,
|
|
3443
|
+
};
|
|
3444
|
+
}
|
|
3445
|
+
const fill = resolveStyleValue(this.options.fill, detection, context);
|
|
3446
|
+
if (fill === null && stroke === null) {
|
|
3447
|
+
return undefined;
|
|
3448
|
+
}
|
|
3449
|
+
return {
|
|
3450
|
+
center,
|
|
3451
|
+
shape,
|
|
3452
|
+
size,
|
|
3453
|
+
sizeSpace,
|
|
3454
|
+
...(rotation === undefined ? {} : { rotation }),
|
|
3455
|
+
...(fill === null
|
|
3456
|
+
? {}
|
|
3457
|
+
: {
|
|
3458
|
+
fill: {
|
|
3459
|
+
alpha: fill?.alpha ?? DEFAULT_FILL.alpha,
|
|
3460
|
+
color: fill?.color ?? DEFAULT_FILL.color,
|
|
3461
|
+
},
|
|
3462
|
+
}),
|
|
3463
|
+
...(stroke === null
|
|
3464
|
+
? {}
|
|
3465
|
+
: stroke === undefined
|
|
3466
|
+
? { stroke: DEFAULT_STROKE }
|
|
3467
|
+
: { stroke: resolveStrokeStyle(stroke, DEFAULT_STROKE) }),
|
|
3468
|
+
};
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
|
|
3209
3472
|
class BasePolygonStyle {
|
|
3210
3473
|
options;
|
|
3211
3474
|
constructor(options = {}) {
|
|
@@ -3233,15 +3496,11 @@ class BasePolygonStyle {
|
|
|
3233
3496
|
...(stroke === null
|
|
3234
3497
|
? {}
|
|
3235
3498
|
: {
|
|
3236
|
-
stroke: {
|
|
3237
|
-
alpha:
|
|
3238
|
-
color:
|
|
3239
|
-
width:
|
|
3240
|
-
|
|
3241
|
-
? {}
|
|
3242
|
-
: { alignment: stroke.alignment }),
|
|
3243
|
-
...(stroke?.dash === undefined ? {} : { dash: stroke.dash }),
|
|
3244
|
-
},
|
|
3499
|
+
stroke: resolveStrokeStyle(stroke, {
|
|
3500
|
+
alpha: 1,
|
|
3501
|
+
color: 0x00ff66,
|
|
3502
|
+
width: 2,
|
|
3503
|
+
}),
|
|
3245
3504
|
}),
|
|
3246
3505
|
};
|
|
3247
3506
|
}
|
|
@@ -3265,15 +3524,11 @@ class BasePolylineStyle {
|
|
|
3265
3524
|
}
|
|
3266
3525
|
return {
|
|
3267
3526
|
points: detection.polyline.points,
|
|
3268
|
-
stroke: {
|
|
3269
|
-
alpha:
|
|
3270
|
-
color:
|
|
3271
|
-
width:
|
|
3272
|
-
|
|
3273
|
-
? {}
|
|
3274
|
-
: { alignment: stroke.alignment }),
|
|
3275
|
-
...(stroke?.dash === undefined ? {} : { dash: stroke.dash }),
|
|
3276
|
-
},
|
|
3527
|
+
stroke: resolveStrokeStyle(stroke, {
|
|
3528
|
+
alpha: 1,
|
|
3529
|
+
color: 0x00ff66,
|
|
3530
|
+
width: 2,
|
|
3531
|
+
}),
|
|
3277
3532
|
};
|
|
3278
3533
|
}
|
|
3279
3534
|
}
|
|
@@ -3307,19 +3562,21 @@ class BaseKeypointStyle {
|
|
|
3307
3562
|
const edges = geometry.edges.map(([fromIndex, toIndex], edgeIndex) => ({
|
|
3308
3563
|
from: geometry.points[fromIndex],
|
|
3309
3564
|
to: geometry.points[toIndex],
|
|
3310
|
-
stroke:
|
|
3311
|
-
|
|
3312
|
-
color: definition
|
|
3313
|
-
|
|
3314
|
-
|
|
3565
|
+
stroke: resolveStrokeStyle(definition?.edges[edgeIndex]?.color === undefined
|
|
3566
|
+
? edgeStroke
|
|
3567
|
+
: { ...edgeStroke, color: definition.edges[edgeIndex].color }, {
|
|
3568
|
+
alpha: 1,
|
|
3569
|
+
color: 0x00ff66,
|
|
3570
|
+
width: 2,
|
|
3571
|
+
}),
|
|
3315
3572
|
...(shadowStroke === null
|
|
3316
3573
|
? {}
|
|
3317
3574
|
: {
|
|
3318
|
-
shadowStroke: {
|
|
3319
|
-
alpha:
|
|
3320
|
-
color:
|
|
3321
|
-
width:
|
|
3322
|
-
},
|
|
3575
|
+
shadowStroke: resolveStrokeStyle(shadowStroke, {
|
|
3576
|
+
alpha: 0.65,
|
|
3577
|
+
color: 0x000000,
|
|
3578
|
+
width: 4,
|
|
3579
|
+
}),
|
|
3323
3580
|
}),
|
|
3324
3581
|
}));
|
|
3325
3582
|
const markers = geometry.points.flatMap((point, index) => {
|
|
@@ -3341,11 +3598,11 @@ class BaseKeypointStyle {
|
|
|
3341
3598
|
shape: visibility === KeypointVisibility.Occluded
|
|
3342
3599
|
? KeypointMarkerShape.Cross
|
|
3343
3600
|
: KeypointMarkerShape.Circle,
|
|
3344
|
-
stroke: {
|
|
3345
|
-
alpha:
|
|
3346
|
-
color:
|
|
3347
|
-
width:
|
|
3348
|
-
},
|
|
3601
|
+
stroke: resolveStrokeStyle(markerStroke, {
|
|
3602
|
+
alpha: 1,
|
|
3603
|
+
color: 0xffffff,
|
|
3604
|
+
width: 2,
|
|
3605
|
+
}),
|
|
3349
3606
|
},
|
|
3350
3607
|
];
|
|
3351
3608
|
});
|
|
@@ -3426,6 +3683,9 @@ function createClassColorStyle(fill, labelBackground, labelText, stroke) {
|
|
|
3426
3683
|
}
|
|
3427
3684
|
|
|
3428
3685
|
const DEFAULT_BOX_CORNER_RADIUS = 1;
|
|
3686
|
+
const DEFAULT_ELLIPSE_AXIS_RATIO = 0.35;
|
|
3687
|
+
const DEFAULT_ELLIPSE_START_ANGLE = (-45 * Math.PI) / 180;
|
|
3688
|
+
const DEFAULT_ELLIPSE_END_ANGLE = (235 * Math.PI) / 180;
|
|
3429
3689
|
const DEFAULT_OUTLINE_WIDTH = 2;
|
|
3430
3690
|
const DEFAULT_FILL_ALPHA = 0.08;
|
|
3431
3691
|
const DEFAULT_MASK_FILL_ALPHA = 0.45;
|
|
@@ -3480,6 +3740,47 @@ function createDefaultBoxStyle(options = {}) {
|
|
|
3480
3740
|
}),
|
|
3481
3741
|
});
|
|
3482
3742
|
}
|
|
3743
|
+
/** Canonical opt-in BoxCornerAnnotator-style presentation. */
|
|
3744
|
+
function createDefaultBoxCornerStyle(options = {}) {
|
|
3745
|
+
const getClassColor = createClassColorResolver(options);
|
|
3746
|
+
return new BaseBoxCornerStyle({
|
|
3747
|
+
stroke: (detection) => ({ color: getClassColor(detection) }),
|
|
3748
|
+
});
|
|
3749
|
+
}
|
|
3750
|
+
/**
|
|
3751
|
+
* Matches the Python Supervision EllipseAnnotator: an elliptical footprint
|
|
3752
|
+
* arc under the detection box, swept from -45deg to 235deg, in the class
|
|
3753
|
+
* color.
|
|
3754
|
+
*/
|
|
3755
|
+
function createDefaultEllipseStyle(options = {}) {
|
|
3756
|
+
const getClassColor = createClassColorResolver(options);
|
|
3757
|
+
return {
|
|
3758
|
+
resolve(detection, context) {
|
|
3759
|
+
if (!detection.rect || context.hidden) {
|
|
3760
|
+
return undefined;
|
|
3761
|
+
}
|
|
3762
|
+
const radiusX = detection.rect.width / 2;
|
|
3763
|
+
const radiusY = radiusX * DEFAULT_ELLIPSE_AXIS_RATIO;
|
|
3764
|
+
return {
|
|
3765
|
+
center: {
|
|
3766
|
+
x: detection.rect.x,
|
|
3767
|
+
// Bottom-tangent so the arc hugs the detection instead of dipping
|
|
3768
|
+
// below its feet.
|
|
3769
|
+
y: detection.rect.y + detection.rect.height / 2 - radiusY,
|
|
3770
|
+
},
|
|
3771
|
+
endAngle: DEFAULT_ELLIPSE_END_ANGLE,
|
|
3772
|
+
radiusX,
|
|
3773
|
+
radiusY,
|
|
3774
|
+
startAngle: DEFAULT_ELLIPSE_START_ANGLE,
|
|
3775
|
+
stroke: {
|
|
3776
|
+
alpha: 1,
|
|
3777
|
+
color: getClassColor(detection),
|
|
3778
|
+
width: DEFAULT_OUTLINE_WIDTH,
|
|
3779
|
+
},
|
|
3780
|
+
};
|
|
3781
|
+
},
|
|
3782
|
+
};
|
|
3783
|
+
}
|
|
3483
3784
|
function createDefaultKeypointStyle(options = {}) {
|
|
3484
3785
|
const getClassColor = createClassColorResolver(options);
|
|
3485
3786
|
return new BaseKeypointStyle({
|
|
@@ -3538,6 +3839,31 @@ function createDefaultMaskStyle(options = {}) {
|
|
|
3538
3839
|
}),
|
|
3539
3840
|
});
|
|
3540
3841
|
}
|
|
3842
|
+
/** Canonical opt-in marker presentation. */
|
|
3843
|
+
function createDefaultMarkerStyle() {
|
|
3844
|
+
return new BaseMarkerStyle();
|
|
3845
|
+
}
|
|
3846
|
+
const DEFAULT_MASK_HALO_ALPHA = 0.6;
|
|
3847
|
+
const DEFAULT_MASK_HALO_SPREAD = 12;
|
|
3848
|
+
/**
|
|
3849
|
+
* Canonical mask halo: a class-colored glow that follows the mask silhouette.
|
|
3850
|
+
* Used when the `maskHalo` renderer is listed without an explicit style.
|
|
3851
|
+
*/
|
|
3852
|
+
function createDefaultMaskHaloStyle(options = {}) {
|
|
3853
|
+
const getClassColor = createClassColorResolver(options);
|
|
3854
|
+
return {
|
|
3855
|
+
resolve(detection, context) {
|
|
3856
|
+
if (!detection.mask || context.hidden) {
|
|
3857
|
+
return undefined;
|
|
3858
|
+
}
|
|
3859
|
+
return {
|
|
3860
|
+
alpha: DEFAULT_MASK_HALO_ALPHA,
|
|
3861
|
+
color: getClassColor(detection),
|
|
3862
|
+
spread: DEFAULT_MASK_HALO_SPREAD,
|
|
3863
|
+
};
|
|
3864
|
+
},
|
|
3865
|
+
};
|
|
3866
|
+
}
|
|
3541
3867
|
function createDefaultPolygonStyle(options = {}) {
|
|
3542
3868
|
const getClassColor = createClassColorResolver(options);
|
|
3543
3869
|
return new BasePolygonStyle({
|
|
@@ -3580,12 +3906,30 @@ function resolveDefaultClassColor(detection, getClassColor) {
|
|
|
3580
3906
|
*/
|
|
3581
3907
|
const annotationRendererKinds = [
|
|
3582
3908
|
"box",
|
|
3909
|
+
"box-corners",
|
|
3910
|
+
"ellipse",
|
|
3583
3911
|
"keypoints",
|
|
3584
3912
|
"label",
|
|
3585
3913
|
"mask",
|
|
3914
|
+
"maskHalo",
|
|
3915
|
+
"marker",
|
|
3586
3916
|
"polygon",
|
|
3587
3917
|
"polyline",
|
|
3918
|
+
"region",
|
|
3588
3919
|
];
|
|
3920
|
+
/** Sources currently supported by a region renderer. */
|
|
3921
|
+
const RegionRendererSourceKind = {
|
|
3922
|
+
Asset: "asset",
|
|
3923
|
+
};
|
|
3924
|
+
/** Media-space regions currently supported by a region renderer. */
|
|
3925
|
+
const RegionRendererRegionKind = {
|
|
3926
|
+
Bounds: "bounds",
|
|
3927
|
+
KeypointAnchor: "keypoint-anchor",
|
|
3928
|
+
};
|
|
3929
|
+
/** Composition modes currently supported by a region renderer. */
|
|
3930
|
+
const RegionRendererComposeMode = {
|
|
3931
|
+
Over: "over",
|
|
3932
|
+
};
|
|
3589
3933
|
/**
|
|
3590
3934
|
* Creates built-in annotation renderer descriptors for
|
|
3591
3935
|
* `MediaRendererPresentation.renderers`.
|
|
@@ -3596,11 +3940,16 @@ const annotationRendererKinds = [
|
|
|
3596
3940
|
*/
|
|
3597
3941
|
const annotationRenderers = {
|
|
3598
3942
|
box: (options) => createAnnotationRenderer("box", options),
|
|
3943
|
+
boxCorners: (options) => createAnnotationRenderer("box-corners", options),
|
|
3944
|
+
ellipse: (options) => createAnnotationRenderer("ellipse", options),
|
|
3599
3945
|
keypoints: (options) => createAnnotationRenderer("keypoints", options),
|
|
3600
3946
|
label: (options) => createAnnotationRenderer("label", options),
|
|
3601
3947
|
mask: (options) => createAnnotationRenderer("mask", options),
|
|
3948
|
+
maskHalo: (options) => createAnnotationRenderer("maskHalo", options),
|
|
3949
|
+
marker: (options) => createAnnotationRenderer("marker", options),
|
|
3602
3950
|
polygon: (options) => createAnnotationRenderer("polygon", options),
|
|
3603
3951
|
polyline: (options) => createAnnotationRenderer("polyline", options),
|
|
3952
|
+
region: (options) => ({ kind: "region", ...options }),
|
|
3604
3953
|
};
|
|
3605
3954
|
function createAnnotationRenderer(kind, options) {
|
|
3606
3955
|
// Every built-in renderer keeps its kind as its stable id. TypeScript cannot
|
|
@@ -3610,31 +3959,67 @@ function createAnnotationRenderer(kind, options) {
|
|
|
3610
3959
|
}
|
|
3611
3960
|
|
|
3612
3961
|
const annotationRendererRegistry = {
|
|
3613
|
-
box: {
|
|
3962
|
+
box: {
|
|
3963
|
+
cardinality: "singleton",
|
|
3964
|
+
createCanonicalStyle: createDefaultBoxStyle,
|
|
3965
|
+
styleField: "boxStyle",
|
|
3966
|
+
},
|
|
3967
|
+
"box-corners": {
|
|
3968
|
+
cardinality: "singleton",
|
|
3969
|
+
createCanonicalStyle: createDefaultBoxCornerStyle,
|
|
3970
|
+
styleField: "boxCornerStyle",
|
|
3971
|
+
},
|
|
3972
|
+
ellipse: {
|
|
3973
|
+
cardinality: "singleton",
|
|
3974
|
+
createCanonicalStyle: createDefaultEllipseStyle,
|
|
3975
|
+
styleField: "ellipseStyle",
|
|
3976
|
+
},
|
|
3614
3977
|
keypoints: {
|
|
3978
|
+
cardinality: "singleton",
|
|
3615
3979
|
createCanonicalStyle: createDefaultKeypointStyle,
|
|
3616
3980
|
styleField: "keypointStyle",
|
|
3617
3981
|
},
|
|
3618
3982
|
label: {
|
|
3983
|
+
cardinality: "singleton",
|
|
3619
3984
|
createCanonicalStyle: createDefaultLabelStyle,
|
|
3620
3985
|
styleField: "labelStyle",
|
|
3621
3986
|
},
|
|
3622
3987
|
mask: {
|
|
3988
|
+
cardinality: "singleton",
|
|
3623
3989
|
createCanonicalStyle: createDefaultMaskStyle,
|
|
3624
3990
|
styleField: "maskStyle",
|
|
3625
3991
|
},
|
|
3992
|
+
maskHalo: {
|
|
3993
|
+
cardinality: "singleton",
|
|
3994
|
+
createCanonicalStyle: () => createDefaultMaskHaloStyle(),
|
|
3995
|
+
styleField: "maskHaloStyle",
|
|
3996
|
+
},
|
|
3997
|
+
marker: {
|
|
3998
|
+
cardinality: "singleton",
|
|
3999
|
+
createCanonicalStyle: createDefaultMarkerStyle,
|
|
4000
|
+
styleField: "markerStyle",
|
|
4001
|
+
},
|
|
3626
4002
|
polygon: {
|
|
4003
|
+
cardinality: "singleton",
|
|
3627
4004
|
createCanonicalStyle: createDefaultPolygonStyle,
|
|
3628
4005
|
styleField: "polygonStyle",
|
|
3629
4006
|
},
|
|
3630
4007
|
polyline: {
|
|
4008
|
+
cardinality: "singleton",
|
|
3631
4009
|
createCanonicalStyle: createDefaultPolylineStyle,
|
|
3632
4010
|
styleField: "polylineStyle",
|
|
3633
4011
|
},
|
|
4012
|
+
region: { cardinality: "multiple" },
|
|
3634
4013
|
};
|
|
4014
|
+
function isStyleBackedAnnotationRendererKind(kind) {
|
|
4015
|
+
return annotationRendererRegistry[kind].cardinality === "singleton";
|
|
4016
|
+
}
|
|
3635
4017
|
/** Presentation fields owned by the given renderer kinds, in the same order. */
|
|
3636
4018
|
function resolveAnnotationRendererStyleFields(kinds) {
|
|
3637
|
-
return kinds.
|
|
4019
|
+
return kinds.flatMap((kind) => {
|
|
4020
|
+
const metadata = annotationRendererRegistry[kind];
|
|
4021
|
+
return "styleField" in metadata ? [metadata.styleField] : [];
|
|
4022
|
+
});
|
|
3638
4023
|
}
|
|
3639
4024
|
|
|
3640
4025
|
/**
|
|
@@ -3650,9 +4035,13 @@ function resolveAnnotationRendererPresentation(presentation) {
|
|
|
3650
4035
|
}
|
|
3651
4036
|
const resolved = {
|
|
3652
4037
|
boxStyle: null,
|
|
4038
|
+
boxCornerStyle: null,
|
|
4039
|
+
ellipseStyle: null,
|
|
3653
4040
|
keypointStyle: null,
|
|
3654
4041
|
labelStyle: null,
|
|
4042
|
+
maskHaloStyle: null,
|
|
3655
4043
|
maskStyle: null,
|
|
4044
|
+
markerStyle: null,
|
|
3656
4045
|
polygonStyle: null,
|
|
3657
4046
|
polylineStyle: null,
|
|
3658
4047
|
};
|
|
@@ -3663,17 +4052,23 @@ function resolveAnnotationRendererPresentation(presentation) {
|
|
|
3663
4052
|
throw new RangeError(`MediaRendererPresentation.renderers contains duplicate renderer id "${renderer.id}".`);
|
|
3664
4053
|
}
|
|
3665
4054
|
rendererIds.add(renderer.id);
|
|
3666
|
-
if (
|
|
4055
|
+
if (annotationRendererRegistry[renderer.kind].cardinality === "singleton" &&
|
|
4056
|
+
rendererKinds.has(renderer.kind)) {
|
|
3667
4057
|
throw new RangeError(`MediaRendererPresentation.renderers contains duplicate renderer kind "${renderer.kind}".`);
|
|
3668
4058
|
}
|
|
3669
4059
|
rendererKinds.add(renderer.kind);
|
|
3670
|
-
|
|
4060
|
+
if (isStyleBackedAnnotationRenderer(renderer)) {
|
|
4061
|
+
applyRendererStyle(resolved, presentation, renderer);
|
|
4062
|
+
}
|
|
3671
4063
|
}
|
|
3672
4064
|
return {
|
|
3673
4065
|
...presentation,
|
|
3674
4066
|
...resolved,
|
|
3675
4067
|
};
|
|
3676
4068
|
}
|
|
4069
|
+
function isStyleBackedAnnotationRenderer(renderer) {
|
|
4070
|
+
return isStyleBackedAnnotationRendererKind(renderer.kind);
|
|
4071
|
+
}
|
|
3677
4072
|
function applyRendererStyle(resolved, configured, renderer) {
|
|
3678
4073
|
const { createCanonicalStyle, styleField } = annotationRendererRegistry[renderer.kind];
|
|
3679
4074
|
const configuredStyle = configured[styleField];
|
|
@@ -3703,12 +4098,24 @@ function createSourceAwarePresentation(globalPresentation = {}, sources, options
|
|
|
3703
4098
|
boxStyle: shouldApplySourceStyle("boxStyle")
|
|
3704
4099
|
? new SourceAwareBoxStyle(normalizeGlobalBoxStyle(globalPresentation.boxStyle), sourcePresentations)
|
|
3705
4100
|
: globalPresentation.boxStyle,
|
|
4101
|
+
boxCornerStyle: shouldApplySourceStyle("boxCornerStyle")
|
|
4102
|
+
? new SourceAwareBoxCornerStyle(globalPresentation.boxCornerStyle ?? null, sourcePresentations)
|
|
4103
|
+
: globalPresentation.boxCornerStyle,
|
|
4104
|
+
ellipseStyle: shouldApplySourceStyle("ellipseStyle")
|
|
4105
|
+
? new SourceAwareEllipseStyle(globalPresentation.ellipseStyle ?? null, sourcePresentations)
|
|
4106
|
+
: globalPresentation.ellipseStyle,
|
|
3706
4107
|
labelStyle: shouldApplySourceStyle("labelStyle")
|
|
3707
4108
|
? new SourceAwareLabelStyle(normalizeGlobalLabelStyle(globalPresentation.labelStyle), sourcePresentations)
|
|
3708
4109
|
: globalPresentation.labelStyle,
|
|
3709
4110
|
maskStyle: shouldApplySourceStyle("maskStyle")
|
|
3710
4111
|
? new SourceAwareMaskStyle(normalizeGlobalMaskStyle(globalPresentation.maskStyle), sourcePresentations)
|
|
3711
4112
|
: globalPresentation.maskStyle,
|
|
4113
|
+
markerStyle: shouldApplySourceStyle("markerStyle")
|
|
4114
|
+
? new SourceAwareMarkerStyle(normalizeGlobalMarkerStyle(globalPresentation.markerStyle), sourcePresentations)
|
|
4115
|
+
: globalPresentation.markerStyle,
|
|
4116
|
+
maskHaloStyle: shouldApplySourceStyle("maskHaloStyle")
|
|
4117
|
+
? new SourceAwareMaskHaloStyle(normalizeGlobalMaskHaloStyle(globalPresentation.maskHaloStyle), sourcePresentations)
|
|
4118
|
+
: globalPresentation.maskHaloStyle,
|
|
3712
4119
|
polygonStyle: shouldApplySourceStyle("polygonStyle")
|
|
3713
4120
|
? new SourceAwarePolygonStyle(normalizeGlobalPolygonStyle(globalPresentation.polygonStyle), sourcePresentations)
|
|
3714
4121
|
: globalPresentation.polygonStyle,
|
|
@@ -3720,6 +4127,17 @@ function createSourceAwarePresentation(globalPresentation = {}, sources, options
|
|
|
3720
4127
|
: globalPresentation.keypointStyle,
|
|
3721
4128
|
};
|
|
3722
4129
|
}
|
|
4130
|
+
class SourceAwareBoxCornerStyle {
|
|
4131
|
+
globalStyle;
|
|
4132
|
+
sourcePresentations;
|
|
4133
|
+
constructor(globalStyle, sourcePresentations) {
|
|
4134
|
+
this.globalStyle = globalStyle;
|
|
4135
|
+
this.sourcePresentations = sourcePresentations;
|
|
4136
|
+
}
|
|
4137
|
+
resolve(detection, context) {
|
|
4138
|
+
return resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, "boxCornerStyle")?.resolve(detection, context);
|
|
4139
|
+
}
|
|
4140
|
+
}
|
|
3723
4141
|
class SourceAwareBoxStyle {
|
|
3724
4142
|
globalStyle;
|
|
3725
4143
|
sourcePresentations;
|
|
@@ -3732,6 +4150,18 @@ class SourceAwareBoxStyle {
|
|
|
3732
4150
|
return style?.resolve(detection, context);
|
|
3733
4151
|
}
|
|
3734
4152
|
}
|
|
4153
|
+
class SourceAwareEllipseStyle {
|
|
4154
|
+
globalStyle;
|
|
4155
|
+
sourcePresentations;
|
|
4156
|
+
constructor(globalStyle, sourcePresentations) {
|
|
4157
|
+
this.globalStyle = globalStyle;
|
|
4158
|
+
this.sourcePresentations = sourcePresentations;
|
|
4159
|
+
}
|
|
4160
|
+
resolve(detection, context) {
|
|
4161
|
+
const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, "ellipseStyle");
|
|
4162
|
+
return style?.resolve(detection, context);
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
3735
4165
|
class SourceAwareLabelStyle {
|
|
3736
4166
|
globalStyle;
|
|
3737
4167
|
sourcePresentations;
|
|
@@ -3759,6 +4189,30 @@ class SourceAwareMaskStyle {
|
|
|
3759
4189
|
return style?.resolve(detection, context);
|
|
3760
4190
|
}
|
|
3761
4191
|
}
|
|
4192
|
+
class SourceAwareMaskHaloStyle {
|
|
4193
|
+
globalStyle;
|
|
4194
|
+
sourcePresentations;
|
|
4195
|
+
constructor(globalStyle, sourcePresentations) {
|
|
4196
|
+
this.globalStyle = globalStyle;
|
|
4197
|
+
this.sourcePresentations = sourcePresentations;
|
|
4198
|
+
}
|
|
4199
|
+
resolve(detection, context) {
|
|
4200
|
+
const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, "maskHaloStyle");
|
|
4201
|
+
return style?.resolve(detection, context);
|
|
4202
|
+
}
|
|
4203
|
+
}
|
|
4204
|
+
class SourceAwareMarkerStyle {
|
|
4205
|
+
globalStyle;
|
|
4206
|
+
sourcePresentations;
|
|
4207
|
+
constructor(globalStyle, sourcePresentations) {
|
|
4208
|
+
this.globalStyle = globalStyle;
|
|
4209
|
+
this.sourcePresentations = sourcePresentations;
|
|
4210
|
+
}
|
|
4211
|
+
resolve(detection, context) {
|
|
4212
|
+
const style = resolveSourceStyle(detection, this.globalStyle, this.sourcePresentations, "markerStyle");
|
|
4213
|
+
return style?.resolve(detection, context);
|
|
4214
|
+
}
|
|
4215
|
+
}
|
|
3762
4216
|
class SourceAwarePolygonStyle {
|
|
3763
4217
|
globalStyle;
|
|
3764
4218
|
sourcePresentations;
|
|
@@ -3814,6 +4268,12 @@ function normalizeGlobalLabelStyle(style) {
|
|
|
3814
4268
|
function normalizeGlobalMaskStyle(style) {
|
|
3815
4269
|
return style === undefined ? new BaseMaskStyle() : style;
|
|
3816
4270
|
}
|
|
4271
|
+
function normalizeGlobalMaskHaloStyle(style) {
|
|
4272
|
+
return style === undefined ? createDefaultMaskHaloStyle() : style;
|
|
4273
|
+
}
|
|
4274
|
+
function normalizeGlobalMarkerStyle(style) {
|
|
4275
|
+
return style === undefined ? new BaseMarkerStyle() : style;
|
|
4276
|
+
}
|
|
3817
4277
|
function normalizeGlobalPolygonStyle(style) {
|
|
3818
4278
|
return style === undefined ? new BasePolygonStyle() : style;
|
|
3819
4279
|
}
|
|
@@ -4310,6 +4770,180 @@ function writePaletteEntry(palette, id, color, alpha) {
|
|
|
4310
4770
|
palette[offset + 3] = Math.max(0, Math.min(alpha, 1));
|
|
4311
4771
|
}
|
|
4312
4772
|
|
|
4773
|
+
const DEFAULT_ELLIPSE_SEGMENT_COUNT = 48;
|
|
4774
|
+
const FULL_TURN = Math.PI * 2;
|
|
4775
|
+
const GEOMETRY_EPSILON = 1e-9;
|
|
4776
|
+
const MIN_ELLIPSE_SEGMENT_COUNT = 4;
|
|
4777
|
+
const MAX_ELLIPSE_SEGMENT_COUNT = 512;
|
|
4778
|
+
/**
|
|
4779
|
+
* Samples an ellipse or elliptical arc into a deterministic polyline so every
|
|
4780
|
+
* backend rasterizes the same structural geometry, including dashed strokes.
|
|
4781
|
+
*
|
|
4782
|
+
* A closed ellipse returns `segmentCount` points without repeating the first
|
|
4783
|
+
* point; an open arc returns `segmentCount + 1` points including both
|
|
4784
|
+
* endpoints.
|
|
4785
|
+
*/
|
|
4786
|
+
function sampleEllipseArc(ellipse, segmentCount = DEFAULT_ELLIPSE_SEGMENT_COUNT) {
|
|
4787
|
+
validateEllipseGeometry(ellipse);
|
|
4788
|
+
assertIntegerAtLeast(segmentCount, MIN_ELLIPSE_SEGMENT_COUNT, "segmentCount");
|
|
4789
|
+
const rotation = ellipse.rotation ?? 0;
|
|
4790
|
+
const startAngle = ellipse.startAngle ?? 0;
|
|
4791
|
+
const endAngle = ellipse.endAngle ?? startAngle + FULL_TURN;
|
|
4792
|
+
const range = endAngle - startAngle;
|
|
4793
|
+
const closed = ellipse.startAngle === undefined;
|
|
4794
|
+
const pointCount = closed ? segmentCount : segmentCount + 1;
|
|
4795
|
+
const cosRotation = Math.cos(rotation);
|
|
4796
|
+
const sinRotation = Math.sin(rotation);
|
|
4797
|
+
const points = [];
|
|
4798
|
+
for (let index = 0; index < pointCount; index += 1) {
|
|
4799
|
+
const angle = startAngle + (range * index) / segmentCount;
|
|
4800
|
+
const localX = Math.cos(angle) * ellipse.radiusX;
|
|
4801
|
+
const localY = Math.sin(angle) * ellipse.radiusY;
|
|
4802
|
+
points.push({
|
|
4803
|
+
x: ellipse.center.x + localX * cosRotation - localY * sinRotation,
|
|
4804
|
+
y: ellipse.center.y + localX * sinRotation + localY * cosRotation,
|
|
4805
|
+
});
|
|
4806
|
+
}
|
|
4807
|
+
return { closed, points };
|
|
4808
|
+
}
|
|
4809
|
+
/**
|
|
4810
|
+
* Chooses a bounded segment count from the ellipse's on-screen radius. The
|
|
4811
|
+
* result targets sub-pixel chord error without making tiny markers expensive.
|
|
4812
|
+
*/
|
|
4813
|
+
function resolveEllipseSegmentCount(ellipse, viewportScale = 1, maxErrorPixels = 0.5) {
|
|
4814
|
+
validateEllipseGeometry(ellipse);
|
|
4815
|
+
assertPositiveFinite(viewportScale, "viewportScale");
|
|
4816
|
+
assertPositiveFinite(maxErrorPixels, "maxErrorPixels");
|
|
4817
|
+
const screenRadius = Math.max(ellipse.radiusX, ellipse.radiusY) * viewportScale;
|
|
4818
|
+
assertPositiveFinite(screenRadius, "screenRadius");
|
|
4819
|
+
const clampedError = Math.min(maxErrorPixels, screenRadius);
|
|
4820
|
+
const maxStep = clampedError === screenRadius
|
|
4821
|
+
? Math.PI / 2
|
|
4822
|
+
: 2 * Math.acos(1 - clampedError / screenRadius);
|
|
4823
|
+
const startAngle = ellipse.startAngle ?? 0;
|
|
4824
|
+
const endAngle = ellipse.endAngle ?? startAngle + FULL_TURN;
|
|
4825
|
+
const arcLength = Math.abs(endAngle - startAngle);
|
|
4826
|
+
const segmentCount = Math.ceil(arcLength / maxStep);
|
|
4827
|
+
return Math.min(MAX_ELLIPSE_SEGMENT_COUNT, Math.max(MIN_ELLIPSE_SEGMENT_COUNT, segmentCount));
|
|
4828
|
+
}
|
|
4829
|
+
/**
|
|
4830
|
+
* Resolves a marker instruction into media-space geometry. Screen-space sizes
|
|
4831
|
+
* are divided by the viewport scale, matching stroke-width semantics.
|
|
4832
|
+
*/
|
|
4833
|
+
function resolveMarkerGeometry(marker, viewportScale = 1) {
|
|
4834
|
+
assertFinitePoint(marker.center, "center");
|
|
4835
|
+
assertPositiveFinite(marker.size, "size");
|
|
4836
|
+
assertPositiveFinite(viewportScale, "viewportScale");
|
|
4837
|
+
if (marker.rotation !== undefined) {
|
|
4838
|
+
assertFinite(marker.rotation, "rotation");
|
|
4839
|
+
}
|
|
4840
|
+
const size = marker.sizeSpace === MarkerSizeSpace.Screen
|
|
4841
|
+
? marker.size / viewportScale
|
|
4842
|
+
: marker.size;
|
|
4843
|
+
const radius = size / 2;
|
|
4844
|
+
const rotation = marker.rotation ?? 0;
|
|
4845
|
+
if (marker.shape === MarkerShape.Circle) {
|
|
4846
|
+
return { center: marker.center, kind: "circle", radius };
|
|
4847
|
+
}
|
|
4848
|
+
if (marker.shape === MarkerShape.Cross) {
|
|
4849
|
+
return {
|
|
4850
|
+
closed: false,
|
|
4851
|
+
kind: "subpaths",
|
|
4852
|
+
subpaths: [
|
|
4853
|
+
[
|
|
4854
|
+
rotatePoint(marker.center, -radius, -radius, rotation),
|
|
4855
|
+
rotatePoint(marker.center, radius, radius, rotation),
|
|
4856
|
+
],
|
|
4857
|
+
[
|
|
4858
|
+
rotatePoint(marker.center, radius, -radius, rotation),
|
|
4859
|
+
rotatePoint(marker.center, -radius, radius, rotation),
|
|
4860
|
+
],
|
|
4861
|
+
],
|
|
4862
|
+
};
|
|
4863
|
+
}
|
|
4864
|
+
if (marker.shape === MarkerShape.Square) {
|
|
4865
|
+
return {
|
|
4866
|
+
closed: true,
|
|
4867
|
+
kind: "subpaths",
|
|
4868
|
+
subpaths: [
|
|
4869
|
+
[
|
|
4870
|
+
rotatePoint(marker.center, -radius, -radius, rotation),
|
|
4871
|
+
rotatePoint(marker.center, radius, -radius, rotation),
|
|
4872
|
+
rotatePoint(marker.center, radius, radius, rotation),
|
|
4873
|
+
rotatePoint(marker.center, -radius, radius, rotation),
|
|
4874
|
+
],
|
|
4875
|
+
],
|
|
4876
|
+
};
|
|
4877
|
+
}
|
|
4878
|
+
// Triangle: equilateral, inscribed in the marker circle, pointing toward
|
|
4879
|
+
// positive y at rotation 0.
|
|
4880
|
+
const baseOffsetY = -radius / 2;
|
|
4881
|
+
const baseOffsetX = radius * (Math.sqrt(3) / 2);
|
|
4882
|
+
return {
|
|
4883
|
+
closed: true,
|
|
4884
|
+
kind: "subpaths",
|
|
4885
|
+
subpaths: [
|
|
4886
|
+
[
|
|
4887
|
+
rotatePoint(marker.center, 0, radius, rotation),
|
|
4888
|
+
rotatePoint(marker.center, baseOffsetX, baseOffsetY, rotation),
|
|
4889
|
+
rotatePoint(marker.center, -baseOffsetX, baseOffsetY, rotation),
|
|
4890
|
+
],
|
|
4891
|
+
],
|
|
4892
|
+
};
|
|
4893
|
+
}
|
|
4894
|
+
function validateEllipseGeometry(ellipse) {
|
|
4895
|
+
assertFinitePoint(ellipse.center, "center");
|
|
4896
|
+
assertPositiveFinite(ellipse.radiusX, "radiusX");
|
|
4897
|
+
assertPositiveFinite(ellipse.radiusY, "radiusY");
|
|
4898
|
+
if (ellipse.rotation !== undefined) {
|
|
4899
|
+
assertFinite(ellipse.rotation, "rotation");
|
|
4900
|
+
}
|
|
4901
|
+
const hasStart = ellipse.startAngle !== undefined;
|
|
4902
|
+
const hasEnd = ellipse.endAngle !== undefined;
|
|
4903
|
+
if (hasStart !== hasEnd) {
|
|
4904
|
+
throw new RangeError("startAngle and endAngle must be provided together");
|
|
4905
|
+
}
|
|
4906
|
+
if (hasStart && hasEnd) {
|
|
4907
|
+
assertFinite(ellipse.startAngle, "startAngle");
|
|
4908
|
+
assertFinite(ellipse.endAngle, "endAngle");
|
|
4909
|
+
const range = Math.abs(ellipse.endAngle - ellipse.startAngle);
|
|
4910
|
+
if (range <= GEOMETRY_EPSILON || range >= FULL_TURN - GEOMETRY_EPSILON) {
|
|
4911
|
+
throw new RangeError("ellipse arc range must be greater than 0 and less than one full turn");
|
|
4912
|
+
}
|
|
4913
|
+
}
|
|
4914
|
+
}
|
|
4915
|
+
function assertFinitePoint(point, name) {
|
|
4916
|
+
assertFinite(point.x, `${name}.x`);
|
|
4917
|
+
assertFinite(point.y, `${name}.y`);
|
|
4918
|
+
}
|
|
4919
|
+
function assertFinite(value, name) {
|
|
4920
|
+
if (!Number.isFinite(value)) {
|
|
4921
|
+
throw new RangeError(`${name} must be finite`);
|
|
4922
|
+
}
|
|
4923
|
+
}
|
|
4924
|
+
function assertPositiveFinite(value, name) {
|
|
4925
|
+
assertFinite(value, name);
|
|
4926
|
+
if (value <= 0) {
|
|
4927
|
+
throw new RangeError(`${name} must be greater than 0`);
|
|
4928
|
+
}
|
|
4929
|
+
}
|
|
4930
|
+
function assertIntegerAtLeast(value, minimum, name) {
|
|
4931
|
+
if (!Number.isInteger(value) || value < minimum) {
|
|
4932
|
+
throw new RangeError(`${name} must be an integer of at least ${minimum}`);
|
|
4933
|
+
}
|
|
4934
|
+
}
|
|
4935
|
+
function rotatePoint(center, offsetX, offsetY, rotation) {
|
|
4936
|
+
if (rotation === 0) {
|
|
4937
|
+
return { x: center.x + offsetX, y: center.y + offsetY };
|
|
4938
|
+
}
|
|
4939
|
+
const cosRotation = Math.cos(rotation);
|
|
4940
|
+
const sinRotation = Math.sin(rotation);
|
|
4941
|
+
return {
|
|
4942
|
+
x: center.x + offsetX * cosRotation - offsetY * sinRotation,
|
|
4943
|
+
y: center.y + offsetX * sinRotation + offsetY * cosRotation,
|
|
4944
|
+
};
|
|
4945
|
+
}
|
|
4946
|
+
|
|
4313
4947
|
function includeDefined(values) {
|
|
4314
4948
|
return Object.fromEntries(Object.entries(values).filter(([, value]) => value !== undefined));
|
|
4315
4949
|
}
|
|
@@ -4426,5 +5060,5 @@ var MediaSessionActivityStatus;
|
|
|
4426
5060
|
MediaSessionActivityStatus["Waiting"] = "waiting";
|
|
4427
5061
|
})(MediaSessionActivityStatus || (MediaSessionActivityStatus = {}));
|
|
4428
5062
|
|
|
4429
|
-
export { AnnotationFrameMutationKind, AnnotationGeometryKind, AnnotationGestureStateKind, AnnotationHandleKind, BaseBoxStyle, BaseFocusStyle, BaseInteractionStyle, BaseKeypointStyle, BaseLabelStyle, BaseMaskStyle, BasePolygonStyle, BasePolylineStyle, BoxShape, BoxStrokeAlignment, DEFAULT_DETECTION_CLASS_STYLES, DEFAULT_DETECTION_COLOR_SEQUENCE, DetectionBufferStatus, DetectionFrameRetentionMode, DetectionFrameSelectionMode, DetectionInteractionState, DetectionMaskEncoding, DetectionMaskPayloadFormat, DetectionPickTarget, FocusTargetMode, KeypointMarkerShape, KeypointVisibility, LabelPlacement, LabelVisibilityMode, MAX_ID_MASK_PALETTE_ENTRIES, MAX_ID_MASK_STROKE_WIDTH, MaskRenderMode, MediaInteractionMode, MediaRendererFit, MediaRendererPlaybackState, MediaSessionActivityKind, MediaSessionActivityStatus, MediaSessionMode, MediaSessionStatus, MediaSourceStatus, SUPERVISION_ROBOFLOW_COLOR, annotationRendererKinds, annotationRenderers, applyAnnotationHandleDrag, canReuseMaskStyleArtifacts, centerRectToTopLeftRect, computeDetectionMaskRect, computeMaskBounds, containsPoint, convertDetectionBoxToMask, convertDetectionBoxToPolygon, convertDetectionMaskToBox, convertDetectionMaskToPolygon, convertDetectionPolygonToBox, convertDetectionPolygonToMask, copySortedDetectionFrames, createAnnotationEditingEngine, createArrayDetectionFrameSource, createBufferedDetectionTimeline, createColdDetectionFrameSource, createCompositeDetectionFrameSource, createDefaultAnnotationPresentation, createDetectionPickKey, createEditableAnnotationFrameSession, createIdMaskFrame, createIdleDetectionBufferState, createMemoryColdDetectionFrameStore, createSourceAwarePresentation, createViewportController, createWritableDetectionFrameSource, decodeCompressedRleCounts, decodeCompressedRleMask, decodeDetectionMaskPayload, deleteAnnotationVertex, detectMaskBorders, detectionFrameOverlapsRange, distanceToSegment, encodeBinaryMask, encodeBinaryMaskWithBounds, encodeCompressedRleCounts, encodeDetectionMaskPayload, extractMaskContour, extractMaskRectRuns, filterDetectionFramesForRange, findClosestAnnotationSegment, getAnnotationHandles, getBufferedDetectionTimelineFrameSnapshot, getDetectionRect, getPointsRect, includeDefined, isDeflatedBase64DetectionMaskPayload, lightenColor, mediaToScreen, mergeDetectionMasks, mergeDetectionPolygonsByClass, normalizeDetectionClassName, offsetDetection, pickAnnotationHandle, pickDetectionAtPoint, pickDetectionByMaskId, pointInPolygon, polygonArea, polygonToRect, rasterizePolygonToMask, rasterizeRectToMask, rebaseDetectionPickToFrame, rectArea, rectToPolygon, resolveAnnotationRendererPresentation, resolveAnnotationStyleState, resolveContrastTextColor, resolveDetectionClassColorStyle, resolveMaskStyleOpacity, resolveStyleValue, screenToMedia, selectDetectionFrame, topLeftRectToCenterRect, validateDetectionFrames };
|
|
5063
|
+
export { AnnotationFrameMutationKind, AnnotationGeometryKind, AnnotationGestureStateKind, AnnotationHandleKind, BaseBoxCornerStyle, BaseBoxStyle, BaseFocusStyle, BaseInteractionStyle, BaseKeypointStyle, BaseLabelStyle, BaseMarkerStyle, BaseMaskStyle, BasePolygonStyle, BasePolylineStyle, BoxShape, StrokeAlignment as BoxStrokeAlignment, DEFAULT_DETECTION_CLASS_STYLES, DEFAULT_DETECTION_COLOR_SEQUENCE, DetectionBufferStatus, DetectionFrameRetentionMode, DetectionFrameSelectionMode, DetectionInteractionState, DetectionMaskEncoding, DetectionMaskPayloadFormat, DetectionPickTarget, FocusTargetMode, KeypointMarkerShape, KeypointVisibility, LabelPlacement, LabelVisibilityMode, MAX_ID_MASK_PALETTE_ENTRIES, MAX_ID_MASK_STROKE_WIDTH, MarkerShape, MarkerSizeSpace, MaskRenderMode, MediaInteractionMode, MediaRendererFit, MediaRendererPlaybackState, MediaSessionActivityKind, MediaSessionActivityStatus, MediaSessionMode, MediaSessionStatus, MediaSourceStatus, RegionRendererComposeMode, RegionRendererRegionKind, RegionRendererSourceKind, SUPERVISION_ROBOFLOW_COLOR, ShapeInstructionKind, StrokeAlignment, annotationRendererKinds, annotationRenderers, applyAnnotationHandleDrag, canReuseMaskStyleArtifacts, centerRectToTopLeftRect, computeDetectionMaskRect, computeMaskBounds, containsPoint, convertDetectionBoxToMask, convertDetectionBoxToPolygon, convertDetectionMaskToBox, convertDetectionMaskToPolygon, convertDetectionPolygonToBox, convertDetectionPolygonToMask, copySortedDetectionFrames, createAnnotationEditingEngine, createArrayDetectionFrameSource, createBufferedDetectionTimeline, createColdDetectionFrameSource, createCompositeDetectionFrameSource, createDefaultAnnotationPresentation, createDetectionPickKey, createEditableAnnotationFrameSession, createIdMaskFrame, createIdleDetectionBufferState, createMemoryColdDetectionFrameStore, createSourceAwarePresentation, createViewportController, createWritableDetectionFrameSource, decodeCompressedRleCounts, decodeCompressedRleMask, decodeDetectionMaskPayload, deleteAnnotationVertex, detectMaskBorders, detectionFrameOverlapsRange, distanceToSegment, encodeBinaryMask, encodeBinaryMaskWithBounds, encodeCompressedRleCounts, encodeDetectionMaskPayload, extractMaskContour, extractMaskRectRuns, filterDetectionFramesForRange, findClosestAnnotationSegment, followDetectionPickAcrossFrames, getAnnotationHandles, getBufferedDetectionTimelineFrameSnapshot, getDetectionRect, getPointsRect, haveSameDetectionPickIdentities, includeDefined, isDeflatedBase64DetectionMaskPayload, lightenColor, mediaToScreen, mergeDetectionMasks, mergeDetectionPolygonsByClass, normalizeDetectionClassName, offsetDetection, pickAnnotationHandle, pickDetectionAtPoint, pickDetectionByMaskId, pointInPolygon, polygonArea, polygonToRect, rasterizePolygonToMask, rasterizeRectToMask, rebaseDetectionPickToFrame, rectArea, rectToPolygon, resolveAnnotationRendererPresentation, resolveAnnotationStyleState, resolveContrastTextColor, resolveDetectionClassColorStyle, resolveEllipseSegmentCount, resolveMarkerGeometry, resolveMaskStyleOpacity, resolveStyleValue, sampleEllipseArc, screenToMedia, selectDetectionFrame, topLeftRectToCenterRect, validateDetectionFrames };
|
|
4430
5064
|
//# sourceMappingURL=index.js.map
|