-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRoiBox.tsx
More file actions
101 lines (90 loc) · 2.72 KB
/
RoiBox.tsx
File metadata and controls
101 lines (90 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { JSX } from 'react';
import { memo, useEffect } from 'react';
import { usePanZoom } from '../../hooks/usePanZoom.js';
import { useRoiDispatch } from '../../hooks/useRoiDispatch.js';
import type {
GetOverlayOpacity,
GetReadOnlyCallback,
GetStyleCallback,
RenderLabelCallback,
} from '../../index.js';
import type { Roi } from '../../types/Roi.js';
import { applyTransformToBox } from '../../utilities/box.js';
import type { GetGridLinesOptions } from '../../utilities/grid.ts';
import { computeTotalPanZoom } from '../../utilities/panZoom.js';
import { LabelBox } from '../label/LabelBox.js';
import { BoxSvg } from './BoxSvg.js';
interface RoiBoxProps {
roi: Roi;
isSelected: boolean;
getStyle: GetStyleCallback;
getReadOnly: GetReadOnlyCallback;
renderLabel: RenderLabelCallback;
allowRotate: boolean;
getOverlayOpacity: GetOverlayOpacity;
showGrid: boolean;
gridOptions: GetGridLinesOptions;
}
function RoiBoxInternal(props: RoiBoxProps): JSX.Element {
const {
roi,
getStyle,
getReadOnly,
isSelected,
renderLabel,
getOverlayOpacity,
allowRotate,
showGrid,
gridOptions,
} = props;
const panzoom = usePanZoom();
const totalPanzoom = computeTotalPanZoom(panzoom);
const { id } = roi;
const roiDispatch = useRoiDispatch();
const isReadOnly = getReadOnly(roi) || false;
const roiAdditionalState = {
isReadOnly,
isSelected,
zoomScale: panzoom.panZoom.scale * panzoom.initialPanZoom.scale,
};
const shadowOpacity = getOverlayOpacity(roi, roiAdditionalState);
useEffect(() => {
if (isReadOnly) {
roiDispatch({ type: 'UNSELECT_ROI', payload: id });
}
}, [id, isReadOnly, roiDispatch]);
const box = applyTransformToBox(totalPanzoom, roi.box);
const label = renderLabel(roi, roiAdditionalState);
return (
<>
<div
data-testid={roi.id}
style={{
transformOrigin: `${roi.box.xRotationCenter} ${roi.box.yRotationCenter}`,
transform: `rotate(${roi.box.angle}rad)`,
position: 'absolute',
left: box.x,
top: box.y,
width: box.width,
height: box.height,
boxShadow:
isSelected && shadowOpacity
? `0 0 0 ${Math.max(panzoom.containerSize.width * 4, panzoom.containerSize.height * 4)}px rgba(0,0,0,${shadowOpacity})`
: 'none',
}}
>
<BoxSvg
roi={roi}
box={box}
isReadOnly={isReadOnly}
getStyle={getStyle}
allowRotate={allowRotate}
showGrid={showGrid}
gridOptions={gridOptions}
/>
</div>
<LabelBox roi={roi} label={label} panZoom={totalPanzoom} />
</>
);
}
export const RoiBox = memo(RoiBoxInternal);