@@ -131,6 +131,57 @@ describe(testName, () => {
131131 }
132132 } ) ;
133133
134+ it ( 'keeps fixed-size scene transforms independent of the assigned canvas size' , ( ) => {
135+ const scene = osn . SceneFactory . create ( 'relative-coordinate-fixed-size-scene' ) ;
136+ const source = osn . InputFactory . create ( EOBSInputTypes . ImageSource , 'relative-coordinate-fixed-size-source' ) ;
137+ const secondCanvas = osn . VideoFactory . create ( ) ;
138+ const originalVideoInfo : osn . IVideoInfo = {
139+ ...obs . defaultVideoContext . video ,
140+ baseWidth : 1920 ,
141+ baseHeight : 1080 ,
142+ outputWidth : 1920 ,
143+ outputHeight : 1080 ,
144+ } ;
145+ const resizedVideoInfo : osn . IVideoInfo = {
146+ ...originalVideoInfo ,
147+ baseWidth : 1280 ,
148+ baseHeight : 720 ,
149+ outputWidth : 1280 ,
150+ outputHeight : 720 ,
151+ } ;
152+ const authoredPosition = { x : 320 , y : 180 } ;
153+ const authoredScale = { x : 1.25 , y : 0.75 } ;
154+ let item : osn . ISceneItem ;
155+
156+ try {
157+ scene . update ( { custom_size : true , cx : 640 , cy : 360 } ) ;
158+ scene . load ( ) ;
159+ expect ( scene . source . width ) . to . equal ( 640 ) ;
160+ expect ( scene . source . height ) . to . equal ( 360 ) ;
161+
162+ secondCanvas . video = originalVideoInfo ;
163+ item = scene . add ( source ) ;
164+ item . video = secondCanvas ;
165+ item . position = authoredPosition ;
166+ item . scale = authoredScale ;
167+
168+ secondCanvas . video = resizedVideoInfo ;
169+ osn . SceneFactory . invalidateItemTransformCache ( ) ;
170+
171+ expect ( scene . source . width ) . to . equal ( 640 ) ;
172+ expect ( scene . source . height ) . to . equal ( 360 ) ;
173+ expect ( item . position . x ) . to . be . closeTo ( authoredPosition . x , 0.01 ) ;
174+ expect ( item . position . y ) . to . be . closeTo ( authoredPosition . y , 0.01 ) ;
175+ expect ( item . scale . x ) . to . be . closeTo ( authoredScale . x , 0.01 ) ;
176+ expect ( item . scale . y ) . to . be . closeTo ( authoredScale . y , 0.01 ) ;
177+ } finally {
178+ if ( item ) item . remove ( ) ;
179+ source . release ( ) ;
180+ scene . release ( ) ;
181+ secondCanvas . destroy ( ) ;
182+ }
183+ } ) ;
184+
134185 it ( 'refreshes cached absolute transforms after a relative canvas reset' , ( ) => {
135186 const originalVideoInfo = obs . defaultVideoContext . video ;
136187 const resizedBaseWidth = Math . round ( originalVideoInfo . baseWidth * 1.5 ) ;
@@ -345,10 +396,11 @@ describe(testName, () => {
345396 blendingMode : osn . EBlendingMode . Normal ,
346397 blendingMethod : osn . EBlendingMethod . Default ,
347398 } ;
399+ let item : osn . ISceneItem ;
348400
349401 try {
350402 verticalCanvas . video = verticalVideoInfo ;
351- const item = outerScene . add ( nestedSource , transform , verticalCanvas ) ;
403+ item = outerScene . add ( nestedSource , transform , verticalCanvas ) ;
352404
353405 expect ( item . video . video . baseWidth ) . to . equal ( verticalVideoInfo . baseWidth ) ;
354406 expect ( item . video . video . baseHeight ) . to . equal ( verticalVideoInfo . baseHeight ) ;
@@ -368,6 +420,10 @@ describe(testName, () => {
368420 expect ( reloadedItem . crop_ref_width ) . to . equal ( verticalVideoInfo . baseWidth ) ;
369421 expect ( reloadedItem . crop_ref_height ) . to . equal ( verticalVideoInfo . baseHeight ) ;
370422 } finally {
423+ if ( item ) {
424+ item . video = obs . defaultVideoContext ;
425+ item . remove ( ) ;
426+ }
371427 nestedSource . release ( ) ;
372428 outerScene . release ( ) ;
373429 nestedScene . release ( ) ;
0 commit comments