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