From 6cebc4d1df6951373382f116c0ba74019304ee8b Mon Sep 17 00:00:00 2001 From: NicolasChampionRoadCare Date: Wed, 19 Jan 2022 11:24:25 +0100 Subject: [PATCH] v0.3.12 (#49) - Event on contextmenu - Delete last point --- package.json | 2 +- src/annotation-engine/stories.tsx | 48 ++++++++++++----- .../use-annotation-engine.ts | 51 ++++++++++--------- src/basic-annotation-engine/index.tsx | 3 ++ 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 8c438c8..6927b61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@thetribe/react-components", - "version": "0.3.11", + "version": "0.3.12", "description": "Library of generic React components", "main": "dist/bundle.js", "types": "dist/index.d.ts", diff --git a/src/annotation-engine/stories.tsx b/src/annotation-engine/stories.tsx index ccea853..2f74334 100644 --- a/src/annotation-engine/stories.tsx +++ b/src/annotation-engine/stories.tsx @@ -118,7 +118,7 @@ const useEngineStateMachine = ( const isModeCreation = () => !isModeEdition() && numberOfPoints > 0; const isModeInactif = () => !isModeCreation() && !isModeEdition(); // key codes map for shape validation (polygon and polylines) - const shapeFinishedOnKeyCodes = ['Space']; + const shapeFinishedOnKeyCodes = ['Space', 'Enter']; const cancelOnKeyCodes = ['Escape']; const initState = () => ({ @@ -133,6 +133,7 @@ const useEngineStateMachine = ( // Cancel edition setAnnotationToEdit(undefined); // Cancel creation + setShapeType('INACTIVE'); refAE.current?.cancelCreation(); }; @@ -231,6 +232,8 @@ const useEngineStateMachine = ( } } + const isLeftClick = (event: Events) => event.event.button === 0; + const isRightClick = (event: Events) => event.event.button === 2; const createNewPoint = (at: Coordinates, operations: Operations): number => operations.addPoint(at); const shapeFinished = (currentGeometry: Coordinates[]) => { @@ -245,13 +248,23 @@ const useEngineStateMachine = ( styleOps.setStyleExclusivelyToAnnotationId(clickStyle, id); }; - const keyDownEvent = (event: KeyDownEvent) => { + const keyPreventDefault = (event: KeyDownEvent) => { if (event.event.code === 'Space') { // avoid page scrolldown on space key up event.event.preventDefault(); } } - + const keyDownEventWhileCreation = (event:KeyDownEvent , operations:Operations)=> { + switch(event.event.key) { + case "Backspace": { + const lastPoint = operations.deleteLastPoint(); + styleOps.setStyleExclusivelyToPointId(hiddenStyle, lastPoint.toString()); + break; + } + default: + break; + } + } const keyUpEvent = (event: KeyUpEvent) => { if (shapeFinishedOnKeyCodes.includes(event.event.code) && isGeometryReadyToBeManuallyCompleted(event.currentGeometry.length)) { shapeFinished(event.currentGeometry); @@ -274,9 +287,10 @@ const useEngineStateMachine = ( if (isModeInactif()) { switch (event.type) { case 'mouse_down_on_annotation_event': - setSelectedItemId(event.annotationsId[0]); - styleOps.setStyleExclusivelyToAnnotationId(clickStyle, event.annotationsId[0]); - + if (isLeftClick(event)) { + setSelectedItemId(event.annotationsId[0]); + styleOps.setStyleExclusivelyToAnnotationId(clickStyle, event.annotationsId[0]); + } break; case 'mouse_move_on_annotation_event': { @@ -303,22 +317,30 @@ const useEngineStateMachine = ( } if (isModeCreation()) { switch (event.type) { - + case 'context_menu_event': + event.event.preventDefault(); + break; case 'key_down_event': - keyDownEvent(event); + keyDownEventWhileCreation(event, operations); + keyPreventDefault(event); break; case 'key_up_event': keyUpEvent(event); break; case 'mouse_down_on_annotation_event': case 'mouse_down_on_existing_point_event': - case 'mouse_down_event': - if (event.currentGeometry.length === 0) { + case 'mouse_down_event': { + if (isLeftClick(event) && event.currentGeometry.length === 0) { operations.addPoint(event.at); styleOps.setStyleExclusivelyToPointId(hiddenStyle, '0'); } styleOps.removeStyleFromPointsByStyleNames(hiddenStyle.name); + if (isRightClick(event)) { + const lastPoint = operations.deleteLastPoint(); + styleOps.setStyleExclusivelyToPointId(hiddenStyle, lastPoint.toString()); + } break; + } case 'mouse_move_on_existing_point_event': if (isPolygonReadyToBeManuallyCompletedByClickOnFirstPoint(event.currentGeometry, event.pointIds)) { styleOps.setStyleExclusivelyToPointId(highlightStyle, '0'); @@ -345,7 +367,9 @@ const useEngineStateMachine = ( } break; case 'mouse_up_event': - mouseUpEvent(event, operations); + if(isLeftClick(event)) { + mouseUpEvent(event, operations); + } break; case 'context_menu_event': event.event.preventDefault() @@ -357,7 +381,7 @@ const useEngineStateMachine = ( if (isModeEdition()) { switch (event.type) { case 'key_down_event': - keyDownEvent(event); + keyPreventDefault(event); break; case 'key_up_event': keyUpEvent(event); diff --git a/src/annotation-engine/use-annotation-engine.ts b/src/annotation-engine/use-annotation-engine.ts index 951f4c2..c56b3b8 100644 --- a/src/annotation-engine/use-annotation-engine.ts +++ b/src/annotation-engine/use-annotation-engine.ts @@ -32,7 +32,7 @@ export type Events = | MouseUpOnExistingPointEvent | MouseWheelEvent | contextMenuEvent; - + export type OnEvent = (event: Events, operations: Operations) => void; export interface MouseDownEvent { @@ -129,6 +129,7 @@ export interface Operations { movePoint(pointId: PointId, to: Coordinates): void; finishCurrentLine(): void; drawOnCanvas(draw: (context2d: CanvasRenderingContext2D) => void): void; + deleteLastPoint(): number; } const useAnnotationEngine = ({ @@ -171,8 +172,8 @@ const useAnnotationEngine = ({ } if (!isPointAnnotation(pathData)) { - return pathData.lines.some((line) => renderingContext?.isPointInStroke(line, x, y)) - } + return pathData.lines.some((line) => renderingContext?.isPointInStroke(line, x, y)); + } return false; } @@ -268,6 +269,7 @@ const useAnnotationEngine = ({ const currentCanvasRef = canvasRef.current; let delayDraw: Array<(context2d: CanvasRenderingContext2D) => void> = []; const operations: Operations = { + // -1 is here because he return also the index of the array of points addPoint: (at: Coordinates) => annotationToEditPointsRef.current.push(at) - 1, movePoint: (pointId: PointId, to: Coordinates): void => { annotationToEditPointsRef.current[pointId] = to; @@ -278,14 +280,19 @@ const useAnnotationEngine = ({ drawOnCanvas: (draw: (context2d: CanvasRenderingContext2D) => void) => { delayDraw.push(draw); }, + deleteLastPoint: () => { + annotationToEditPointsRef.current.splice((annotationToEditPointsRef.current).length - 2, 1); + + return annotationToEditPointsRef.current.length - 1; + } }; const clickedExistingPointsIds = (coordinates: Array, clickAt: Coordinates): Array => { const newCoordinates = [...coordinates]; if (!annotationToEdit) { - newCoordinates.pop() + newCoordinates.pop(); } - + return newCoordinates .map((coordinate, idx) => ({ coordinate, idx })) .filter(({ coordinate }) => areCoordinatesInsideCircle(coordinate, clickAt, EXISTING_POINT_RADIUS_DETECTION)) @@ -321,8 +328,8 @@ const useAnnotationEngine = ({ event, }, operations, - ); - } else { + ); + } else { const currentGeometry = [...annotationToEditPointsRef.current]; onEvent( { @@ -360,8 +367,8 @@ const useAnnotationEngine = ({ }, operations, ) - } - + } + if (clickedPointIds.length > 0) { return onEvent( @@ -374,8 +381,8 @@ const useAnnotationEngine = ({ }, operations, ); - } - + } + return onEvent( { type: 'mouse_down_event', @@ -385,7 +392,7 @@ const useAnnotationEngine = ({ }, operations, ); - + }); const handleMouseMove = (event: MouseEvent) => @@ -400,7 +407,7 @@ const useAnnotationEngine = ({ return ({ id, style }); }) - + return onEvent( { type: 'mouse_move_on_annotation_event', @@ -425,8 +432,7 @@ const useAnnotationEngine = ({ }, operations, ); - } - + } return onEvent( { type: 'mouse_move_event', @@ -477,15 +483,14 @@ const useAnnotationEngine = ({ const handleContextMenu = (event: MouseEvent) => handleEvent(() => { - onEvent( - { - type: 'context_menu_event', - event, - }, - operations, - ); + onEvent( + { + type: 'context_menu_event', + event, + }, + operations, + ); }); - if (currentCanvasRef) { const canvasRenderingContext = currentCanvasRef.getContext('2d'); diff --git a/src/basic-annotation-engine/index.tsx b/src/basic-annotation-engine/index.tsx index cc42316..645526d 100644 --- a/src/basic-annotation-engine/index.tsx +++ b/src/basic-annotation-engine/index.tsx @@ -64,6 +64,9 @@ const BasicAnnotationEngine: FC = ({ } } break; + case 'context_menu_event': + event.event.preventDefault(); + break; case 'mouse_up_on_existing_point_event': case 'mouse_up_event': if (state.current.dragOngoing) {