@@ -76,9 +76,17 @@ <h1>Social Media Card Cropper</h1>
7676 < label style ="margin-right: 10px; ">
7777 < input type ="radio " name ="aspectRatio " value ="2 " checked > 2:1 ratio
7878 </ label >
79- < label >
79+ < label style =" margin-right: 10px; " >
8080 < input type ="radio " name ="aspectRatio " value ="1.4 "> 14:10 ratio
8181 </ label >
82+ < div style ="margin-top: 10px; ">
83+ < label for ="backgroundColor "> Background color:</ label >
84+ < input type ="color " id ="backgroundColor " value ="#ffffff ">
85+ </ div >
86+ < div style ="margin-top: 10px; ">
87+ < button id ="zoomInBtn " type ="button " style ="margin-right: 5px; "> Zoom +</ button >
88+ < button id ="zoomOutBtn " type ="button "> Zoom -</ button >
89+ </ div >
8290 </ div >
8391
8492 < div class ="drop-zone " id ="dropZone ">
@@ -105,6 +113,9 @@ <h3>Preview (0.7 quality JPEG)</h3>
105113 let cropper = null ;
106114 const dropZone = document . getElementById ( 'dropZone' ) ;
107115 const fileInput = document . getElementById ( 'fileInput' ) ;
116+ const backgroundColor = document . getElementById ( 'backgroundColor' ) ;
117+ const zoomInBtn = document . getElementById ( 'zoomInBtn' ) ;
118+ const zoomOutBtn = document . getElementById ( 'zoomOutBtn' ) ;
108119
109120 // Handle paste events
110121 document . addEventListener ( 'paste' , ( e ) => {
@@ -158,6 +169,37 @@ <h3>Preview (0.7 quality JPEG)</h3>
158169 }
159170 } ) ;
160171 } ) ;
172+
173+ // Listen for background color changes and update the cropper
174+ backgroundColor . addEventListener ( 'change' , ( ) => {
175+ if ( cropper ) {
176+ initCropper ( ) ;
177+ }
178+ } ) ;
179+
180+ // Handle zoom buttons
181+ zoomInBtn . addEventListener ( 'click' , ( ) => {
182+ if ( cropper ) {
183+ cropper . zoom ( 0.1 ) ;
184+ }
185+ } ) ;
186+
187+ zoomOutBtn . addEventListener ( 'click' , ( ) => {
188+ if ( cropper ) {
189+ cropper . zoom ( - 0.1 ) ;
190+ // Force update canvas size to allow zooming out beyond image boundaries
191+ const canvasData = cropper . getCanvasData ( ) ;
192+ const newWidth = canvasData . width * 0.9 ;
193+ const newHeight = canvasData . height * 0.9 ;
194+
195+ cropper . setCanvasData ( {
196+ width : newWidth ,
197+ height : newHeight ,
198+ left : canvasData . left + ( canvasData . width - newWidth ) / 2 ,
199+ top : canvasData . top + ( canvasData . height - newHeight ) / 2
200+ } ) ;
201+ }
202+ } ) ;
161203
162204 function handleFile ( file ) {
163205 if ( ! file . type . startsWith ( 'image/' ) ) {
@@ -185,26 +227,68 @@ <h3>Preview (0.7 quality JPEG)</h3>
185227
186228 cropper = new Cropper ( image , {
187229 aspectRatio : ratio ,
188- viewMode : 1 ,
230+ viewMode : 0 , // Changed to 0 for no restrictions
189231 dragMode : 'move' ,
190- autoCropArea : 1 ,
232+ autoCropArea : 0.8 ,
191233 restore : false ,
192234 guides : true ,
193235 center : true ,
194236 highlight : false ,
195237 cropBoxMovable : true ,
196- cropBoxResizable : false ,
238+ cropBoxResizable : true ,
197239 toggleDragModeOnDblclick : false ,
240+ minCropBoxWidth : 100 ,
241+ minCropBoxHeight : 100 ,
242+ minCanvasWidth : 0 ,
243+ minCanvasHeight : 0 ,
244+ background : true ,
198245 crop : updatePreview
199246 } ) ;
200247 }
201248
202249 function updatePreview ( ) {
203250 if ( ! cropper ) return ;
204251
205- const canvas = cropper . getCroppedCanvas ( ) ;
206- if ( ! canvas ) return ;
207-
252+ // Create a larger canvas with the background color
253+ const crop = cropper . getData ( ) ;
254+ const canvas = document . createElement ( 'canvas' ) ;
255+ const ctx = canvas . getContext ( '2d' ) ;
256+
257+ // Get the selected aspect ratio
258+ const aspectRatioValue = document . querySelector ( 'input[name="aspectRatio"]:checked' ) . value ;
259+ const ratio = parseFloat ( aspectRatioValue ) ;
260+
261+ // Set canvas dimensions to the desired aspect ratio
262+ if ( ratio === 2 ) {
263+ canvas . width = 1200 ;
264+ canvas . height = 600 ;
265+ } else {
266+ canvas . width = 1400 ;
267+ canvas . height = 1000 ;
268+ }
269+
270+ // Fill with background color
271+ ctx . fillStyle = backgroundColor . value ;
272+ ctx . fillRect ( 0 , 0 , canvas . width , canvas . height ) ;
273+
274+ // Get the cropped canvas
275+ const croppedCanvas = cropper . getCroppedCanvas ( ) ;
276+ if ( ! croppedCanvas ) return ;
277+
278+ // Calculate dimensions to center the image
279+ const scale = Math . min (
280+ canvas . width / croppedCanvas . width ,
281+ canvas . height / croppedCanvas . height
282+ ) * 0.9 ; // Scale slightly down to add padding
283+
284+ const scaledWidth = croppedCanvas . width * scale ;
285+ const scaledHeight = croppedCanvas . height * scale ;
286+ const x = ( canvas . width - scaledWidth ) / 2 ;
287+ const y = ( canvas . height - scaledHeight ) / 2 ;
288+
289+ // Draw the cropped image centered on the background
290+ ctx . drawImage ( croppedCanvas , x , y , scaledWidth , scaledHeight ) ;
291+
208292 // Convert to JPEG with 0.7 quality
209293 const previewUrl = canvas . toDataURL ( 'image/jpeg' , 0.7 ) ;
210294 preview . src = previewUrl ;
0 commit comments