@@ -82,6 +82,7 @@ export function ScreenshotEditorFactory({
8282 const croppingRef = hooks . useRef < HTMLCanvasElement > ( null ) ;
8383 const [ croppingRect , setCroppingRect ] = hooks . useState < Box > ( { startX : 0 , startY : 0 , endX : 0 , endY : 0 } ) ;
8484 const [ confirmCrop , setConfirmCrop ] = hooks . useState ( false ) ;
85+ const [ isResizing , setIsResizing ] = hooks . useState ( false ) ;
8586
8687 hooks . useEffect ( ( ) => {
8788 WINDOW . addEventListener ( 'resize' , resizeCropper , false ) ;
@@ -141,11 +142,13 @@ export function ScreenshotEditorFactory({
141142
142143 function onGrabButton ( e : Event , corner : string ) : void {
143144 setConfirmCrop ( false ) ;
145+ setIsResizing ( true ) ;
144146 const handleMouseMove = makeHandleMouseMove ( corner ) ;
145147 const handleMouseUp = ( ) : void => {
146148 DOCUMENT . removeEventListener ( 'mousemove' , handleMouseMove ) ;
147149 DOCUMENT . removeEventListener ( 'mouseup' , handleMouseUp ) ;
148150 setConfirmCrop ( true ) ;
151+ setIsResizing ( false ) ;
149152 } ;
150153
151154 DOCUMENT . addEventListener ( 'mouseup' , handleMouseUp ) ;
@@ -194,6 +197,56 @@ export function ScreenshotEditorFactory({
194197 } ;
195198 } , [ ] ) ;
196199
200+ // DRAGGING FUNCTIONALITY.
201+ const initialPositionRef = hooks . useRef ( { initialX : 0 , initialY : 0 } ) ;
202+
203+ function onDragStart ( e : MouseEvent ) : void {
204+ if ( isResizing ) return ;
205+
206+ initialPositionRef . current = { initialX : e . clientX , initialY : e . clientY } ;
207+
208+ const handleMouseMove = ( moveEvent : MouseEvent ) : void => {
209+ const cropCanvas = croppingRef . current ;
210+ if ( ! cropCanvas ) return ;
211+
212+ const deltaX = moveEvent . clientX - initialPositionRef . current . initialX ;
213+ const deltaY = moveEvent . clientY - initialPositionRef . current . initialY ;
214+
215+ setCroppingRect ( prev => {
216+ // Math.max stops it from going outside of the borders
217+ const newStartX = Math . max (
218+ 0 ,
219+ Math . min ( prev . startX + deltaX , cropCanvas . width / DPI - ( prev . endX - prev . startX ) ) ,
220+ ) ;
221+ const newStartY = Math . max (
222+ 0 ,
223+ Math . min ( prev . startY + deltaY , cropCanvas . height / DPI - ( prev . endY - prev . startY ) ) ,
224+ ) ;
225+ // Don't want to change size, just position
226+ const newEndX = newStartX + ( prev . endX - prev . startX ) ;
227+ const newEndY = newStartY + ( prev . endY - prev . startY ) ;
228+
229+ initialPositionRef . current . initialX = moveEvent . clientX ;
230+ initialPositionRef . current . initialY = moveEvent . clientY ;
231+
232+ return {
233+ startX : newStartX ,
234+ startY : newStartY ,
235+ endX : newEndX ,
236+ endY : newEndY ,
237+ } ;
238+ } ) ;
239+ } ;
240+
241+ const handleMouseUp = ( ) : void => {
242+ DOCUMENT . removeEventListener ( 'mousemove' , handleMouseMove ) ;
243+ DOCUMENT . removeEventListener ( 'mouseup' , handleMouseUp ) ;
244+ } ;
245+
246+ DOCUMENT . addEventListener ( 'mousemove' , handleMouseMove ) ;
247+ DOCUMENT . addEventListener ( 'mouseup' , handleMouseUp ) ;
248+ }
249+
197250 function submit ( ) : void {
198251 const cutoutCanvas = DOCUMENT . createElement ( 'canvas' ) ;
199252 const imageBox = constructRect ( getContainedSize ( imageBuffer ) ) ;
@@ -263,7 +316,11 @@ export function ScreenshotEditorFactory({
263316 < style dangerouslySetInnerHTML = { styles } />
264317 < div class = "editor__canvas-container" ref = { canvasContainerRef } >
265318 < div class = "editor__crop-container" style = { { position : 'absolute' , zIndex : 1 } } ref = { cropContainerRef } >
266- < canvas style = { { position : 'absolute' } } ref = { croppingRef } > </ canvas >
319+ < canvas
320+ onMouseDown = { onDragStart }
321+ style = { { position : 'absolute' , cursor : confirmCrop ? 'move' : 'auto' } }
322+ ref = { croppingRef }
323+ > </ canvas >
267324 < CropCorner
268325 left = { croppingRect . startX - CROP_BUTTON_BORDER }
269326 top = { croppingRect . startY - CROP_BUTTON_BORDER }
0 commit comments