UNPKG

react-video-annotation-tool

Version:

A React-based video player with built-in annotation features, enabling interactive video tagging and markup for seamless media annotation workflows

681 lines (662 loc) 30.7 kB
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } import React, { useState, useEffect, useRef, useCallback, forwardRef, useImperativeHandle } from "react"; import { Stage, Layer, Rect, Transformer, Circle, Line } from "react-konva"; import { throttle } from "lodash"; import generateId from "../utils/generateId"; import Player from "../VideoPlayer/Player"; import TransparentVideoController from "../VideoPlayerController/TransparentVideoplayerController"; import useVideoController from "../VideoPlayerController/UseVideoPlayerControllerHook"; import { useCanvas } from "../contexts/CanvasProvider"; import { LineShape } from "../shapes/Line"; import { CircleShape } from "../shapes/Circle"; import { Rectangle } from "../shapes/Rectangle"; var Canvas = /*#__PURE__*/forwardRef(function (_ref, ref) { var _canvasParentRef$curr, _canvasParentRef$curr2, _canvasParentRef$curr5, _canvasParentRef$curr6, _videoRef$current3; var children = _ref.children, url = _ref.url, selectedShapeTool = _ref.selectedShapeTool, hideAnnotations = _ref.hideAnnotations, lockEdit = _ref.lockEdit, annotationColor = _ref.annotationColor, opacity = _ref.opacity, strokeWidth = _ref.strokeWidth, selectedAnnotationData = _ref.selectedAnnotationData, videoControls = _ref.videoControls; var _useCanvas = useCanvas(), shapes = _useCanvas.shapes, setShapes = _useCanvas.setShapes, isDrawing = _useCanvas.isDrawing, setIsDrawing = _useCanvas.setIsDrawing, newShape = _useCanvas.newShape, setNewShape = _useCanvas.setNewShape, selectedShapeId = _useCanvas.selectedShapeId, setSelectedShapeId = _useCanvas.setSelectedShapeId, rectPosititon = _useCanvas.rectPosititon, setRectPosition = _useCanvas.setRectPosition, videoRefVal = _useCanvas.videoRefVal, setVideoRefVal = _useCanvas.setVideoRefVal, dimensions = _useCanvas.dimensions, setDimensions = _useCanvas.setDimensions, history = _useCanvas.history, setHistory = _useCanvas.setHistory, redoStack = _useCanvas.redoStack, setRedoStack = _useCanvas.setRedoStack, undo = _useCanvas.undo, redo = _useCanvas.redo, deleteShape = _useCanvas.deleteShape; // REF STATES var shapeRef = useRef({}); var transformerRef = useRef(); var stageRef = useRef(null); var canvasParentRef = useRef(null); var layerRef = useRef(null); var videoRef = useRef(null); // HOOK VALUES var _useVideoController = useVideoController(videoRefVal, canvasParentRef), currentTime = _useVideoController.currentTime, setCurrentTime = _useVideoController.setCurrentTime, isFullScreen = _useVideoController.isFullScreen; var _useState = useState(canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr = canvasParentRef.current) === null || _canvasParentRef$curr === void 0 ? void 0 : _canvasParentRef$curr.offsetWidth), _useState2 = _slicedToArray(_useState, 2), canvasParentWidth = _useState2[0], setcanvasParentWidth = _useState2[1]; var _useState3 = useState(canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr2 = canvasParentRef.current) === null || _canvasParentRef$curr2 === void 0 ? void 0 : _canvasParentRef$curr2.offsetHeight), _useState4 = _slicedToArray(_useState3, 2), canvasParentHeight = _useState4[0], setcanvasParentHeight = _useState4[1]; useEffect(function () { if (videoRef) { setVideoRefVal(videoRef); } return function () { setVideoRefVal(null); }; }, [videoRef]); // =================== Exported Handlers =================================== useEffect(function () { if (typeof selectedAnnotationData === 'function') { if (selectedShapeId) { var selectedData = shapes.find(function (shape) { return shape.id === selectedShapeId; }); selectedAnnotationData(selectedData); } else { selectedAnnotationData(null); } } }, [selectedShapeId, shapes, selectedAnnotationData]); useImperativeHandle(ref, function () { return { undo: undo, redo: redo, deleteShape: deleteShape }; }); // ============================================================================ /** * Handle mouse down event to start drawing a new shape. * * @param {Object} e - The mouse event object. */ var handleMouseDown = useCallback(function (e) { if (isFullScreen) return; var cursor = window.getComputedStyle(document.body).cursor; if (cursor === "nwse-resize") return; // console.log(selectedShapeTool) if (selectedShapeTool !== "rectangle" && selectedShapeTool !== "circle" && selectedShapeTool !== "line") { console.warning("Kindly Select appropriate tool which can only include line rectangle and circle"); return; } var stage = e.target.getStage(); if (!stage) return; var _stage$getPointerPosi = stage.getPointerPosition(), x = _stage$getPointerPosi.x, y = _stage$getPointerPosi.y; // console.log({ x, y }); var startTime = currentTime; var shapeProperties; switch (selectedShapeTool) { case "rectangle": shapeProperties = { type: "rectangle", x: x, y: y, width: 4, // Default width for rectangle height: 4, // Default height for rectangle startTime: startTime, endTime: startTime + 0.5, scaleX: 1, scaleY: 1, screenHeight: canvasParentHeight, screenWidth: canvasParentWidth, strokeWidth: strokeWidth || 2, opacity: opacity }; break; case "circle": shapeProperties = { type: "circle", x: x, y: y, radius: 4, startTime: startTime, endTime: startTime + 0.5, scaleX: 1, scaleY: 1, screenHeight: canvasParentHeight, screenWidth: canvasParentWidth, strokeWidth: strokeWidth || 2, opacity: opacity }; break; case "line": shapeProperties = { type: "line", x: x, y: y, points: [0, 0, 100, 0, 100, 100], startTime: startTime, endTime: startTime + 0.5, scaleX: 1, scaleY: 1, screenHeight: canvasParentHeight, screenWidth: canvasParentWidth, strokeWidth: strokeWidth || 2, opacity: opacity }; break; default: return; } setNewShape({ id: generateId(), color: annotationColor, label: "", data: {}, properties: shapeProperties }); setIsDrawing(true); }, [currentTime, isFullScreen, annotationColor, selectedShapeTool, strokeWidth, opacity, canvasParentHeight, canvasParentWidth]); /** * Handle mouse move event to update the shape dimensions while drawing. * * @param {Object} e - The mouse event object. */ var handleMouseMove = throttle(function (e) { if (isFullScreen) return; if (!isDrawing || !newShape) return; var stage = e.target.getStage(); if (!stage) return; var _stage$getPointerPosi2 = stage.getPointerPosition(), x = _stage$getPointerPosi2.x, y = _stage$getPointerPosi2.y; if (x === newShape.properties.x && y === newShape.properties.y) return; var updatedShape; switch (newShape.properties.type) { case "rectangle": var width = x - newShape.properties.x; var height = y - newShape.properties.y; updatedShape = _objectSpread(_objectSpread({}, newShape), {}, { properties: _objectSpread(_objectSpread({}, newShape.properties), {}, { width: width, height: height }) }); break; case "circle": var radius = Math.sqrt(Math.pow(x - newShape.properties.x, 2) + Math.pow(y - newShape.properties.y, 2)); updatedShape = _objectSpread(_objectSpread({}, newShape), {}, { properties: _objectSpread(_objectSpread({}, newShape.properties), {}, { radius: radius }) }); break; case "line": var points = [0, 0, x - newShape.properties.x, y - newShape.properties.y]; updatedShape = _objectSpread(_objectSpread({}, newShape), {}, { properties: _objectSpread(_objectSpread({}, newShape.properties), {}, { points: points }) }); break; default: return; } setNewShape(updatedShape); }, 100); /** * Handle mouse up event to finalize drawing and add the shape to the state. * * @param {Object} e - The mouse event object. */ var handleMouseUp = useCallback(function () { if (newShape) { setHistory(function (prevHistory) { return [].concat(_toConsumableArray(prevHistory), [shapes]); }); setRedoStack([]); setShapes(function (prevShapes) { return [].concat(_toConsumableArray(prevShapes), [newShape]); }); setIsDrawing(false); setSelectedShapeId(newShape.id); setNewShape(null); } }, [newShape, shapes]); /** * Handle shape selection by setting the selected shape's ID. * * @param {string} shapeId - The unique ID of the clicked shape. * @param {Object} e - The click event object. */ var handleSelectShape = useCallback(function (shapeId, e) { e.cancelBubble = true; setSelectedShapeId(shapeId); }, []); /** * Handle shape deselection by setting the selected shape to null. * * @param {Object} e - The click event object. */ var handleStageClick = function handleStageClick(e) { if (isFullScreen) return; if (e.target === e.target.getStage() || e.target.className === "Image") { setSelectedShapeId(null); } }; /** * Handle drag start event to change the cursor style. * * @param {Object} e - The event object. */ var handleDragStart = function handleDragStart(e) { setHistory(function (prevHistory) { return [].concat(_toConsumableArray(prevHistory), [shapes]); }); setRedoStack([]); e.target.getStage().container().style.cursor = "move"; }; /** * Handle drag end event to update the shape's position. * * @param {Object} e - The event object. * @param {string} shapeId - The ID of the shape being dragged. */ var handleDragEnd = useCallback(function (e, shapeId) { var x = rectPosititon.x, y = rectPosititon.y; if (x !== null && y !== null) { setShapes(function (prevShapes) { return prevShapes.map(function (shape) { return shape.id === shapeId ? _objectSpread(_objectSpread({}, shape), {}, { properties: _objectSpread(_objectSpread({}, shape.properties), {}, { x: x, y: y }) }) : shape; }); }); } e.target.getStage().container().style.cursor = "default"; }, [rectPosititon]); /** * Handle transform end event to update the shape's properties. * * @param {Object} e - The event object. * @param {string} shapeId - The ID of the shape being transformed. */ var handleTransformStart = useCallback(function () { document.body.style.cursor = 'nwse-resize'; setHistory(function (prevHistory) { return [].concat(_toConsumableArray(prevHistory), [shapes]); }); setRedoStack([]); }, [shapes]); var handleTransformEnd = useCallback(function (e, shapeId) { document.body.style.cursor = 'auto'; var node = e.target; var scaleX = node.scaleX(); var scaleY = node.scaleY(); node.scaleX(1); node.scaleY(1); if (!isFullScreen) { setShapes(function (prevShapes) { return prevShapes.map(function (shape) { if (shape.id !== shapeId) return shape; var type = shape.properties.type; var updatedProperties; switch (type) { case "rectangle": updatedProperties = _objectSpread(_objectSpread({}, shape.properties), {}, { x: node.x(), y: node.y(), width: node.width() * scaleX, height: node.height() * scaleY }); break; case "circle": updatedProperties = _objectSpread(_objectSpread({}, shape.properties), {}, { x: node.x(), y: node.y(), radius: node.radius() * scaleX // Assuming uniform scaling for radius }); break; case "line": updatedProperties = _objectSpread(_objectSpread({}, shape.properties), {}, { x: node.x(), y: node.y(), points: node.points().map(function (point, index) { return index % 2 === 0 ? point * scaleX : point * scaleY; }) // Scale points for the line }); break; default: return shape; // No changes for unknown types } return _objectSpread(_objectSpread({}, shape), {}, { properties: updatedProperties }); }); }); } }, [isFullScreen]); useEffect(function () { var _canvasParentRef$curr3, _canvasParentRef$curr4; setcanvasParentHeight(canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr3 = canvasParentRef.current) === null || _canvasParentRef$curr3 === void 0 ? void 0 : _canvasParentRef$curr3.offsetHeight); setcanvasParentWidth(canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr4 = canvasParentRef.current) === null || _canvasParentRef$curr4 === void 0 ? void 0 : _canvasParentRef$curr4.offsetWidth); }, [canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr5 = canvasParentRef.current) === null || _canvasParentRef$curr5 === void 0 ? void 0 : _canvasParentRef$curr5.offsetHeight, canvasParentRef === null || canvasParentRef === void 0 || (_canvasParentRef$curr6 = canvasParentRef.current) === null || _canvasParentRef$curr6 === void 0 ? void 0 : _canvasParentRef$curr6.offsetWidth]); /** * UNDO/REDO shortcut key events */ useEffect(function () { var handleKeyDown = function handleKeyDown(e) { if ((e.ctrlKey || e.metaKey) && e.key === "z") { undo(); } if ((e.ctrlKey || e.metaKey) && e.key === "y") { redo(); } if (e.key === "Delete") { deleteShape(); } }; window.addEventListener("keydown", handleKeyDown); return function () { window.removeEventListener("keydown", handleKeyDown); }; }, [undo, redo, deleteShape]); /** * Synchronize the transformer with the selected shape when the selected shape changes. */ useEffect(function () { if (selectedShapeId !== null && shapeRef.current[selectedShapeId]) { var _transformerRef$curre; transformerRef.current.nodes([shapeRef.current[selectedShapeId]]); (_transformerRef$curre = transformerRef.current.getLayer()) === null || _transformerRef$curre === void 0 || _transformerRef$curre.batchDraw(); } else { transformerRef.current.nodes([]); } }, [selectedShapeId]); /** * Update current time when the video plays. */ useEffect(function () { var handleTimeUpdate = function handleTimeUpdate() { var _videoRef$current; return setCurrentTime(videoRef === null || videoRef === void 0 || (_videoRef$current = videoRef.current) === null || _videoRef$current === void 0 ? void 0 : _videoRef$current.currentTime); }; var video = videoRef.current; video === null || video === void 0 || video.addEventListener("timeupdate", handleTimeUpdate); return function () { return video === null || video === void 0 ? void 0 : video.removeEventListener("timeupdate", handleTimeUpdate); }; }, [videoRef]); var isVisible = useCallback(function (shapeId) { var _shape$properties, _shape$properties2; var shape = shapes.find(function (shape) { return shape.id === shapeId; }); return currentTime >= (shape === null || shape === void 0 || (_shape$properties = shape.properties) === null || _shape$properties === void 0 ? void 0 : _shape$properties.startTime) && currentTime <= (shape === null || shape === void 0 || (_shape$properties2 = shape.properties) === null || _shape$properties2 === void 0 ? void 0 : _shape$properties2.endTime); }, [currentTime, shapes]); useEffect(function () { var _videoRef$current2; if (!((_videoRef$current2 = videoRef.current) !== null && _videoRef$current2 !== void 0 && _videoRef$current2.paused) || lockEdit || !isVisible(selectedShapeId)) { setSelectedShapeId(null); } }, [(_videoRef$current3 = videoRef.current) === null || _videoRef$current3 === void 0 ? void 0 : _videoRef$current3.paused, lockEdit, currentTime, isVisible, selectedShapeId]); var dragBoundFunc = function dragBoundFunc(pos) { var newX = Math.max(0, Math.min(pos.x, dimensions.width - shapeRef.current[selectedShapeId].width())); var newY = Math.max(0, Math.min(pos.y, dimensions.height - shapeRef.current[selectedShapeId].height())); return { x: newX, y: newY }; }; var handleDragMove = function handleDragMove(e) { var newX = Math.max(0, Math.min(e.target.x(), dimensions.width - shapeRef.current[selectedShapeId].width())); var newY = Math.max(0, Math.min(e.target.y(), dimensions.height - shapeRef.current[selectedShapeId].height())); setRectPosition({ x: newX, y: newY }); }; var _useState5 = useState(dimensions), _useState6 = _slicedToArray(_useState5, 2), imagedim = _useState6[0], setImgDim = _useState6[1]; useEffect(function () { var updateSize = function updateSize() { if (canvasParentRef.current) { var _canvasParentRef$curr7 = canvasParentRef.current, offsetWidth = _canvasParentRef$curr7.offsetWidth, offsetHeight = _canvasParentRef$curr7.offsetHeight; setDimensions({ width: offsetWidth, height: offsetHeight }); setImgDim({ width: offsetWidth, height: offsetHeight }); } }; updateSize(); window.addEventListener("resize", updateSize); return function () { return window.removeEventListener("resize", updateSize); }; }, []); var handleMouseEnterInStage = function handleMouseEnterInStage(e) { if (!selectedShapeTool) { e.target.getStage().container().style.cursor = "pointer"; } else { e.target.getStage().container().style.cursor = "crosshair"; } }; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { ref: canvasParentRef, style: { maxWidth: window.innerWidth, aspectRatio: "16/9", minHeight: 300, minWidth: 500, position: "relative" // backgroundColor: "red", } }, /*#__PURE__*/React.createElement(Player, { url: url, videoControls: videoControls, ref: videoRef, dimensions: imagedim, parentref: canvasParentRef }), /*#__PURE__*/React.createElement(Stage, { ref: stageRef, width: dimensions.width, height: dimensions.height, style: { backgroundColor: "black", display: hideAnnotations ? "none" : "block" }, onMouseEnter: handleMouseEnterInStage, onMouseLeave: function onMouseLeave(e) { return e.target.getStage().container().style.cursor = "default"; }, onMouseDown: !lockEdit && !isFullScreen && selectedShapeTool ? handleMouseDown : null, onMouseMove: !lockEdit && !isFullScreen && selectedShapeTool ? handleMouseMove : null, onMouseUp: !lockEdit && !isFullScreen && selectedShapeTool ? handleMouseUp : null, onClick: !isFullScreen ? function (e) { return handleStageClick(e); } : null }, /*#__PURE__*/React.createElement(Layer, { ref: layerRef }, shapes.filter(function (shape) { return currentTime >= shape.properties.startTime && currentTime <= shape.properties.endTime; }).map(function (shape) { var _stageRef$current, _stageRef$current2, _stageRef$current3, _stageRef$current4, _stageRef$current5, _stageRef$current6; switch (shape.properties.type) { case "rectangle": return /*#__PURE__*/React.createElement(Rectangle, _extends({ key: shape.id, ref: function ref(_ref2) { shapeRef.current[shape.id] = _ref2; } }, shape, { scaleX: (_stageRef$current = stageRef.current) === null || _stageRef$current === void 0 ? void 0 : _stageRef$current.scaleX(), scaleY: (_stageRef$current2 = stageRef.current) === null || _stageRef$current2 === void 0 ? void 0 : _stageRef$current2.scaleY(), onMouseEnter: handleMouseEnterInStage, draggable: !selectedShapeTool && !isFullScreen && !lockEdit && shape.id === selectedShapeId, onClick: !lockEdit && !isFullScreen && !selectedShapeTool ? function (e) { return handleSelectShape(shape.id, e); } : null, onDragEnd: selectedShapeId ? function (e) { return handleDragEnd(e, shape.id); } : null, onDragStart: selectedShapeId ? handleDragStart : null, onDragMove: selectedShapeId ? handleDragMove : null, dragBoundFunc: dragBoundFunc, onTransformEnd: selectedShapeId ? function (e) { return handleTransformEnd(e, shape.id); } : null, onTransformStart: selectedShapeId ? handleTransformStart : null, currentHeight: canvasParentHeight, currentWidth: canvasParentWidth })); case "circle": return /*#__PURE__*/React.createElement(CircleShape, _extends({ key: shape.id, ref: function ref(_ref3) { shapeRef.current[shape.id] = _ref3; } }, shape, { scaleX: (_stageRef$current3 = stageRef.current) === null || _stageRef$current3 === void 0 ? void 0 : _stageRef$current3.scaleX(), scaleY: (_stageRef$current4 = stageRef.current) === null || _stageRef$current4 === void 0 ? void 0 : _stageRef$current4.scaleY(), onMouseEnter: handleMouseEnterInStage, draggable: !selectedShapeTool && !isFullScreen && !lockEdit && shape.id === selectedShapeId, onClick: !lockEdit && !isFullScreen && !selectedShapeTool ? function (e) { return handleSelectShape(shape.id, e); } : null, onDragEnd: selectedShapeId ? function (e) { return handleDragEnd(e, shape.id); } : null, onDragStart: selectedShapeId ? handleDragStart : null, onDragMove: selectedShapeId ? handleDragMove : null, dragBoundFunc: dragBoundFunc, onTransformEnd: selectedShapeId ? function (e) { return handleTransformEnd(e, shape.id); } : null, onTransformStart: selectedShapeId ? handleTransformStart : null, currentHeight: canvasParentHeight, currentWidth: canvasParentWidth })); case "line": return /*#__PURE__*/React.createElement(LineShape, _extends({ key: shape.id, ref: function ref(_ref4) { shapeRef.current[shape.id] = _ref4; } }, shape, { scaleX: (_stageRef$current5 = stageRef.current) === null || _stageRef$current5 === void 0 ? void 0 : _stageRef$current5.scaleX(), scaleY: (_stageRef$current6 = stageRef.current) === null || _stageRef$current6 === void 0 ? void 0 : _stageRef$current6.scaleY(), onMouseEnter: handleMouseEnterInStage, draggable: !selectedShapeTool && !isFullScreen && !lockEdit && shape.id === selectedShapeId, onClick: !lockEdit && !isFullScreen && !selectedShapeTool ? function (e) { return handleSelectShape(shape.id, e); } : null, onDragEnd: selectedShapeId ? function (e) { return handleDragEnd(e, shape.id); } : null, onDragStart: selectedShapeId ? handleDragStart : null, onDragMove: selectedShapeId ? handleDragMove : null, dragBoundFunc: dragBoundFunc, onTransformEnd: selectedShapeId ? function (e) { return handleTransformEnd(e, shape.id); } : null, onTransformStart: selectedShapeId ? handleTransformStart : null, currentHeight: canvasParentHeight, currentWidth: canvasParentWidth })); default: return null; } }), newShape && /*#__PURE__*/React.createElement(React.Fragment, null, function (_newShape$properties, _newShape$properties2, _newShape$properties3, _newShape$properties4, _newShape$properties5, _newShape$properties6) { switch (newShape.properties.type) { case "rectangle": return /*#__PURE__*/React.createElement(Rect, { x: (_newShape$properties = newShape.properties) === null || _newShape$properties === void 0 ? void 0 : _newShape$properties.x, y: (_newShape$properties2 = newShape.properties) === null || _newShape$properties2 === void 0 ? void 0 : _newShape$properties2.y, width: newShape.properties.width, height: newShape.properties.height, stroke: "violet", opacity: 0.8 }); case "circle": return /*#__PURE__*/React.createElement(Circle, { x: (_newShape$properties3 = newShape.properties) === null || _newShape$properties3 === void 0 ? void 0 : _newShape$properties3.x, y: (_newShape$properties4 = newShape.properties) === null || _newShape$properties4 === void 0 ? void 0 : _newShape$properties4.y, radius: newShape.properties.radius, stroke: "violet", opacity: 0.8 }); case "line": return /*#__PURE__*/React.createElement(Line, { x: (_newShape$properties5 = newShape.properties) === null || _newShape$properties5 === void 0 ? void 0 : _newShape$properties5.x, y: (_newShape$properties6 = newShape.properties) === null || _newShape$properties6 === void 0 ? void 0 : _newShape$properties6.y, points: newShape.properties.points, stroke: "violet", opacity: 0.8 }); default: return null; } }()), /*#__PURE__*/React.createElement(Transformer, { ref: transformerRef, keepRatio: false, rotateEnabled: false, anchorSize: 7, anchorCornerRadius: 10 })))), /*#__PURE__*/React.createElement(TransparentVideoController, { playerRef: videoRef, dimensions: dimensions, canvasParentRef: canvasParentRef })); }); export default Canvas;