|
@@ -52,7 +52,7 @@ class ViewportEvent extends AREvent<ViewportEventType> { }
|
52
|
52
|
class ViewportEventTarget extends AREventTarget<ViewportEventType> { }
|
53
|
53
|
|
54
|
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,6 +308,7 @@ class ViewportCanvases
|
308
|
308
|
canvas.style.width = '100%';
|
309
|
309
|
canvas.style.height = '100%';
|
310
|
310
|
canvas.style.zIndex = String(zIndex);
|
|
311
|
+ canvas.style.objectFit = 'unset';
|
311
|
312
|
|
312
|
313
|
return canvas;
|
313
|
314
|
}
|
|
@@ -586,6 +587,10 @@ class ViewportResizer
|
586
|
587
|
this.setStrategy(new StretchResizeStrategy());
|
587
|
588
|
break;
|
588
|
589
|
|
|
590
|
+ case 'crop':
|
|
591
|
+ this.setStrategy(new CropResizeStrategy());
|
|
592
|
+ break;
|
|
593
|
+
|
589
|
594
|
case 'inline':
|
590
|
595
|
this.setStrategy(new InlineResizeStrategy());
|
591
|
596
|
break;
|
|
@@ -786,6 +791,8 @@ abstract class ViewportResizeStrategy
|
786
|
791
|
{
|
787
|
792
|
viewport.container.style.cssText = '';
|
788
|
793
|
viewport._subContainer.style.cssText = '';
|
|
794
|
+ viewport._backgroundCanvas.style.objectFit = 'unset';
|
|
795
|
+ viewport.canvas.style.objectFit = 'unset';
|
789
|
796
|
}
|
790
|
797
|
}
|
791
|
798
|
|
|
@@ -843,8 +850,8 @@ abstract class ImmersiveResizeStrategy extends ViewportResizeStrategy
|
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
|
856
|
class BestFitResizeStrategy extends ImmersiveResizeStrategy
|
850
|
857
|
{
|
|
@@ -883,8 +890,8 @@ class BestFitResizeStrategy extends ImmersiveResizeStrategy
|
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
|
896
|
class StretchResizeStrategy extends ImmersiveResizeStrategy
|
890
|
897
|
{
|
|
@@ -906,6 +913,35 @@ class StretchResizeStrategy extends ImmersiveResizeStrategy
|
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,20 +1026,6 @@ export class Viewport extends ViewportEventTarget
|
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
|
1029
|
* HUD
|
1008
|
1030
|
*/
|
1009
|
1031
|
get hud(): HUD
|
|
@@ -1182,7 +1204,7 @@ export class Viewport extends ViewportEventTarget
|
1182
|
1204
|
{
|
1183
|
1205
|
// validate if the viewport style matches the session mode
|
1184
|
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
|
1208
|
Utils.warning(`Invalid viewport style \"${this._style}\" for the \"${sessionMode}\" mode`);
|
1187
|
1209
|
this._style = 'best-fit';
|
1188
|
1210
|
this._resizer.setStrategyByName(this._style);
|