11import React , { FunctionComponent } from "react" ;
22import { Stage , Layer , Image } from "react-konva" ;
33import { RectConfig } from "konva/types/shapes/Rect" ;
4- import Rectangle from "./Rectangle" ;
4+ import Rectangle , { MIN_RECT_SIDE_PIXEL } from "./Rectangle" ;
55import { KonvaEventObject } from "konva/types/Node" ;
66import { IgnoreArea } from "../types/ignoreArea" ;
77
@@ -25,6 +25,7 @@ interface IDrawArea {
2525 React . Dispatch < React . SetStateAction < { x : number ; y : number } > >
2626 ] ;
2727 stageScaleState : [ number , React . Dispatch < React . SetStateAction < number > > ] ;
28+ drawModeState : [ boolean , React . Dispatch < React . SetStateAction < boolean > > ] ;
2829}
2930const DrawArea : FunctionComponent < IDrawArea > = ( {
3031 image,
@@ -37,20 +38,67 @@ const DrawArea: FunctionComponent<IDrawArea> = ({
3738 stageOffsetState,
3839 stageInitPosState,
3940 stagePosState,
41+ drawModeState,
4042} ) => {
4143 const [ stageInitPos , setStageInitPos ] = stageInitPosState ;
4244 const [ stageOffset , setStageOffset ] = stageOffsetState ;
4345 const [ stagePos , setStagePos ] = stagePosState ;
4446 const [ stageScale ] = stageScaleState ;
4547 const [ isDrag , setIsDrag ] = React . useState ( false ) ;
4648
49+ const [ isDrawMode , setIsDrawMode ] = drawModeState ;
50+ const [ isDrawing , setIsDrawing ] = React . useState ( isDrawMode ) ;
51+
52+ const handleContentMousedown = ( e : any ) => {
53+ if ( ! isDrawMode ) return ;
54+
55+ const newArea : IgnoreArea = {
56+ id : Date . now ( ) . toString ( ) ,
57+ x : Math . round ( ( e . evt . layerX - stageOffset . x ) / stageScale ) ,
58+ y : Math . round ( ( e . evt . layerY - stageOffset . y ) / stageScale ) ,
59+ width : MIN_RECT_SIDE_PIXEL ,
60+ height : MIN_RECT_SIDE_PIXEL ,
61+ } ;
62+ setIgnoreAreas ( [ ...ignoreAreas , newArea ] ) ;
63+ setSelectedRectId ( newArea . id ) ;
64+ setIsDrawing ( true ) ;
65+ } ;
66+
67+ const handleContentMouseup = ( e : any ) => {
68+ if ( isDrawing ) {
69+ setIsDrawing ( ! isDrawing ) ;
70+ setIsDrawMode ( false ) ;
71+ }
72+ } ;
73+
74+ const handleContentMouseMove = ( e : any ) => {
75+ if ( ! isDrawMode ) return ;
76+
77+ if ( isDrawing ) {
78+ // update the current rectangle's width and height based on the mouse position + stage scale
79+ const mouseX = ( e . evt . layerX - stageOffset . x ) / stageScale ;
80+ const mouseY = ( e . evt . layerY - stageOffset . y ) / stageScale ;
81+
82+ const newShapesList = ignoreAreas . map ( ( i ) => {
83+ if ( i . id === selectedRectId ) {
84+ // new width and height
85+ i . width = Math . max ( Math . round ( mouseX - i . x ) , MIN_RECT_SIDE_PIXEL ) ;
86+ i . height = Math . max ( Math . round ( mouseY - i . y ) , MIN_RECT_SIDE_PIXEL ) ;
87+ return i ;
88+ }
89+ return i ;
90+ } ) ;
91+ setIgnoreAreas ( newShapesList ) ;
92+ }
93+ } ;
94+
4795 return (
4896 < div
4997 style = { {
5098 transform : `translate3d(${ stagePos . x } px, ${ stagePos . y } px, 0px)` ,
5199 } }
52100 onMouseMove = { ( event ) => {
53- if ( isDrag && ! selectedRectId ) {
101+ if ( ! isDrawMode && isDrag && ! selectedRectId ) {
54102 event . preventDefault ( ) ;
55103 setStagePos ( {
56104 x : event . clientX - stageInitPos . x ,
@@ -83,12 +131,15 @@ const DrawArea: FunctionComponent<IDrawArea> = ({
83131 transform : `scale(${ stageScale } )` ,
84132 transformOrigin : "top left" ,
85133 } }
134+ onContentMousedown = { handleContentMousedown }
135+ onContentMouseup = { handleContentMouseup }
136+ onContentMouseMove = { handleContentMouseMove }
86137 >
87138 < Layer >
88139 < Image
89140 image = { image }
90141 onMouseOver = { ( event ) => {
91- document . body . style . cursor = "grab" ;
142+ document . body . style . cursor = isDrawMode ? "crosshair" : "grab" ;
92143 } }
93144 onMouseDown = { ( event ) => {
94145 document . body . style . cursor = "grabbing" ;
@@ -117,8 +168,12 @@ const DrawArea: FunctionComponent<IDrawArea> = ({
117168
118169 rects [ i ] . x = Math . round ( newAttrs . x || 0 ) ;
119170 rects [ i ] . y = Math . round ( newAttrs . y || 0 ) ;
120- rects [ i ] . width = Math . round ( newAttrs . width || 0 ) ;
121- rects [ i ] . height = Math . round ( newAttrs . height || 0 ) ;
171+ rects [ i ] . width = Math . round (
172+ newAttrs . width || MIN_RECT_SIDE_PIXEL
173+ ) ;
174+ rects [ i ] . height = Math . round (
175+ newAttrs . height || MIN_RECT_SIDE_PIXEL
176+ ) ;
122177
123178 setIgnoreAreas ( rects ) ;
124179 } }
0 commit comments