Selaa lähdekoodia

解决微信浏览器横屏问题

黄琪勇 11 kuukautta sitten
vanhempi
commit
b6f75388fd

+ 15 - 0
src/views/creation/playCreation/index.module.less

@@ -10,6 +10,18 @@
     left: 50%;
     transform: translate(-50%, -50%) rotate(90deg);
     transform-origin: center;
+    :global{
+      .plyr .plyr__controls__item.plyr__progress__container input{
+        pointer-events: none;
+      }
+    }
+  }
+  &.notLoaded{
+    :global{
+      .plyr .plyr__controls {
+        display: none;
+      }
+    }
   }
   :global {
       .plyr {
@@ -85,6 +97,9 @@
               }
 
           }
+          .plyr__tooltip{
+            display: none;
+          }
       }
   }
   .videoBox{

+ 90 - 11
src/views/creation/playCreation/index.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, onMounted, reactive, ref, onUnmounted } from 'vue';
+import { defineComponent, onMounted, reactive, ref, onUnmounted, watch } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { browser } from "@/helpers/utils"
 import styles from './index.module.less';
@@ -11,6 +11,7 @@ import backImg from "../images/back.png";
 import {
   postMessage
 } from '@/helpers/native-message';
+import { usePageVisibility } from '@vant/use';
 
 export default defineComponent({
   name: 'playCreation',
@@ -24,11 +25,25 @@ export default defineComponent({
     const playType = resourceUrl.lastIndexOf('mp4') !== -1 ? 'Video' : 'Audio'
     const lottieDom = ref()
     const landscapeScreen = ref(false)
+    let _plrl:any
+    const loaded = ref(false)
+    const { registerDrag, unRegisterDrag } = landscapeScreenDrag()
+    watch(landscapeScreen, ()=>{
+      if(landscapeScreen.value){
+        registerDrag()
+      }else{
+        unRegisterDrag()
+      }
+    })
     function initPlay(){
       const id = playType === "Audio" ? "#audioMediaSrc" : "#videoMediaSrc";
-      const _plrl = new Plyr(id, {
+      _plrl = new Plyr(id, {
         controls: ["play-large", "play", "progress", "current-time", "duration"]
       });
+      // 在微信中运行的时候,微信没有开放自动加载资源的权限,所以要等播放之后才显示播放控制器
+      _plrl.on('loadedmetadata', () => {
+        loaded.value = true
+      });
       // 创建音波数据
       if(playType === "Audio"){
         const audioDom = document.querySelector("#audioMediaSrc") as HTMLAudioElement
@@ -44,7 +59,61 @@ export default defineComponent({
         });
       }
     }
-        /**
+    // 注册 横屏时候的自定义拖动事件 解决旋转时候拖动进度条坐标的问题
+    function landscapeScreenDrag() {
+      let progressBar: HTMLElement
+      function onDown(e: MouseEvent | TouchEvent) {
+        e.preventDefault();
+        e.stopPropagation();
+        // 记录拖动之前的状态
+        const playing = _plrl.playing
+        _plrl.pause()
+        const isTouchEv = isTouchEvent(e);
+        const event = isTouchEv ? e.touches[0] : e;
+        setProgress(event)
+        function onUp() {
+          document.removeEventListener(
+            isTouchEv ? 'touchmove' : 'mousemove',
+            onMove
+          );
+          document.removeEventListener(isTouchEv ? 'touchend' : 'mouseup', onUp);
+          playing && _plrl.play()  // 之前是播放状态  就播放
+        }
+        function onMove(e: MouseEvent | TouchEvent){
+          e.preventDefault();
+          e.stopPropagation();
+          const event = isTouchEvent(e) ? e.touches[0] : e;
+          setProgress(event)
+        }
+        function setProgress(event: MouseEvent | Touch) {
+          const {top, height} = progressBar.getBoundingClientRect();
+          const progress = (event.clientY - top) / height;
+          const progressNum = Math.min(Math.max(progress, 0), 1);
+          _plrl.currentTime = progressNum * _plrl.duration
+        }
+        document.addEventListener(isTouchEv ? 'touchmove' : 'mousemove', onMove);
+        document.addEventListener(isTouchEv ? 'touchend' : 'mouseup', onUp);
+      }
+      function registerDrag() {
+        if(!progressBar){
+          progressBar = document.querySelector('#landscapeScreenPlay .plyr__progress__container') as HTMLElement;
+        }
+        progressBar.addEventListener('mousedown', onDown);
+        progressBar.addEventListener('touchstart', onDown);
+      }
+      function unRegisterDrag() {
+        progressBar.removeEventListener('mousedown', onDown);
+        progressBar.removeEventListener('touchstart', onDown);
+      }
+      return {
+        registerDrag,
+        unRegisterDrag
+      }
+    }
+    function isTouchEvent(e: MouseEvent | TouchEvent): e is TouchEvent {
+      return window.TouchEvent && e instanceof window.TouchEvent;
+    }
+    /**
      * 音频可视化
      * @param audioDom
      * @param canvasDom
@@ -72,7 +141,8 @@ export default defineComponent({
         fillCanvasBackground(ctx, w, h, canvFillColor)
           // 可视化
         const dataLen = data.length
-        const step = (w / 2 - lineGap * dataLen) / dataLen
+        let step = (w / 2 - lineGap * dataLen) / dataLen
+        step < 1 && (step = 1)
         const midX = w / 2
         const midY = h / 2
         let xLeft = midX
@@ -157,15 +227,24 @@ export default defineComponent({
       }
     }
     function updateLandscapeScreenState(){
-      if(window.innerWidth > window.innerHeight){
-        landscapeScreen.value = false
-      }else{
-        landscapeScreen.value = true
-      }
+      // 下一帧 计算  横竖屏切换太快  获取的宽高不准
+      requestAnimationFrame(()=>{
+        if(window.innerWidth > window.innerHeight){
+          landscapeScreen.value = false
+        }else{
+          landscapeScreen.value = true
+        }
+      })
     }
-    handlerLandscapeScreen()
+    const pageVisibility = usePageVisibility();
+    watch(pageVisibility, value => {
+      if (value === 'hidden') {
+        _plrl?.pause();
+      }
+    });
     onMounted(()=>{
       initPlay()
+      handlerLandscapeScreen()
     })
     onUnmounted(()=>{
       if(isApp){
@@ -180,7 +259,7 @@ export default defineComponent({
       }
     })
     return () =>
-    <div class={[styles.playCreation,landscapeScreen.value && styles.landscapeScreen]}>
+    <div id="landscapeScreenPlay" class={[styles.playCreation,landscapeScreen.value && styles.landscapeScreen,!loaded.value && styles.notLoaded]}>
       <div class={styles.backBox}>
         <img class={styles.backImg} src={backImg}onClick={handlerBack} />
         <div class={styles.musicDetail}>