From 086c6fdf540919c27163a4eb11826e031932835c Mon Sep 17 00:00:00 2001
From: Anthony Geourjon <anthony.geourjon@tetras-libre.fr>
Date: Mon, 8 Jan 2024 15:28:04 +0100
Subject: [PATCH] Add video support on AnnotationSvgDrawing.js

---
 src/components/AnnotationSvgDrawing.js | 113 +++++++++++++++++++++----
 1 file changed, 96 insertions(+), 17 deletions(-)

diff --git a/src/components/AnnotationSvgDrawing.js b/src/components/AnnotationSvgDrawing.js
index e39eccc..22bd527 100644
--- a/src/components/AnnotationSvgDrawing.js
+++ b/src/components/AnnotationSvgDrawing.js
@@ -2,6 +2,7 @@ import React, { Component } from 'react';
 import ReactDOM from 'react-dom';
 import PropTypes from 'prop-types';
 import { OSDReferences } from 'mirador/dist/es/src/plugins/OSDReferences';
+import { VideosReferences } from 'mirador/dist/es/src/plugins/VideosReferences';
 import { renderWithPaperScope, PaperContainer } from '@psychobolt/react-paperjs';
 import {
   EllipseTool,
@@ -19,6 +20,10 @@ class AnnotationSvgDrawing extends Component {
   constructor(props) {
     super(props);
 
+    this.paper = null;
+    this.getDisplayProps = this.getDisplayProps.bind(this);
+    this.onPaperResize = this.onPaperResize.bind(this);
+    this.paperDidMount = this.paperDidMount.bind(this);
     this.addPath = this.addPath.bind(this);
   }
 
@@ -26,6 +31,25 @@ class AnnotationSvgDrawing extends Component {
   componentDidMount() {
     const { windowId } = this.props;
     this.OSDReference = OSDReferences.get(windowId);
+    this.onPaperResize();
+  }
+
+  /** Sync drawing canvas size/zoom with annotations canvas */
+  onPaperResize(ev) {
+    const { windowId } = this.props;
+    if (VideosReferences.get(windowId) && this.paper) {
+      const { canvasOverlay, video } = VideosReferences.get(windowId);
+      const { height, width } = canvasOverlay.ref.current;
+      const { videoHeight, videoWidth } = video;
+      this.paper.view.center = new Point(videoWidth / 2, videoHeight / 2);
+      this.paper.view.zoom = canvasOverlay.scale;
+      this.paper.view.viewSize = new this.paper.Size(width, height);
+    }
+  }
+
+  /** Save paperjs ref once created */
+  paperDidMount(paper) {
+    this.paper = paper;
   }
 
   /** */
@@ -43,28 +67,73 @@ class AnnotationSvgDrawing extends Component {
     });
   }
 
+  getDisplayProps() {
+    const { windowId } = this.props;
+    const osdref = OSDReferences.get(windowId);
+    const videoref = VideosReferences.get(windowId);
+
+    if (osdref) {
+      const { viewport } = osdref.current;
+      const img = osdref.current.world.getItemAt(0);
+      const center = img.viewportToImageCoordinates(viewport.getCenter(true));
+      return {
+        canvasProps: { style: { height: '100%', width: '100%' } },
+        viewProps: {
+          center: new Point(center.x, center.y),
+          rotation: viewport.getRotation(),
+          scaling: new Point(viewport.getFlip() ? -1 : 1, 1),
+          zoom: img.viewportToImageZoom(viewport.getZoom()),
+        },
+      };
+    }
+
+    if (videoref) {
+      const { height, width } = videoref.canvasOverlay.ref.current;
+      return {
+        canvasProps: {
+          height,
+          resize: 'true',
+          style: {
+            left: 0, position: 'absolute', top: 0,
+          },
+          width,
+        },
+        viewProps: {
+          center: new Point(width / 2, height / 2),
+          height,
+          width,
+          zoom: videoref.canvasOverlay.scale,
+        },
+      };
+    }
+
+    throw new Error('Unknown or missing data player, not OpenSeadragon (image viewer) nor the video player');
+  }
+
   /** */
   paperThing() {
+    const { viewProps, canvasProps } = this.getDisplayProps();
     const {
-      activeTool, fillColor, strokeColor, strokeWidth, svg, edit
+      activeTool, fillColor, strokeColor, strokeWidth, svg,
     } = this.props;
+
     if (!activeTool || activeTool === 'cursor') {
       return null;
     }
-    // Setup Paper View to have the same center and zoom as the OSD Viewport
-    const viewportZoom = this.OSDReference.viewport.getZoom(true);
-    const image1 = this.OSDReference.world.getItemAt(0);
-    const center = image1.viewportToImageCoordinates(
-      this.OSDReference.viewport.getCenter(true),
-    );
-    const flipped = this.OSDReference.viewport.getFlip();
-
-    const viewProps = {
-      center: new Point(center.x, center.y),
-      rotation: this.OSDReference.viewport.getRotation(),
-      scaling: new Point(flipped ? -1 : 1, 1),
-      zoom: image1.viewportToImageZoom(viewportZoom),
-    };
+    // // Setup Paper View to have the same center and zoom as the OSD Viewport
+    // const viewportZoom = this.OSDReference.viewport.getZoom(true);
+    // const image1 = this.OSDReference.world.getItemAt(0);
+    // const center = image1.viewportToImageCoordinates(
+    //   this.OSDReference.viewport.getCenter(true),
+    // );
+    // const flipped = this.OSDReference.viewport.getFlip();
+    //
+    // const viewProps = {
+    //   center: new Point(center.x, center.y),
+    //   rotation: this.OSDReference.viewport.getRotation(),
+    //   scaling: new Point(flipped ? -1 : 1, 1),
+    //   zoom: image1.viewportToImageZoom(viewportZoom),
+    // };
 
     let ActiveTool = RectangleTool;
     switch (activeTool) {
@@ -124,9 +193,19 @@ class AnnotationSvgDrawing extends Component {
   /** */
   render() {
     const { windowId } = this.props;
-    this.OSDReference = OSDReferences.get(windowId).current;
+    const osdref = OSDReferences.get(windowId);
+    const videoref = VideosReferences.get(windowId);
+    if (!osdref && !videoref) {
+      throw new Error("Unknown or missing data player, didn't found OpenSeadragon (image viewer) nor the video player");
+    }
+    if (osdref && videoref) {
+      throw new Error('Unhandled case: both OpenSeadragon (image viewer) and video player on the same canvas');
+    }
+    const container = osdref
+      ? osdref.current.element
+      : videoref.ref.current.parentElement;
     return (
-      ReactDOM.createPortal(this.paperThing(), this.OSDReference.element)
+      ReactDOM.createPortal(this.paperThing(), container)
     );
   }
 }
-- 
GitLab