Procházet zdrojové kódy

Viewport: introduce a sub-container so that the viewport style is respected when going fullscreen

customisations
alemart před 1 rokem
rodič
revize
4bfa538f2e
2 změnil soubory, kde provedl 82 přidání a 17 odebrání
  1. 7
    5
      src/core/hud.ts
  2. 75
    12
      src/core/viewport.ts

+ 7
- 5
src/core/hud.ts Zobrazit soubor

@@ -45,14 +45,16 @@ export class HUD
45 45
      * @param parent parent of the hud container
46 46
      * @param hudContainer an existing hud container (optional)
47 47
      */
48
-    constructor(parent: ViewportContainer, hudContainer: Nullable<HUDContainer>)
48
+    constructor(parent: HTMLElement, hudContainer: Nullable<HUDContainer>)
49 49
     {
50 50
         this._container = hudContainer || this._createContainer(parent);
51 51
         this._ownContainer = (hudContainer == null);
52 52
 
53
-        // validate
54
-        if(this._container.parentElement !== parent)
55
-            throw new IllegalArgumentError('The container of the HUD must be a direct child of the container of the viewport');
53
+        // move the HUD container to the parent node
54
+        if(this._container.parentElement !== parent) {
55
+            this._container.remove();
56
+            parent.insertAdjacentElement('afterbegin', this._container);
57
+        }
56 58
 
57 59
         // the HUD should be hidden initially
58 60
         if(!this._container.hidden)
@@ -122,7 +124,7 @@ export class HUD
122 124
         const node = document.createElement('div') as HTMLDivElement;
123 125
 
124 126
         node.hidden = true;
125
-        parent.appendChild(node);
127
+        parent.insertAdjacentElement('afterbegin', node);
126 128
 
127 129
         return node;
128 130
     }

+ 75
- 12
src/core/viewport.ts Zobrazit soubor

@@ -93,6 +93,9 @@ export interface Viewport extends ViewportEventTarget
93 93
     /** Size of the drawing buffer of the background canvas @internal */
94 94
     readonly _realSize: SpeedySize;
95 95
 
96
+    /** Sub-container of the viewport container @internal */
97
+    readonly _subContainer: HTMLDivElement;
98
+
96 99
     /** Initialize the viewport @internal */
97 100
     _init(): void;
98 101
 
@@ -108,7 +111,7 @@ export interface ViewportSettings
108 111
     /** Viewport container */
109 112
     container: Nullable<ViewportContainer>;
110 113
 
111
-    /** HUD container (must be a direct child of container) */
114
+    /** HUD container */
112 115
     hudContainer?: Nullable<HUDContainer>;
113 116
 
114 117
     /** Resolution of the canvas on which the virtual scene will be drawn */
@@ -130,7 +133,7 @@ const DEFAULT_VIEWPORT_SETTINGS: Readonly<Required<ViewportSettings>> = {
130 133
     canvas: null,
131 134
 };
132 135
 
133
-/** Z-index of the viewport container */
136
+/** Z-index of the viewport container in immersive mode */
134 137
 const CONTAINER_ZINDEX = 1000000000;
135 138
 
136 139
 /** Base z-index of the children of the viewport container */
@@ -170,6 +173,9 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
170 173
     /** Viewport style */
171 174
     protected _style: ViewportStyle;
172 175
 
176
+    /** A container inside the viewport container */
177
+    private readonly __subContainer: HTMLDivElement;
178
+
173 179
     /** Internal canvas used to render the physical scene */
174 180
     private readonly __backgroundCanvas: HTMLCanvasElement;
175 181
 
@@ -201,7 +207,8 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
201 207
         // initialize attributes
202 208
         this._resolution = settings.resolution;
203 209
         this._container = settings.container;
204
-        this._hud = new HUD(settings.container, settings.hudContainer);
210
+        this.__subContainer = this._createSubContainer(this._container);
211
+        this._hud = new HUD(this.__subContainer, settings.hudContainer);
205 212
 
206 213
         // make this more elegant?
207 214
         // need to initialize this._style and validate settings.style
@@ -209,11 +216,11 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
209 216
         this.style = settings.style;
210 217
 
211 218
         // create the background canvas
212
-        this.__backgroundCanvas = this._createBackgroundCanvas(this._container, size);
219
+        this.__backgroundCanvas = this._createBackgroundCanvas(this.__subContainer, size);
213 220
 
214 221
         // create the foreground canvas
215 222
         if(settings.canvas == null) {
216
-            this._foregroundCanvas = this._createForegroundCanvas(this._container, size);
223
+            this._foregroundCanvas = this._createForegroundCanvas(this.__subContainer, size);
217 224
             this._parentOfImportedForegroundCanvas = null;
218 225
         }
219 226
         else {
@@ -419,6 +426,15 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
419 426
     }
420 427
 
421 428
     /**
429
+     * Sub-container of the viewport container
430
+     * @internal
431
+     */
432
+    get _subContainer(): HTMLDivElement
433
+    {
434
+        return this.__subContainer;
435
+    }
436
+
437
+    /**
422 438
      * Initialize the viewport (when the session starts)
423 439
      * @internal
424 440
      */
