1+ import { useResizeObserver } from '@vueuse/core'
12import { computed , onMounted , onUnmounted , ref , watch } from 'vue'
23
34import type { LGraphNode , NodeId } from '@/lib/litegraph/src/LGraphNode'
@@ -68,7 +69,11 @@ export const useImageCrop = (nodeId: NodeId) => {
6869 const resizeStartCropWidth = ref ( 0 )
6970 const resizeStartCropHeight = ref ( 0 )
7071
71- let resizeObserver : ResizeObserver | null = null
72+ useResizeObserver ( containerEl , ( ) => {
73+ if ( imageEl . value && imageUrl . value ) {
74+ updateDisplayedDimensions ( )
75+ }
76+ } )
7277
7378 const getWidgetValue = ( name : string ) : number => {
7479 if ( ! node . value ) return 0
@@ -131,7 +136,11 @@ export const useImageCrop = (nodeId: NodeId) => {
131136 }
132137
133138 const updateImageUrl = ( ) => {
134- imageUrl . value = getInputImageUrl ( )
139+ const nextUrl = getInputImageUrl ( )
140+ if ( nextUrl !== imageUrl . value ) {
141+ imageUrl . value = nextUrl
142+ isLoading . value = ! ! nextUrl
143+ }
135144 }
136145
137146 const updateDisplayedDimensions = ( ) => {
@@ -143,6 +152,11 @@ export const useImageCrop = (nodeId: NodeId) => {
143152 naturalWidth . value = img . naturalWidth
144153 naturalHeight . value = img . naturalHeight
145154
155+ if ( naturalWidth . value <= 0 || naturalHeight . value <= 0 ) {
156+ scaleFactor . value = 1
157+ return
158+ }
159+
146160 const containerWidth = container . clientWidth
147161 const containerHeight = container . clientHeight
148162
@@ -161,20 +175,27 @@ export const useImageCrop = (nodeId: NodeId) => {
161175 imageOffsetY . value = 0
162176 }
163177
164- if ( naturalWidth . value > 0 && displayedWidth . value > 0 ) {
165- scaleFactor . value = displayedWidth . value / naturalWidth . value
166- } else {
178+ if ( naturalWidth . value <= 0 || displayedWidth . value <= 0 ) {
167179 scaleFactor . value = 1
180+ } else {
181+ scaleFactor . value = displayedWidth . value / naturalWidth . value
168182 }
169183 }
170184
171185 const getEffectiveScale = ( ) : number => {
172- if ( ! containerEl . value || naturalWidth . value === 0 ) return 1
186+ const container = containerEl . value
173187
174- const rect = containerEl . value . getBoundingClientRect ( )
188+ if ( ! container || naturalWidth . value <= 0 || displayedWidth . value <= 0 ) {
189+ return 1
190+ }
191+
192+ const rect = container . getBoundingClientRect ( )
193+ const clientWidth = container . clientWidth
194+
195+ if ( ! clientWidth || ! rect . width ) return 1
175196
176197 const renderedDisplayedWidth =
177- ( displayedWidth . value / containerEl . value . clientWidth ) * rect . width
198+ ( displayedWidth . value / clientWidth ) * rect . width
178199
179200 return renderedDisplayedWidth / naturalWidth . value
180201 }
@@ -335,22 +356,22 @@ export const useImageCrop = (nodeId: NodeId) => {
335356 const maxX = naturalWidth . value - cropWidth . value
336357 const maxY = naturalHeight . value - cropHeight . value
337358
338- const newX = Math . round (
359+ cropX . value = Math . round (
339360 Math . max ( 0 , Math . min ( maxX , dragStartCropX . value + deltaX ) )
340361 )
341- const newY = Math . round (
362+ cropY . value = Math . round (
342363 Math . max ( 0 , Math . min ( maxY , dragStartCropY . value + deltaY ) )
343364 )
344-
345- setWidgetValue ( 'x' , newX )
346- setWidgetValue ( 'y' , newY )
347365 }
348366
349367 const handleDragEnd = ( e : PointerEvent ) => {
350368 if ( ! isDragging . value ) return
351369
352370 isDragging . value = false
353371 releasePointer ( e )
372+
373+ setWidgetValue ( 'x' , cropX . value )
374+ setWidgetValue ( 'y' , cropY . value )
354375 }
355376
356377 const handleResizeStart = ( e : PointerEvent , direction : ResizeDirection ) => {
@@ -418,12 +439,12 @@ export const useImageCrop = (nodeId: NodeId) => {
418439 }
419440
420441 if ( affectsLeft || affectsRight ) {
421- setWidgetValue ( 'x' , Math . round ( newX ) )
422- setWidgetValue ( 'width' , Math . round ( newWidth ) )
442+ cropX . value = Math . round ( newX )
443+ cropWidth . value = Math . round ( newWidth )
423444 }
424445 if ( affectsTop || affectsBottom ) {
425- setWidgetValue ( 'y' , Math . round ( newY ) )
426- setWidgetValue ( 'height' , Math . round ( newHeight ) )
446+ cropY . value = Math . round ( newY )
447+ cropHeight . value = Math . round ( newHeight )
427448 }
428449 }
429450
@@ -433,31 +454,25 @@ export const useImageCrop = (nodeId: NodeId) => {
433454 isResizing . value = false
434455 resizeDirection . value = null
435456 releasePointer ( e )
457+
458+ setWidgetValue ( 'x' , cropX . value )
459+ setWidgetValue ( 'y' , cropY . value )
460+ setWidgetValue ( 'width' , cropWidth . value )
461+ setWidgetValue ( 'height' , cropHeight . value )
436462 }
437463
438464 const initialize = ( ) => {
439- if ( nodeId ) {
465+ if ( nodeId != null ) {
440466 node . value = app . rootGraph ?. getNodeById ( nodeId ) || null
441467 }
442468
443469 updateImageUrl ( )
444470 registerWidgetChangeHandler ( )
445471 syncCropFromWidgets ( )
446-
447- resizeObserver = new ResizeObserver ( ( ) => {
448- if ( imageEl . value && imageUrl . value ) {
449- updateDisplayedDimensions ( )
450- }
451- } )
452-
453- if ( containerEl . value ) {
454- resizeObserver . observe ( containerEl . value )
455- }
456472 }
457473
458474 const cleanup = ( ) => {
459475 unregisterWidgetChangeHandler ( )
460- resizeObserver ?. disconnect ( )
461476 }
462477
463478 watch (
0 commit comments