@@ -448,29 +448,106 @@ const Board = React.forwardRef<BoardActions, BoardProps>(
448448 obj : fabricTypes . CustomObject ,
449449 includeContent = true ,
450450 ) => {
451- const width = editor ?. canvas . getWidth ( ) ?? 0 ;
452- const height = editor ?. canvas . getHeight ( ) ?? 0 ;
451+ const width1 = editor ?. canvas . getWidth ( ) ?? 0 ;
452+ const height1 = editor ?. canvas . getHeight ( ) ?? 0 ;
453453 const updatedCoordPoints = fabricUtils . pointsInCanvas ( obj ) ;
454454 const updatedCoords = updatedCoordPoints . map ( ( p ) =>
455455 fabricUtils . toOriginalCoord ( {
456456 cInfo : {
457- width,
458- height,
457+ width : width1 ,
458+ height : height1 ,
459459 } ,
460460 iInfo : imageSize ,
461461 coord : p ,
462462 scaleRatio,
463463 } ) ,
464464 ) ;
465+ // Assume updatedCoords is an array of points [{ x: Number, y: Number }, ...]
466+ const p0 = updatedCoords [ 0 ] ;
467+ const p1 = updatedCoords [ 1 ] ;
468+ const p2 = updatedCoords [ 2 ] ;
469+
470+ // Calculate the angle between the first two points
471+ const angle = Math . atan2 ( p1 . y - p0 . y , p1 . x - p0 . x ) ;
472+
473+ // Function to calculate the distance between two points
474+ function distance (
475+ pA : {
476+ x : number ;
477+ y : number ;
478+ } ,
479+ pB : {
480+ x : number ;
481+ y : number ;
482+ } ,
483+ ) {
484+ return Math . hypot ( pB . x - pA . x , pB . y - pA . y ) ;
485+ }
486+
487+ // Calculate the width and height of the rotated area
488+ const width = distance ( p0 , p1 ) ;
489+ const height = distance ( p1 , p2 ) ;
490+
491+ // Calculate the center point of the polygon
492+ const centerX = ( p0 . x + p2 . x ) / 2 ;
493+ const centerY = ( p0 . y + p2 . y ) / 2 ;
494+
495+ // Create an off-screen canvas with the dimensions of the rotated area
496+ const offscreenCanvas = document . createElement ( "canvas" ) ;
497+ offscreenCanvas . width = width ;
498+ offscreenCanvas . height = height ;
499+
500+ const ctx = offscreenCanvas . getContext ( "2d" ) ;
501+
502+ // Function to transform points according to the canvas transformations
503+ function transformPoint ( p : { x : number ; y : number } ) {
504+ // Translate points to the origin (center of the polygon)
505+ const x = p . x - centerX ;
506+ const y = p . y - centerY ;
507+
508+ // Rotate points by the negative angle to align them vertically
509+ const sin = Math . sin ( - angle ) ;
510+ const cos = Math . cos ( - angle ) ;
511+
512+ const xRotated = x * cos - y * sin ;
513+ const yRotated = x * sin + y * cos ;
514+
515+ // Translate points to the canvas coordinate system
516+ const xTransformed = xRotated + width / 2 ;
517+ const yTransformed = yRotated + height / 2 ;
518+
519+ return { x : xTransformed , y : yTransformed } ;
520+ }
521+
522+ // Transform the updatedCoords to match the canvas coordinate system
523+ const transformedCoords = updatedCoords . map ( transformPoint ) ;
524+
525+ // Define the clipping path using the transformed coordinates
526+ ctx ! . beginPath ( ) ;
527+ transformedCoords . forEach ( ( point , index ) => {
528+ if ( index === 0 ) {
529+ ctx ! . moveTo ( point . x , point . y ) ;
530+ } else {
531+ ctx ! . lineTo ( point . x , point . y ) ;
532+ }
533+ } ) ;
534+ ctx ! . closePath ( ) ;
535+ ctx ! . clip ( ) ;
536+
537+ // Apply transformations to the context to align the image correctly
538+ ctx ! . translate ( width / 2 , height / 2 ) ;
539+ ctx ! . rotate ( - angle ) ;
540+ ctx ! . translate ( - centerX , - centerY ) ;
541+
542+ // Draw the original image onto the transformed context
543+ ctx ! . drawImage ( originalFabricImage ! . getElement ( ) , 0 , 0 ) ;
544+
545+ // Export the rotated and cropped image
546+ const dataURL = offscreenCanvas . toDataURL ( ) ;
465547
466548 return {
467549 coords : updatedCoords ,
468- content : includeContent
469- ? originalFabricImage ?. toDataURL ( {
470- withoutTransform : true ,
471- ...fabricUtils . getBoundingBox ( updatedCoords ) ,
472- } )
473- : undefined ,
550+ content : includeContent ? dataURL : undefined ,
474551 } ;
475552 } ;
476553
0 commit comments