@@ -427,13 +443,12 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
427 443
         // import foreground canvas
428 444
         if(this._parentOfImportedForegroundCanvas != null) {
429 445
             const size = Speedy.Size(DEFAULT_VIEWPORT_WIDTH, DEFAULT_VIEWPORT_HEIGHT);
430
-            this._importForegroundCanvas(this._foregroundCanvas, this._container, size);
446
+            this._importForegroundCanvas(this._foregroundCanvas, this._subContainer, size);
431 447
         }
432 448
 
433 449
         // setup CSS
434 450
         this._container.style.touchAction = 'none';
435 451
         this._container.style.backgroundColor = 'black';
436
-        this._container.style.zIndex = String(CONTAINER_ZINDEX);
437 452
 
438 453
         // initialize the HUD
439 454
         this._hud._init(HUD_ZINDEX);
@@ -458,6 +473,26 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
458 473
     }
459 474
 
460 475
     /**
476
+     * Create a sub-container
477
+     * @param parent parent node
478
+     * @returns the canvas container
479
+     */
480
+    private _createSubContainer(parent: ViewportContainer): HTMLDivElement
481
+    {
482
+        const container = document.createElement('div') as HTMLDivElement;
483
+
484
+        container.style.position = 'absolute';
485
+        container.style.left = '0px';
486
+        container.style.top = '0px';
487
+        container.style.width = '100%';
488
+        container.style.height = '100%';
489
+
490
+        parent.appendChild(container);
491
+
492
+        return container;
493
+    }
494
+
495
+    /**
461 496
      * Create a canvas and attach it to another HTML element
462 497
      * @param parent parent container
463 498
      * @param size size of the drawing buffer
@@ -480,7 +515,7 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
480 515
      * @param size size of the drawing buffer
481 516
      * @returns a new canvas as a child of parent
482 517
      */
483
-    private _createBackgroundCanvas(parent: ViewportContainer, size: SpeedySize): HTMLCanvasElement
518
+    private _createBackgroundCanvas(parent: HTMLElement, size: SpeedySize): HTMLCanvasElement
484 519
     {
485 520
         const canvas = this._createCanvas(parent, size);
486 521
         return this._styleCanvas(canvas, BACKGROUND_ZINDEX);
@@ -492,7 +527,7 @@ export class BaseViewport extends ViewportEventTarget implements Viewport
492 527
      * @param size size of the drawing buffer
493 528
      * @returns a new canvas as a child of parent
494 529
      */
495
-    private _createForegroundCanvas(parent: ViewportContainer, size: SpeedySize): HTMLCanvasElement
530
+    private _createForegroundCanvas(parent: HTMLElement, size: SpeedySize): HTMLCanvasElement
496 531
     {
497 532
         const canvas = this._createCanvas(parent, size);
498 533
         return this._styleCanvas(canvas, FOREGROUND_ZINDEX);
@@ -692,6 +727,15 @@ abstract class ViewportDecorator extends ViewportEventTarget implements Viewport
692 727
     }
693 728
 
694 729
     /**
730
+     * Sub-container of the viewport container
731
+     * @internal
732
+     */
733
+    get _subContainer(): HTMLDivElement
734
+    {
735
+        return this._base._subContainer;
736
+    }
737
+
738
+    /**
695 739
      * Initialize the viewport
696 740
      * @internal
697 741
      */
@@ -800,7 +844,8 @@ abstract class ResizableViewport extends ViewportDecorator
800 844
             window.addEventListener('orientationchange', this._resize.bind(this)); // deprecated
801 845
 
802 846
         // trigger a resize to setup the sizes / the CSS
803
-        this._resize();
847
+        // note: we may adjust this.style after this._init(); see the inline viewport
848
+        setTimeout(() => this._resize(), 0);
804 849
     }
805 850
 
806 851
     /**
@@ -854,6 +899,24 @@ abstract class ResizableViewport extends ViewportDecorator
854 899
 export class ImmersiveViewport extends ResizableViewport
855 900
 {
856 901
     /**
902
+     * Initialize the viewport
903
+     * @internal
904
+     */
905
+    _init(): void
906
+    {
907
+        const container = this.container;
908
+
909
+        container.style.position = 'fixed';
910
+        container.style.left = '0px';
911
+        container.style.top = '0px';
912
+        container.style.width = '100vw';
913
+        container.style.height = '100vh';
914
+        container.style.zIndex = String(CONTAINER_ZINDEX);
915
+
916
+        super._init();
917
+    }
918
+
919
+    /**
857 920
      * Release the viewport
858 921
      * @internal
859 922
      */
@@ -875,8 +938,8 @@ export class ImmersiveViewport extends ResizableViewport
875 938
     {
876 939
         super._onResize();
877 940
 
878
-        const container = this.container;
879
-        container.style.position = 'fixed';
941
+        const container = this._subContainer;
942
+        container.style.position = 'absolute';
880 943
 
881 944
         if(this.style == 'best-fit') {
882 945
             // cover the page while maintaining the aspect ratio

Načítá se…
Zrušit
Uložit