@@ -137,7 +137,7 @@ export class BookScene {
137137 this . pages . push ( page ) ;
138138 }
139139
140- this . _createMediaIcons ( textureLoader ) ;
140+ this . _initIcons ( textureLoader ) ;
141141 this . update ( 0 ) ;
142142 }
143143
@@ -228,8 +228,9 @@ export class BookScene {
228228
229229 this . updateIcons ( ) ;
230230
231-
232231 }
232+
233+
233234 private updateBgColor ( progress : number ) {
234235 const now = performance . now ( ) ;
235236 if ( now - this . lastBgUpdate < 16 ) return ;
@@ -278,6 +279,7 @@ export class BookScene {
278279 this . camera . position . y = height < width ? 0 : - 0.25 * ( visibleHeight - config . pageHeight ) ;
279280
280281 this . camera . updateProjectionMatrix ( ) ;
282+ this . _updateIconGroupPosition ( ) ;
281283 }
282284
283285 public dispose ( ) {
@@ -438,9 +440,16 @@ export class BookScene {
438440 return geometry ;
439441 }
440442
441- private _createMediaIcons ( textureLoader : THREE . TextureLoader ) {
443+ private iconGroup : THREE . Group | null = null ;
444+ private iconLayoutVertical : boolean = false
445+
446+ private _initIcons ( textureLoader : THREE . TextureLoader ) {
442447 const iconSize = 0.3 ;
443448 const iconGeometry = new THREE . PlaneGeometry ( iconSize , iconSize ) ;
449+ this . iconLayoutVertical = ! ( this . container . clientWidth > this . container . clientHeight * 1.2 ) ;
450+
451+ this . iconGroup = new THREE . Group ( ) ;
452+ this . scene . add ( this . iconGroup ) ;
444453
445454 const videoTexture = textureLoader . load ( assets . icons . video ) ;
446455 videoTexture . colorSpace = THREE . SRGBColorSpace ;
@@ -449,10 +458,9 @@ export class BookScene {
449458 transparent : true ,
450459 opacity : 0 ,
451460 } ) ;
452-
453461 this . videoIcon = new THREE . Mesh ( iconGeometry , videoMaterial ) ;
454- this . videoIcon . position . set ( - config . pageWidth - 0.3 , 0.7 , 0 ) ;
455- this . scene . add ( this . videoIcon ) ;
462+ this . videoIcon . position . set ( 0 , 0.4 , 0 ) ;
463+ this . iconGroup . add ( this . videoIcon ) ;
456464
457465 const audioTexture = textureLoader . load ( assets . icons . audio ) ;
458466 audioTexture . colorSpace = THREE . SRGBColorSpace ;
@@ -463,10 +471,46 @@ export class BookScene {
463471 } ) ;
464472
465473 this . audioIcon = new THREE . Mesh ( iconGeometry . clone ( ) , audioMaterial ) ;
466- this . audioIcon . position . set ( - config . pageWidth - 0.3 , 0.3 , 0 ) ;
467- this . scene . add ( this . audioIcon ) ;
474+ this . audioIcon . position . set ( 0 , 0 , 0 ) ;
475+
476+ this . iconGroup . add ( this . audioIcon ) ;
477+
478+ this . _updateIconGroupPosition ( ) ;
479+ }
480+
481+ private _updateIconGroupPosition ( ) {
482+ const margin = 0.25 ;
483+
484+ if ( ! this . iconGroup ) return ;
485+ const isPortrait = this . container . clientWidth > this . container . clientHeight * 1.2 ;
486+
487+ if ( isPortrait && ! this . iconLayoutVertical ) {
488+ this . iconLayoutVertical = true ;
489+ this . iconGroup . position . set ( - config . pageWidth - margin , 0.35 , 0 ) ;
490+
491+ if ( this . videoIcon && this . audioIcon ) {
492+ this . videoIcon . position . set ( 0 , 0.4 , 0 ) ;
493+ this . audioIcon . position . set ( 0 , 0 , 0 ) ;
494+ }
495+ }
496+ else if ( ! isPortrait && this . iconLayoutVertical ) {
497+ this . iconLayoutVertical = false ;
498+
499+ const yOffset = - config . pageHeight / 2 - margin ;
500+ this . iconGroup . position . set ( 0 , yOffset , 0 ) ;
501+ if ( this . isMobile ) {
502+ this . iconGroup . scale . set ( 1.2 , 1.2 , 1.2 ) ;
503+ }
504+ if ( this . videoIcon && this . audioIcon ) {
505+ this . videoIcon . position . set ( - 0.2 , 0 , 0 ) ;
506+ this . audioIcon . position . set ( 0.2 , 0 , 0 ) ;
507+ }
508+ }
468509 }
469510
511+
512+
513+
470514 private updateIcons ( ) {
471515 if ( ! this . videoIcon || ! this . audioIcon ) return ;
472516
@@ -500,11 +544,11 @@ export class BookScene {
500544
501545 if ( intersects . length > 0 ) {
502546 const clickedObject = intersects [ 0 ] . object ;
503-
547+
504548 if ( clickedObject === this . videoIcon ) {
505549 this . videoOverlayManager . show ( assets . videos [ this . currentPage . toString ( ) ] || '' ) ;
506550 } else if ( clickedObject === this . audioIcon ) {
507- playAudio ( assets . audios [ this . currentPage . toString ( ) ] || '' , ) ;
551+ playAudio ( assets . audios [ this . currentPage . toString ( ) ] || '' ) ;
508552 }
509553 }
510554 }
0 commit comments