@@ -117,6 +117,8 @@ export class Visualizer extends Events<VisualizerEvents> {
117117 private renderers : Renderer [ ] = [ ] ;
118118 private rateLimitedTransfer : RateLimitedRenderer ;
119119 private interactionManager ! : InteractionManager ;
120+ private initialSpectrogramHeight : number ;
121+ private initialWaveformHeight : number ;
120122
121123 constructor ( options : VisualizerOptions , waveform : Waveform ) {
122124 super ( ) ;
@@ -131,7 +133,10 @@ export class Visualizer extends Events<VisualizerEvents> {
131133 this . autoCenter = options . autoCenter ?? this . autoCenter ;
132134 this . splitChannels = options . splitChannels ?? this . splitChannels ;
133135 this . waveformHeight = options . waveformHeight ?? options . height ?? options . waveHeight ?? 32 ;
134- this . spectrogramHeight = options . spectrogramHeight ?? options . height ?? 32 ;
136+ this . spectrogramHeight = options . spectrogramHeight ?? options . height ?? options . waveHeight ?? 32 ;
137+ // Save initial height for computing adaptive max height during resize
138+ this . initialWaveformHeight = this . waveformHeight ;
139+ this . initialSpectrogramHeight = this . spectrogramHeight ;
135140 this . timelineHeight = options . timelineHeight ?? options . timeline ?. height ?? 20 ;
136141 this . timelinePlacement = options ?. timeline ?. placement ?? this . timelinePlacement ;
137142 this . gridColor = options . gridColor ? rgba ( options . gridColor ) : this . gridColor ;
@@ -465,14 +470,14 @@ export class Visualizer extends Events<VisualizerEvents> {
465470 }
466471
467472 drawRequestId : number | null = null ;
468- drawRequestDry = false ;
473+ drawRequestDry = true ;
469474 draw ( dry = false ) {
470475 if ( ! isSyncedBuffering ) {
471476 this . _draw ( dry ) ;
472477 return ;
473478 }
474479 if ( this . drawRequestId ) {
475- this . drawRequestDry = this . drawRequestDry || dry ;
480+ this . drawRequestDry = this . drawRequestDry && dry ;
476481 } else {
477482 this . drawRequestDry = dry ;
478483 this . drawRequestId = requestAnimationFrame ( ( ) => {
@@ -580,14 +585,14 @@ export class Visualizer extends Events<VisualizerEvents> {
580585 return this . container . clientWidth ;
581586 }
582587
583- get computedWaveformHeight ( ) {
588+ get waveformLayerHeight ( ) {
584589 if ( this . splitChannels && this . audio ?. channelCount ) {
585590 return this . waveformHeight * this . audio . channelCount ;
586591 }
587592 return this . waveformHeight ;
588593 }
589594
590- get computedSpectrogramHeight ( ) {
595+ get spectrogramLayerHeight ( ) {
591596 if ( this . splitChannels && this . audio ?. channelCount ) {
592597 return this . spectrogramHeight * this . audio . channelCount ;
593598 }
@@ -606,8 +611,8 @@ export class Visualizer extends Events<VisualizerEvents> {
606611
607612 // If the timeline layer doesn't exist yet, assume it's visible and use timelineHeight
608613 height += timelineLayer === undefined ? this . timelineHeight : timelineLayer . isVisible ? this . timelineHeight : 0 ;
609- height += waveformLayer ?. isVisible ? this . computedWaveformHeight : 0 ;
610- height += spectrogramLayer ?. isVisible ? this . computedSpectrogramHeight : 0 ; // Use computedSpectrogramHeight!
614+ height += waveformLayer ?. isVisible ? this . waveformLayerHeight : 0 ;
615+ height += spectrogramLayer ?. isVisible ? this . spectrogramLayerHeight : 0 ;
611616
612617 return height ;
613618 }
@@ -651,13 +656,19 @@ export class Visualizer extends Events<VisualizerEvents> {
651656 this . wrapper . style . height = "100%" ;
652657
653658 const mainLayer = this . createLayer ( { name : "main" } ) ;
654- this . createLayer ( { name : "background" , offscreen : true , zIndex : 0 , isVisible : false , height : this . waveformHeight } ) ;
655- this . createLayer ( { name : "waveform" , offscreen : true , zIndex : 100 , height : this . waveformHeight } ) ;
659+ this . createLayer ( {
660+ name : "background" ,
661+ offscreen : true ,
662+ zIndex : 0 ,
663+ isVisible : false ,
664+ height : this . waveformLayerHeight ,
665+ } ) ;
666+ this . createLayer ( { name : "waveform" , offscreen : true , zIndex : 100 , height : this . waveformLayerHeight } ) ;
656667 this . createLayer ( {
657668 name : "waveform-resize" ,
658669 offscreen : true ,
659670 zIndex : 200 ,
660- height : this . waveformHeight ,
671+ height : this . waveformLayerHeight ,
661672 compositeOperation : "difference" , // Use blend mode for better visibility
662673 } ) ;
663674
@@ -668,14 +679,14 @@ export class Visualizer extends Events<VisualizerEvents> {
668679 offscreen : true ,
669680 zIndex : 100 ,
670681 isVisible : true ,
671- height : this . spectrogramHeight ,
682+ height : this . spectrogramLayerHeight ,
672683 } ) ;
673684 this . createLayer ( {
674685 name : "spectrogram-resize" ,
675686 offscreen : true ,
676687 zIndex : 200 ,
677688 isVisible : true ,
678- height : this . spectrogramHeight ,
689+ height : this . spectrogramLayerHeight ,
679690 compositeOperation : "difference" , // Use blend mode for better visibility
680691 } ) ;
681692 this . createLayer ( { name : "progress" , offscreen : true , zIndex : 1020 , isVisible : true , height : 0 } ) ;
@@ -684,7 +695,7 @@ export class Visualizer extends Events<VisualizerEvents> {
684695 offscreen : true ,
685696 zIndex : 1100 ,
686697 isVisible : true ,
687- height : this . spectrogramHeight ,
698+ height : this . spectrogramLayerHeight ,
688699 } ) ;
689700 }
690701
@@ -1100,15 +1111,15 @@ export class Visualizer extends Events<VisualizerEvents> {
11001111 if ( layer . name !== "main" ) {
11011112 layer . pixelRatio = this . pixelRatio ;
11021113 layer . width = this . width ;
1103- // Update height for layers that should match the waveform height
1114+ // Update height for layers according to their type
11041115 if ( layer . name === "waveform" ) {
1105- layer . height = this . waveformHeight ;
1116+ layer . height = this . waveformLayerHeight ;
11061117 } else if ( layer . name === "waveform-resize" ) {
1107- layer . height = this . waveformHeight ;
1118+ layer . height = this . waveformLayerHeight ;
11081119 } else if ( layer . name === "spectrogram" || layer . name === "spectrogram-grid" ) {
1109- layer . height = this . spectrogramHeight ;
1120+ layer . height = this . spectrogramLayerHeight ;
11101121 } else if ( layer . name === "spectrogram-resize" ) {
1111- layer . height = this . spectrogramHeight ;
1122+ layer . height = this . spectrogramLayerHeight ;
11121123 }
11131124 // Update regions layer height to match the full visualizer height
11141125 if ( layer . name === "regions" ) {
@@ -1243,13 +1254,6 @@ export class Visualizer extends Events<VisualizerEvents> {
12431254 const spectrogramLayer = this . getLayer ( "spectrogram" ) ;
12441255 if ( ! spectrogramLayer ?. isVisible ) return 0 ;
12451256
1246- const channelCount = this . audio ?. channelCount ?? 1 ;
1247-
1248- if ( this . splitChannels ) {
1249- // Each channel gets an equal split of the spectrogram area
1250- return this . spectrogramHeight / channelCount ;
1251- }
1252- // Spectrogram uses the full height when not split
12531257 return this . spectrogramHeight ;
12541258 }
12551259
@@ -1291,7 +1295,7 @@ export class Visualizer extends Events<VisualizerEvents> {
12911295 if ( componentName === "spectrogram" ) {
12921296 // Spectrogram comes after waveform in the vertical stack
12931297 if ( waveformLayer ?. isVisible ) {
1294- offsetY += this . computedWaveformHeight ;
1298+ offsetY += this . waveformLayerHeight ;
12951299 }
12961300 }
12971301
@@ -1300,9 +1304,9 @@ export class Visualizer extends Events<VisualizerEvents> {
13001304 let height = 0 ;
13011305
13021306 if ( componentName === "waveform" ) {
1303- height = this . computedWaveformHeight ;
1307+ height = this . waveformLayerHeight ;
13041308 } else if ( componentName === "spectrogram" ) {
1305- height = this . computedSpectrogramHeight ;
1309+ height = this . spectrogramLayerHeight ;
13061310 }
13071311
13081312 return {
@@ -1317,40 +1321,54 @@ export class Visualizer extends Events<VisualizerEvents> {
13171321 * Handle height changes from ResizeRenderer
13181322 */
13191323 private handleHeightChange = ( componentName : string , newHeight : number ) : void => {
1324+ let initialHeight = 0 ;
1325+ if ( componentName === "waveform" ) {
1326+ initialHeight = this . initialWaveformHeight * ( ( this . splitChannels && this . audio ?. channelCount ) || 1 ) ;
1327+ } else if ( componentName === "spectrogram" ) {
1328+ initialHeight = this . initialSpectrogramHeight * ( ( this . splitChannels && this . audio ?. channelCount ) || 1 ) ;
1329+ }
13201330 const minHeight = 50 ;
1321- const maxHeight = 500 ;
1331+ const maxHeight = Math . max ( 500 , initialHeight ) ;
13221332 const clampedHeight = Math . max ( minHeight , Math . min ( maxHeight , newHeight ) ) ;
13231333
13241334 if ( componentName === "waveform" ) {
1325- this . waveformHeight = clampedHeight ;
1335+ if ( this . splitChannels && this . audio ?. channelCount ) {
1336+ this . waveformHeight = clampedHeight / this . audio . channelCount ;
1337+ } else {
1338+ this . waveformHeight = clampedHeight ;
1339+ }
13261340 // Update the waveform-related layers
13271341 const waveformLayer = this . getLayer ( "waveform" ) ;
13281342 const waveformResizeLayer = this . getLayer ( "waveform-resize" ) ;
13291343 const backgroundLayer = this . getLayer ( "background" ) ;
13301344
1331- if ( waveformLayer ) waveformLayer . height = clampedHeight ;
1332- if ( waveformResizeLayer ) waveformResizeLayer . height = clampedHeight ;
1333- if ( backgroundLayer ) backgroundLayer . height = clampedHeight ;
1345+ if ( waveformLayer ) waveformLayer . height = this . waveformLayerHeight ;
1346+ if ( waveformResizeLayer ) waveformResizeLayer . height = this . waveformLayerHeight ;
1347+ if ( backgroundLayer ) backgroundLayer . height = this . waveformLayerHeight ;
13341348
13351349 // Update WaveformRenderer configuration
13361350 if ( this . waveformRenderer ) {
13371351 // For height changes, we only need to update the waveHeight config
13381352 // without triggering expensive redraws
1339- this . waveformRenderer . config . waveHeight = clampedHeight ;
1353+ this . waveformRenderer . config . waveHeight = this . waveformHeight ;
13401354
13411355 // Don't call resetRenderState - it forces expensive redraw
13421356 // The waveform data doesn't change, just the rendering height
13431357 }
13441358 } else if ( componentName === "spectrogram" ) {
1345- this . spectrogramHeight = clampedHeight ;
1359+ if ( this . splitChannels && this . audio ?. channelCount ) {
1360+ this . spectrogramHeight = clampedHeight / this . audio . channelCount ;
1361+ } else {
1362+ this . spectrogramHeight = clampedHeight ;
1363+ }
13461364 // Update the spectrogram-related layers
13471365 const spectrogramLayer = this . getLayer ( "spectrogram" ) ;
13481366 const spectrogramResizeLayer = this . getLayer ( "spectrogram-resize" ) ;
13491367 const spectrogramGridLayer = this . getLayer ( "spectrogram-grid" ) ;
13501368
1351- if ( spectrogramLayer ) spectrogramLayer . height = clampedHeight ;
1352- if ( spectrogramResizeLayer ) spectrogramResizeLayer . height = clampedHeight ;
1353- if ( spectrogramGridLayer ) spectrogramGridLayer . height = clampedHeight ;
1369+ if ( spectrogramLayer ) spectrogramLayer . height = this . spectrogramLayerHeight ;
1370+ if ( spectrogramResizeLayer ) spectrogramResizeLayer . height = this . spectrogramLayerHeight ;
1371+ if ( spectrogramGridLayer ) spectrogramGridLayer . height = this . spectrogramLayerHeight ;
13541372
13551373 // Update SpectrogramRenderer configuration
13561374 if ( this . spectrogramRenderer ) {
0 commit comments