@@ -14,6 +14,21 @@ import { PresetManagerDialog } from "./utils/PresetManagerDialog.js";
1414const log = createModuleLogger ( 'ResolutionMaster' ) ;
1515
1616class ResolutionMasterCanvas {
17+ // Category mapping for UI to backend widget conversion
18+ static CATEGORY_MAPPING = {
19+ 'Flux' : 'SD1.5/SDXL' ,
20+ 'Flux.2' : 'Flux.2' ,
21+ 'Standard' : 'SD1.5/SDXL' ,
22+ 'SDXL' : 'SD1.5/SDXL' ,
23+ 'Social Media' : 'SD1.5/SDXL' ,
24+ 'Print' : 'SD1.5/SDXL' ,
25+ 'Cinema' : 'SD1.5/SDXL' ,
26+ 'Display Resolutions' : 'SD1.5/SDXL' ,
27+ 'WAN' : 'SD1.5/SDXL' ,
28+ 'HiDream Dev' : 'SD1.5/SDXL' ,
29+ 'Qwen-Image' : 'SD1.5/SDXL'
30+ } ;
31+
1732 constructor ( node ) {
1833 this . node = node ;
1934
@@ -259,22 +274,7 @@ class ResolutionMasterCanvas {
259274
260275 // Initialize category widget from properties
261276 if ( categoryWidget ) {
262- // Map UI category to backend category
263- const categoryMapping = {
264- 'Flux' : 'SD1.5/SDXL' ,
265- 'Flux.2' : 'Flux.2' ,
266- 'Standard' : 'SD1.5/SDXL' ,
267- 'SDXL' : 'SD1.5/SDXL' ,
268- 'Social Media' : 'SD1.5/SDXL' ,
269- 'Print' : 'SD1.5/SDXL' ,
270- 'Cinema' : 'SD1.5/SDXL' ,
271- 'Display Resolutions' : 'SD1.5/SDXL' ,
272- 'WAN' : 'SD1.5/SDXL' ,
273- 'HiDream Dev' : 'SD1.5/SDXL' ,
274- 'Qwen-Image' : 'SD1.5/SDXL'
275- } ;
276-
277- const backendCategory = categoryMapping [ node . properties . selectedCategory ] || 'SD1.5/SDXL' ;
277+ const backendCategory = ResolutionMasterCanvas . CATEGORY_MAPPING [ node . properties . selectedCategory ] || 'SD1.5/SDXL' ;
278278 categoryWidget . value = backendCategory ;
279279 }
280280
@@ -760,66 +760,34 @@ class ResolutionMasterCanvas {
760760
761761 drawScalingGrid ( ctx , y ) {
762762 const margin = 20 ;
763- this . drawScaleRow ( ctx , margin , y ) ;
764- this . drawResolutionRow ( ctx , margin , y + 35 ) ;
765- this . drawMegapixelsRow ( ctx , margin , y + 70 ) ;
766- return 105 ;
767- }
768-
769- drawScaleRow ( ctx , x , y ) {
770763 const props = this . node . properties ;
771- this . drawScalingRowBase ( ctx , x , y , {
772- buttonControl : 'scaleBtn' ,
773- mainControl : 'scaleSlider' ,
774- radioControl : 'upscaleRadio' ,
775- controlType : 'slider' ,
776- icon : this . icons . upscale ,
777- valueProperty : 'upscaleValue' ,
778- min : props . scaling_slider_min ,
779- max : props . scaling_slider_max ,
780- step : props . scaling_slider_step ,
781- displayValue : props . upscaleValue . toFixed ( 1 ) + "x" ,
782- scaleFactor : props . upscaleValue ,
783- rescaleMode : 'manual'
764+
765+ // Scale row (manual upscale slider)
766+ this . drawScalingRowBase ( ctx , margin , y , {
767+ buttonControl : 'scaleBtn' , mainControl : 'scaleSlider' , radioControl : 'upscaleRadio' ,
768+ controlType : 'slider' , icon : this . icons . upscale , valueProperty : 'upscaleValue' ,
769+ min : props . scaling_slider_min , max : props . scaling_slider_max , step : props . scaling_slider_step ,
770+ displayValue : props . upscaleValue . toFixed ( 1 ) + "x" , scaleFactor : props . upscaleValue , rescaleMode : 'manual'
784771 } ) ;
785- }
786-
787- drawResolutionRow ( ctx , x , y ) {
788- const props = this . node . properties ;
789- const selectedText = `${ props . targetResolution } p` ;
790- const scaleFactor = this . calculateResolutionScale ( props . targetResolution ) ;
791-
792- this . drawScalingRowBase ( ctx , x , y , {
793- buttonControl : 'resolutionBtn' ,
794- mainControl : 'resolutionDropdown' ,
795- radioControl : 'resolutionRadio' ,
796- controlType : 'dropdown' ,
797- icon : this . icons . resolution ,
798- selectedText : selectedText ,
799- displayValue : `×${ scaleFactor . toFixed ( 2 ) } ` ,
800- scaleFactor : scaleFactor ,
801- rescaleMode : 'resolution'
772+
773+ // Resolution row (target resolution dropdown)
774+ const resScale = this . calculateResolutionScale ( props . targetResolution ) ;
775+ this . drawScalingRowBase ( ctx , margin , y + 35 , {
776+ buttonControl : 'resolutionBtn' , mainControl : 'resolutionDropdown' , radioControl : 'resolutionRadio' ,
777+ controlType : 'dropdown' , icon : this . icons . resolution , selectedText : `${ props . targetResolution } p` ,
778+ displayValue : `×${ resScale . toFixed ( 2 ) } ` , scaleFactor : resScale , rescaleMode : 'resolution'
802779 } ) ;
803- }
804-
805- drawMegapixelsRow ( ctx , x , y ) {
806- const props = this . node . properties ;
807- const scaleFactor = this . calculateMegapixelsScale ( props . targetMegapixels ) ;
808-
809- this . drawScalingRowBase ( ctx , x , y , {
810- buttonControl : 'megapixelsBtn' ,
811- mainControl : 'megapixelsSlider' ,
812- radioControl : 'megapixelsRadio' ,
813- controlType : 'slider' ,
814- icon : this . icons . megapixels ,
815- valueProperty : 'targetMegapixels' ,
816- min : props . megapixels_slider_min ,
817- max : props . megapixels_slider_max ,
818- step : props . megapixels_slider_step ,
819- displayValue : `${ props . targetMegapixels . toFixed ( 1 ) } MP` ,
820- scaleFactor : scaleFactor ,
821- rescaleMode : 'megapixels'
780+
781+ // Megapixels row (target MP slider)
782+ const mpScale = this . calculateMegapixelsScale ( props . targetMegapixels ) ;
783+ this . drawScalingRowBase ( ctx , margin , y + 70 , {
784+ buttonControl : 'megapixelsBtn' , mainControl : 'megapixelsSlider' , radioControl : 'megapixelsRadio' ,
785+ controlType : 'slider' , icon : this . icons . megapixels , valueProperty : 'targetMegapixels' ,
786+ min : props . megapixels_slider_min , max : props . megapixels_slider_max , step : props . megapixels_slider_step ,
787+ displayValue : `${ props . targetMegapixels . toFixed ( 1 ) } MP` , scaleFactor : mpScale , rescaleMode : 'megapixels'
822788 } ) ;
789+
790+ return 105 ;
823791 }
824792
825793 drawAutoDetectSection ( ctx , y ) {
@@ -2040,21 +2008,7 @@ class ResolutionMasterCanvas {
20402008
20412009 // Update backend category widget
20422010 if ( this . categoryWidget ) {
2043- const categoryMapping = {
2044- 'Flux' : 'SD1.5/SDXL' ,
2045- 'Flux.2' : 'Flux.2' ,
2046- 'Standard' : 'SD1.5/SDXL' ,
2047- 'SDXL' : 'SD1.5/SDXL' ,
2048- 'Social Media' : 'SD1.5/SDXL' ,
2049- 'Print' : 'SD1.5/SDXL' ,
2050- 'Cinema' : 'SD1.5/SDXL' ,
2051- 'Display Resolutions' : 'SD1.5/SDXL' ,
2052- 'WAN' : 'SD1.5/SDXL' ,
2053- 'HiDream Dev' : 'SD1.5/SDXL' ,
2054- 'Qwen-Image' : 'SD1.5/SDXL'
2055- } ;
2056-
2057- const backendCategory = categoryMapping [ value ] || 'SD1.5/SDXL' ;
2011+ const backendCategory = ResolutionMasterCanvas . CATEGORY_MAPPING [ value ] || 'SD1.5/SDXL' ;
20582012 this . categoryWidget . value = backendCategory ;
20592013 log . debug ( `Updated backend category widget to: ${ backendCategory } for UI category: ${ value } ` ) ;
20602014 }
@@ -2455,80 +2409,37 @@ class ResolutionMasterCanvas {
24552409 return `(${ Math . round ( pValue ) } p)` ;
24562410 }
24572411
2458- applyFluxCalculation ( width , height ) {
2459- // Najpierw sprawdź czy trzeba skalować ze względu na MP (zachowując proporcje)
2412+ // Unified Flux-like calculation (works for Flux, Flux.2, and future versions)
2413+ applyFluxLikeCalculation ( width , height , maxMP , maxDim , minDim , multiple ) {
24602414 const currentMP = ( width * height ) / 1000000 ;
2461- let scaledWidth = width ;
2462- let scaledHeight = height ;
2415+ let w = width , h = height ;
24632416
2464- if ( currentMP > 4.0 ) {
2465- // Skaluj zachowując dokładnie proporcje
2466- const scale = Math . sqrt ( 4.0 / currentMP ) ;
2467- scaledWidth = width * scale ;
2468- scaledHeight = height * scale ;
2417+ // Scale down if exceeds max megapixels
2418+ if ( currentMP > maxMP ) {
2419+ const scale = Math . sqrt ( maxMP / currentMP ) ;
2420+ w *= scale ; h *= scale ;
24692421 }
24702422
2471- // Ogranicz do zakresu 320-2560px zachowując proporcje
2472- const maxDimension = Math . max ( scaledWidth , scaledHeight ) ;
2473- if ( maxDimension > 2560 ) {
2474- const limitScale = 2560 / maxDimension ;
2475- scaledWidth *= limitScale ;
2476- scaledHeight *= limitScale ;
2477- }
2423+ // Limit to dimension range while preserving aspect ratio
2424+ const maxD = Math . max ( w , h ) ;
2425+ if ( maxD > maxDim ) { const s = maxDim / maxD ; w *= s ; h *= s ; }
24782426
2479- const minDimension = Math . min ( scaledWidth , scaledHeight ) ;
2480- if ( minDimension < 320 ) {
2481- const limitScale = 320 / minDimension ;
2482- scaledWidth *= limitScale ;
2483- scaledHeight *= limitScale ;
2484- }
2485-
2486- // DOPIERO NA KOŃCU zaokrąglij do 32px (to może nieznacznie zmienić proporcje)
2487- const finalWidth = Math . round ( scaledWidth / 32 ) * 32 ;
2488- const finalHeight = Math . round ( scaledHeight / 32 ) * 32 ;
2427+ const minD = Math . min ( w , h ) ;
2428+ if ( minD < minDim ) { const s = minDim / minD ; w *= s ; h *= s ; }
24892429
2430+ // Round to multiple at the end
24902431 return {
2491- width : Math . max ( 320 , Math . min ( 2560 , finalWidth ) ) ,
2492- height : Math . max ( 320 , Math . min ( 2560 , finalHeight ) )
2432+ width : Math . max ( minDim , Math . min ( maxDim , Math . round ( w / multiple ) * multiple ) ) ,
2433+ height : Math . max ( minDim , Math . min ( maxDim , Math . round ( h / multiple ) * multiple ) )
24932434 } ;
24942435 }
24952436
2437+ applyFluxCalculation ( width , height ) {
2438+ return this . applyFluxLikeCalculation ( width , height , 4.0 , 2560 , 320 , 32 ) ;
2439+ }
2440+
24962441 applyFlux2Calculation ( width , height ) {
2497- // Najpierw sprawdź czy trzeba skalować ze względu na MP (zachowując proporcje)
2498- const currentMP = ( width * height ) / 1000000 ;
2499- let scaledWidth = width ;
2500- let scaledHeight = height ;
2501-
2502- if ( currentMP > 6.0 ) {
2503- // Skaluj zachowując dokładnie proporcje
2504- const scale = Math . sqrt ( 6.0 / currentMP ) ;
2505- scaledWidth = width * scale ;
2506- scaledHeight = height * scale ;
2507- }
2508-
2509- // Ogranicz do zakresu 320-2560px zachowując proporcje
2510- const maxDimension = Math . max ( scaledWidth , scaledHeight ) ;
2511- if ( maxDimension > 3840 ) {
2512- const limitScale = 3840 / maxDimension ;
2513- scaledWidth *= limitScale ;
2514- scaledHeight *= limitScale ;
2515- }
2516-
2517- const minDimension = Math . min ( scaledWidth , scaledHeight ) ;
2518- if ( minDimension < 320 ) {
2519- const limitScale = 320 / minDimension ;
2520- scaledWidth *= limitScale ;
2521- scaledHeight *= limitScale ;
2522- }
2523-
2524- // DOPIERO NA KOŃCU zaokrąglij do 32px (to może nieznacznie zmienić proporcje)
2525- const finalWidth = Math . round ( scaledWidth / 16 ) * 16 ;
2526- const finalHeight = Math . round ( scaledHeight / 16 ) * 16 ;
2527-
2528- return {
2529- width : Math . max ( 320 , Math . min ( 3840 , finalWidth ) ) ,
2530- height : Math . max ( 320 , Math . min ( 3840 , finalHeight ) )
2531- } ;
2442+ return this . applyFluxLikeCalculation ( width , height , 6.0 , 3840 , 320 , 16 ) ;
25322443 }
25332444
25342445 applyWANCalculation ( width , height ) {
0 commit comments