浏览代码

New viewport style: crop. Closes #13

customisations
alemart 2 个月前
父节点
当前提交
8d55c9d0e0
共有 2 个文件被更改,包括 45 次插入22 次删除
  1. 3
    2
      docs/api/viewport.md
  2. 42
    20
      src/core/viewport.ts

+ 3
- 2
docs/api/viewport.md 查看文件

79
 
79
 
80
 The style determines the way the viewport appears on the screen. Different styles are applicable to different [session modes](session.md#mode). The following are valid styles:
80
 The style determines the way the viewport appears on the screen. Different styles are applicable to different [session modes](session.md#mode). The following are valid styles:
81
 
81
 
82
-* `"best-fit"`: an immersive viewport that is scaled in a way that covers the page while preserving the aspect ratio of the augmented scene.
83
-* `"stretch"`: an immersive viewport that is scaled in a way that covers the entire page, stretching the augmented scene if necessary.
82
+* `"best-fit"`: an immersive viewport that is scaled in a way that covers the page while preserving the aspect ratio of the augmented scene. This is known as letterboxing or pillarboxing.
83
+* `"stretch"`: an immersive viewport that is scaled in a way that fills the entire page, stretching the augmented scene if necessary.
84
+* `"crop"`: an immersive viewport that is scaled in a way that fills the entire page, cropping the augmented scene if necessary to maintain its aspect ratio. *Since:* 0.4.4
84
 * `"inline"`: an inline viewport that follows the typical flow of a web page.
85
 * `"inline"`: an inline viewport that follows the typical flow of a web page.
85
 
86
 
86
 The default style is `"best-fit"` in immersive mode, or `"inline"` in inline mode.
87
 The default style is `"best-fit"` in immersive mode, or `"inline"` in inline mode.

+ 42
- 20
src/core/viewport.ts 查看文件

52
 class ViewportEventTarget extends AREventTarget<ViewportEventType> { }
52
 class ViewportEventTarget extends AREventTarget<ViewportEventType> { }
53
 
53
 
54
 /** Viewport style (immersive mode) */
54
 /** Viewport style (immersive mode) */
55
-type ViewportStyle = 'best-fit' | 'stretch' | 'inline';
55
+type ViewportStyle = 'best-fit' | 'stretch' | 'crop' | 'inline';
56
 
56
 
57
 
57
 
58
 
58
 
308
         canvas.style.width = '100%';
308
         canvas.style.width = '100%';
309
         canvas.style.height = '100%';
309
         canvas.style.height = '100%';
310
         canvas.style.zIndex = String(zIndex);
310
         canvas.style.zIndex = String(zIndex);
311
+        canvas.style.objectFit = 'unset';
311
 
312
 
312
         return canvas;
313
         return canvas;
313
     }
314
     }
586
                 this.setStrategy(new StretchResizeStrategy());
587
                 this.setStrategy(new StretchResizeStrategy());
587
                 break;
588
                 break;
588
 
589
 
590
+            case 'crop':
591
+                this.setStrategy(new CropResizeStrategy());
592
+                break;
593
+
589
             case 'inline':
594
             case 'inline':
590
                 this.setStrategy(new InlineResizeStrategy());
595
                 this.setStrategy(new InlineResizeStrategy());
591
                 break;
596
                 break;
786
     {
791
     {
787
         viewport.container.style.cssText = '';
792
         viewport.container.style.cssText = '';
788
         viewport._subContainer.style.cssText = '';
793
         viewport._subContainer.style.cssText = '';
794
+        viewport._backgroundCanvas.style.objectFit = 'unset';
795
+        viewport.canvas.style.objectFit = 'unset';
789
     }
796
     }
790
 }
797
 }
791
 
798
 
843
 }
850
 }
844
 
851
 
845
 /**
852
 /**
846
- * Immersive viewport with best-fit style: it occupies the entire page and
847
- * preserves the aspect ratio of the media
853
+ * Immersive viewport with best-fit style: it preserves the aspect ratio of the
854
+ * media. This is also known as letterboxing or pillarboxing
848
  */
855
  */
849
 class BestFitResizeStrategy extends ImmersiveResizeStrategy
856
 class BestFitResizeStrategy extends ImmersiveResizeStrategy
850
 {
857
 {
883
 }
890
 }
884
 
891
 
885
 /**
892
 /**
886
- * Immersive viewport with stretch style: it occupies the entire page and
887
- * fully stretches the media, possibly distorting it
893
+ * Immersive viewport with stretch style: it fully fills the viewport with the
894
+ * media, possibly distorting it
888
  */
895
  */
889
 class StretchResizeStrategy extends ImmersiveResizeStrategy
896
 class StretchResizeStrategy extends ImmersiveResizeStrategy
890
 {
897
 {
906
     }
913
     }
907
 }
914
 }
908
 
915
 
916
+/**
917
+ * Immersive viewport with crop style: it fully fills the viewport with the
918
+ * media, possibly cropping and scaling it to maintain its aspect ratio
919
+ */
920
+class CropResizeStrategy extends ImmersiveResizeStrategy
921
+{
922
+    /**
923
+     * Resize the viewport
924
+     * @param viewport
925
+     */
926
+    resize(viewport: Viewport): void
927
+    {
928
+        const subContainer = viewport._subContainer;
929
+        const backgroundCanvas = viewport._backgroundCanvas;
930
+        const foregroundCanvas = viewport.canvas;
931
+
932
+        subContainer.style.position = 'absolute';
933
+        subContainer.style.left = '0px';
934
+        subContainer.style.top = '0px';
935
+        subContainer.style.width = window.innerWidth + 'px';
936
+        subContainer.style.height = window.innerHeight + 'px';
937
+
938
+        backgroundCanvas.style.objectFit = 'cover';
939
+        foregroundCanvas.style.objectFit = 'cover';
940
+
941
+        super.resize(viewport);
942
+    }
943
+}
944
+
909
 
945
 
910
 
946
 
911
 
947
 
990
     }
1026
     }
991
 
1027
 
992
     /**
1028
     /**
993
-     * Set viewport style
994
-     */
995
-    /*
996
-    set style(value: ViewportStyle)
997
-    {
998
-        // note: the viewport style is independent of the session mode!
999
-        if(value !== this._style) {
1000
-            this._resizer.setStrategyByName(value);
1001
-            this._style = value;
1002
-        }
1003
-    }
1004
-    */
1005
-
1006
-    /**
1007
      * HUD
1029
      * HUD
1008
      */
1030
      */
1009
     get hud(): HUD
1031
     get hud(): HUD
1182
     {
1204
     {
1183
         // validate if the viewport style matches the session mode
1205
         // validate if the viewport style matches the session mode
1184
         if(sessionMode == 'immersive') {
1206
         if(sessionMode == 'immersive') {
1185
-            if(this._style != 'best-fit' && this._style != 'stretch') {
1207
+            if(this._style != 'best-fit' && this._style != 'stretch' && this._style != 'crop') {
1186
                 Utils.warning(`Invalid viewport style \"${this._style}\" for the \"${sessionMode}\" mode`);
1208
                 Utils.warning(`Invalid viewport style \"${this._style}\" for the \"${sessionMode}\" mode`);
1187
                 this._style = 'best-fit';
1209
                 this._style = 'best-fit';
1188
                 this._resizer.setStrategyByName(this._style);
1210
                 this._resizer.setStrategyByName(this._style);

正在加载...
取消
保存