소스 검색

Introduce method _aspectRatioOfScreen(). Add comment

customisations
alemart 2 달 전
부모
커밋
27b5ba78b9
1개의 변경된 파일66개의 추가작업 그리고 7개의 파일을 삭제
  1. 66
    7
      src/core/viewport.ts

+ 66
- 7
src/core/viewport.ts 파일 보기

@@ -626,7 +626,7 @@ class ViewportResizer
626 626
 
627 627
         Ultimately, the size of the viewport is dependent on the size of the
628 628
         underlying media (typically a camera feed). When the device is rotated,
629
-        the browser should rotate the camera feed automatically*. In addition,
629
+        the browser should rotate the camera feed automatically[1]. In addition,
630 630
         it will trigger a resize event on the window, which will, in time,
631 631
         resize the viewport. If the order of events is such that the viewport
632 632
         is resized before the camera feed is rotated, then we will observe a
@@ -635,7 +635,7 @@ class ViewportResizer
635 635
         Let's correct the issue by first detecting the situation and then by
636 636
         triggering a new resize event.
637 637
 
638
-        (*) at the time of this writing, when testing on Android devices, I see
638
+        [1] at the time of this writing, when testing on Android devices, I see
639 639
             that Chrome does it. Firefox 139 does it in one device but doesn't
640 640
             do it in another (it's a browser bug - see below). Safari/iOS does
641 641
             it (tested on the cloud).
@@ -644,18 +644,19 @@ class ViewportResizer
644 644
 
645 645
         */
646 646
 
647
-        const MAX_ATTEMPTS = 3;
647
+        const MAX_ATTEMPTS = 3; //5;
648 648
         const canvas = this._viewport._backgroundCanvas;
649 649
 
650 650
         for(let i = 0; i < MAX_ATTEMPTS; i++) {
651 651
 
652
+            // this is polling
652 653
             await Utils.wait(RESIZE_THROTTLE_DELAY);
653 654
 
654 655
             // After one delay, this._viewport.aspectRatio will likely be
655 656
             // correct, but the canvas will not reflect that if, instants ago,
656 657
             // it was resized using the previous aspect ratio of the media.
657 658
             const a = canvas.width / canvas.height;
658
-            const b = screen.width / screen.height;
659
+            const b = this._aspectRatioOfScreen();
659 660
 
660 661
             // if there is a mismatch between the aspect ratios, then the last
661 662
             // resize of the viewport took place with the previous aspect ratio
@@ -663,15 +664,32 @@ class ViewportResizer
663 664
             // and that the previous viewport resize event was ineffective.
664 665
             if((a-1) * (b-1) < 0) { //if((a < 1 && b > 1) || (a > 1 && b < 1))
665 666
                 this._triggerResizeEvent();
666
-                break;
667
+                //break; // keep listening; see [2]
667 668
             }
668 669
 
669 670
             // Note: when using a canvas or a video file as a source of data,
670
-            // its aspect ratio is not expected to change. We will trigger an
671
-            // additional resize event on mobile in this case. Unlikely to be
671
+            // its aspect ratio is not expected to change. We will trigger
672
+            // additional resize events on mobile in this case. Unlikely to be
672 673
             // an issue.
673 674
 
674 675
         }
676
+
677
+        /*
678
+
679
+        [2] is this order of events possible when changing the orientation?
680
+
681
+        1. orientationchange event is fired and handled
682
+        2. resize event is fired and handled
683
+        3. camera feed is rotated
684
+
685
+        If so, increasing the throttling will likely make the camera feed be
686
+        rotated first, but then the user will more easily notice the delay.
687
+        Increasing MAX_ATTEMPTS is a simple alternative that makes this
688
+        callback be executed after the video rotation, which is what we want.
689
+        About listening to video resize: the Viewport doesn't know about it
690
+        and has no access to the source of data. The Session does, however.
691
+
692
+        */
675 693
     }
676 694
 
677 695
     /**
@@ -698,6 +716,47 @@ class ViewportResizer
698 716
         // Call strategy
699 717
         this._resizeStrategy.resize(viewport);
700 718
     }
719
+
720
+    /**
721
+     * The current aspect ratio of the screen
722
+     * @returns a value greater than 1 if the device is in landscape mode
723
+     */
724
+    private _aspectRatioOfScreen(): number
725
+    {
726
+        // When changing the orientation of a mobile device, screen.width and
727
+        // screen.height are flipped on Chrome and on Firefox, but not on Safari
728
+        //return screen.width / screen.height;
729
+
730
+        // These are the width and the height of the screen in landscape mode
731
+        const width = Math.max(screen.width, screen.height);
732
+        const height = Math.min(screen.width, screen.height);
733
+
734
+        // use screen.orientation if possible
735
+        if(typeof screen.orientation === 'object') {
736
+            if(screen.orientation.type.startsWith('landscape'))
737
+                return width / height;
738
+            else
739
+                return height / width;
740
+        }
741
+
742
+        // fallback for older iOS
743
+        // https://developer.apple.com/documentation/webkitjs/domwindow/1632568-orientation
744
+        if(typeof window.orientation === 'number') {
745
+            if(Math.abs(window.orientation) == 90)
746
+                return width / height;
747
+            else
748
+                return height / width;
749
+        }
750
+
751
+        // general fallback
752
+        // note: before evaluating clientWidth & clientHeight, a setTimeout(fn,
753
+        // t >= 100?) is necessary immediately after a change of orientation.
754
+        // mobile devices should not fall in this case, so no worries.
755
+        if(document.documentElement.clientWidth > document.documentElement.clientHeight)
756
+            return width / height;
757
+        else
758
+            return height / width;
759
+    }
701 760
 }
702 761
 
703 762
 

Loading…
취소
저장