浏览代码

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

customisations
alemart 1年前
父节点
当前提交
4bfa538f2e
共有 2 个文件被更改,包括 82 次插入17 次删除
  1. 7
    5
      src/core/hud.ts
  2. 75
    12
      src/core/viewport.ts

+ 7
- 5
src/core/hud.ts 查看文件

45
      * @param parent parent of the hud container
45
      * @param parent parent of the hud container
46
      * @param hudContainer an existing hud container (optional)
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
         this._container = hudContainer || this._createContainer(parent);
50
         this._container = hudContainer || this._createContainer(parent);
51
         this._ownContainer = (hudContainer == null);
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
         // the HUD should be hidden initially
59
         // the HUD should be hidden initially
58
         if(!this._container.hidden)
60
         if(!this._container.hidden)
122
         const node = document.createElement('div') as HTMLDivElement;
124
         const node = document.createElement('div') as HTMLDivElement;
123
 
125
 
124
         node.hidden = true;
126
         node.hidden = true;
125
-        parent.appendChild(node);
127
+        parent.insertAdjacentElement('afterbegin', node);
126
 
128
 
127
         return node;
129
         return node;
128
     }
130
     }

+ 75
- 12
src/core/viewport.ts 查看文件

93
     /** Size of the drawing buffer of the background canvas @internal */
93
     /** Size of the drawing buffer of the background canvas @internal */
94
     readonly _realSize: SpeedySize;
94
     readonly _realSize: SpeedySize;
95
 
95
 
96
+    /** Sub-container of the viewport container @internal */
97
+    readonly _subContainer: HTMLDivElement;
98
+
96
     /** Initialize the viewport @internal */
99
     /** Initialize the viewport @internal */
97
     _init(): void;
100
     _init(): void;
98
 
101
 
108
     /** Viewport container */
111
     /** Viewport container */
109
     container: Nullable<ViewportContainer>;
112
     container: Nullable<ViewportContainer>;
110
 
113
 
111
-    /** HUD container (must be a direct child of container) */
114
+    /** HUD container */
112
     hudContainer?: Nullable<HUDContainer>;
115
     hudContainer?: Nullable<HUDContainer>;
113
 
116
 
114
     /** Resolution of the canvas on which the virtual scene will be drawn */
117
     /** Resolution of the canvas on which the virtual scene will be drawn */
130
     canvas: null,
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
 const CONTAINER_ZINDEX = 1000000000;
137
 const CONTAINER_ZINDEX = 1000000000;
135
 
138
 
136
 /** Base z-index of the children of the viewport container */
139
 /** Base z-index of the children of the viewport container */
170
     /** Viewport style */
173
     /** Viewport style */
171
     protected _style: ViewportStyle;
174
     protected _style: ViewportStyle;
172
 
175
 
176
+    /** A container inside the viewport container */
177
+    private readonly __subContainer: HTMLDivElement;
178
+
173
     /** Internal canvas used to render the physical scene */
179
     /** Internal canvas used to render the physical scene */
174
     private readonly __backgroundCanvas: HTMLCanvasElement;
180
     private readonly __backgroundCanvas: HTMLCanvasElement;
175
 
181
 
201
         // initialize attributes
207
         // initialize attributes
202
         this._resolution = settings.resolution;
208
         this._resolution = settings.resolution;
203
         this._container = settings.container;
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
         // make this more elegant?
213
         // make this more elegant?
207
         // need to initialize this._style and validate settings.style
214
         // need to initialize this._style and validate settings.style
209
         this.style = settings.style;
216
         this.style = settings.style;
210
 
217
 
211
         // create the background canvas
218
         // create the background canvas
212
-        this.__backgroundCanvas = this._createBackgroundCanvas(this._container, size);
219
+        this.__backgroundCanvas = this._createBackgroundCanvas(this.__subContainer, size);
213
 
220
 
214
         // create the foreground canvas
221
         // create the foreground canvas
215
         if(settings.canvas == null) {
222
         if(settings.canvas == null) {
216
-            this._foregroundCanvas = this._createForegroundCanvas(this._container, size);
223
+            this._foregroundCanvas = this._createForegroundCanvas(this.__subContainer, size);
217
             this._parentOfImportedForegroundCanvas = null;
224
             this._parentOfImportedForegroundCanvas = null;
218
         }
225
         }
219
         else {
226
         else {
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
      * Initialize the viewport (when the session starts)
438
      * Initialize the viewport (when the session starts)
423
      * @internal
439
      * @internal
424
      */
440
      */
427
         // import foreground canvas
443
         // import foreground canvas
428
         if(this._parentOfImportedForegroundCanvas != null) {
444
         if(this._parentOfImportedForegroundCanvas != null) {
429
             const size = Speedy.Size(DEFAULT_VIEWPORT_WIDTH, DEFAULT_VIEWPORT_HEIGHT);
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
         // setup CSS
449
         // setup CSS
434
         this._container.style.touchAction = 'none';
450
         this._container.style.touchAction = 'none';
435
         this._container.style.backgroundColor = 'black';
451
         this._container.style.backgroundColor = 'black';
436
-        this._container.style.zIndex = String(CONTAINER_ZINDEX);
437
 
452
 
438
         // initialize the HUD
453
         // initialize the HUD
439
         this._hud._init(HUD_ZINDEX);
454
         this._hud._init(HUD_ZINDEX);
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
      * Create a canvas and attach it to another HTML element
496
      * Create a canvas and attach it to another HTML element
462
      * @param parent parent container
497
      * @param parent parent container
463
      * @param size size of the drawing buffer
498
      * @param size size of the drawing buffer
480
      * @param size size of the drawing buffer
515
      * @param size size of the drawing buffer
481
      * @returns a new canvas as a child of parent
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
         const canvas = this._createCanvas(parent, size);
520
         const canvas = this._createCanvas(parent, size);
486
         return this._styleCanvas(canvas, BACKGROUND_ZINDEX);
521
         return this._styleCanvas(canvas, BACKGROUND_ZINDEX);
492
      * @param size size of the drawing buffer
527
      * @param size size of the drawing buffer
493
      * @returns a new canvas as a child of parent
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
         const canvas = this._createCanvas(parent, size);
532
         const canvas = this._createCanvas(parent, size);
498
         return this._styleCanvas(canvas, FOREGROUND_ZINDEX);
533
         return this._styleCanvas(canvas, FOREGROUND_ZINDEX);
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
      * Initialize the viewport
739
      * Initialize the viewport
696
      * @internal
740
      * @internal
697
      */
741
      */
800
             window.addEventListener('orientationchange', this._resize.bind(this)); // deprecated
844
             window.addEventListener('orientationchange', this._resize.bind(this)); // deprecated
801
 
845
 
802
         // trigger a resize to setup the sizes / the CSS
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
 export class ImmersiveViewport extends ResizableViewport
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
      * Release the viewport
920
      * Release the viewport
858
      * @internal
921
      * @internal
859
      */
922
      */
875
     {
938
     {
876
         super._onResize();
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
         if(this.style == 'best-fit') {
944
         if(this.style == 'best-fit') {
882
             // cover the page while maintaining the aspect ratio
945
             // cover the page while maintaining the aspect ratio

正在加载...
取消
保存