Skip to content

Add ROI over h5web canvas

Thomas Vincent requested to merge svgscene into master

This MR adds some machinery to provide a SVG layer over h5web that has the same coordinates as the axes: SvgScene. It must be inside a h5web viscanvas. In this component, it is possible to add some svg fragments with the SvgSceneObject component.

The SvgSceneObjectNonScalingGroup component provides the vector-effect: 'non-scaling-size' feature which cancels the current scale but that is not implemented (yet?) in SVG ;( The SvgSceneHandle provides dragging support on top of this "non-scaling-size". Finally, SvgSceneRectROI is the rectangular ROI which needs to be inside SvgScene.

It is still a WIP and there's a few things to improve and to think about but it is functional.

Here is an example of use:

/src/components/tomo/tiling/TilingVis.tsx
@@ -1,9 +1,9 @@
 import type { TilesApi } from '@h5web/lib';
 import { TooltipMesh } from '@h5web/lib';
 import type { PropsWithChildren } from 'react';
-import { useCallback, useEffect, useMemo } from 'react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
 import { capitalize } from 'lodash';
-import type { Box2 } from 'three';
+import { Box2, Vector2 } from 'three';
 import type { TomoScanTask, TomoScanTaskActions } from 'types/Tomo';
 import Qty from 'js-quantities';
 import type { TomoConfigHardware } from 'connect/tomo/utils';
@@ -29,6 +29,8 @@ import { getSampleStageBounds } from './geometry';
 import TilingInteraction from './TilingInteraction';
 import TilingMesh from './TilingMesh';
 import { CubeRoiItem } from './CubeRoiItem';
+import SvgScene from './SvgScene';
+import SvgSceneRectROI from './SvgSceneRectROI';
 
 interface Props extends ColorMapProps {
   projRotation: 0 | -90;
@@ -119,6 +121,16 @@ function TilingVis(props: PropsWithChildren<Props>) {
   );
   const yMotorName = concateMotorNames(sampleStage.sz, null, 'z');
 
+  const [box, setBox] = useState<Box2>(
+    new Box2(new Vector2(0, 0), new Vector2(100, 50))
+  );
+  const boxDragEnd = useCallback(
+    (newbox) => {
+      setBox(newbox);
+    },
+    [setBox]
+  );
+
   return (
     <LinearVisCanvas
       abscissaConfig={{
@@ -151,6 +163,9 @@ function TilingVis(props: PropsWithChildren<Props>) {
         operator={operator}
         setMarker={setMarker}
       />
+      <SvgScene>
+        <SvgSceneRectROI box={box} readOnly onDragEnd={boxDragEnd} />
+      </SvgScene>
       <TilingMesh api={api} box={tilingBox} {...colorMapProps} />
       {tasks.map((task) => (
         <TomoScanTaskSelectRect

attn @bocciare

Merge request reports

Loading