Pārlūkot izejas kodu

Merge branch 'iteration-oss-up' into jenkins-main

lex 1 gadu atpakaļ
vecāks
revīzija
14f6e8bd88

+ 57 - 0
src/views/coursewarePlay/component/video-item/index.module.less

@@ -1,4 +1,5 @@
 .videoWrap {
+  position: relative;
   width: 100%;
   height: 100%;
 
@@ -156,4 +157,60 @@
       }
     }
   }
+}
+
+.sliderPopup {
+  position: absolute;
+  z-index: 9999;
+  left: 74px;
+  bottom: 46px;
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  height: 165px;
+  width: 45px;
+  padding: 10px 0 15px;
+  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFoAAAGaCAMAAAC46aQwAAAAOVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8dlA9AAAAE3RSTlNaAAxUVwdPRSc7MzYsEEoXGgshjXaABwAAAZBJREFUeNrt1GtO40AQReF77X46tvPY/2IHhiCDA0Ez7pb4cb4FHLVaVSU/isM/i360S5+nnIL+Q0h5On+fXuqoQ8a6fJm+VjVQr4/pEtREKPt0VTP1UzpmNZTjh3RWU3lLn9TY6T1d1Fx5S8eg5kL8m57UwfSaHoI6CIPlSV1MlpO6SNaiThbN6mRWVSdVWZ1kJXWSFNRJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg9wnqJGhVJ6uyOsmq6qSqqJOiqzq5yqu6WC3P6mK2HEd1MEbLfZ49+zXtpOaS39IXNXe5p13UWPF72ic1dfKW9ql1eUu7tP2NLf3inNREOnuXflFGHTaWrSdvYsk6JJfoXXoTb1PNabwL+kEY71Ku023r7tOPYv5pFJ6Rn5qfj8KRtC+jvjGefSztYdWX1sFH0k82tUY3SPsWtDfZTdJekj4JN7dKO1Z9kBY3ST+er3x10/R2vqrdOO04BUnp4nbpTVwug30g3cwf1jMLKix6VfsAAAAASUVORK5CYII=') no-repeat top center;
+  background-size: contain;
+
+  .iconAdd,
+  .iconCut {
+    display: inline-block;
+    width: 24px;
+    height: 24px;
+    background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABgFBMVEUAAADScFLSc1LRclPRc1PQc1TOcVH9gVn9noDQclPQclPRclTQc1PQclPRclPRclPQclTQc1TRclT/kGrTdVD/kme/YED4gVr/mHb/hl//glz/mHX/h1//j2r/lnT/jmn/j2n/mnr/hV3/m3r/hF3/i2T/mXr/hFv+nX/5m3z/imT/nX3/hl//g1v5m3z5gFj/kG3/gVr/nHv/hFz9oYP9gVn/nH3/mnr/lXP/////jmr/iWP/hl//lnT/i2X/iGH/mHb/mnrQclP/jGf/jWj/nHz/nn//nX3/mXj/lXP/lHH/kGz/hV7/n4D/k3D/hFz/kW3/oIL/km7/g1r/oYP/v6v/mnn/xbP/u6b/vqj/9vP/x7X/wa3/uKLfgGH/uqT/2Mvpi2zfelnUdFT/spn/sJb/rZL/qY39oILwknP6k3HdfF3wf1rofVred1b/0MH/zb3/y7r/tZ33mnv0lXXvjWzviGX0h2TohWTWeFn/yLb/wq//pYj/o4b3j23rgF0pNa8/AAAAOXRSTlMAGTPvX1I//f78++jPxbawkm1DIyMKCP2EhFFHR/j069fQ0Lq6rahYUPj28fHxzc2xqJWViopYWFKR82o3AAADFUlEQVRIx6WVZV8iURjFBwnpstfO7U5B6iolitJIGdi1dmx+9X1ucWcG0Bd7XvJ7/pxz5rlzR2pSz2D/u7HR4eHRsemBoR7pMQ3OjKRXVxMej2dh3u/3v5geenD82/jiYjKdZgAQXm9g4knb8a5JXzxOgQQACxQIzE11tZ7/OuLz+eJgwTNxYO7V01bz/bFgEAPJZmBpaaB5/kMeAJXDPACUWPnY9P+hfCy8lxIlWGsOrKg8voRD+b2fhcIuz6RojYmMokfXy1BorwC6oJnSCZEpwCxey5/VZDT8G8+v56lD+rxUOldlykyJ+WeRaDQH89UYtMbE9ixoR5ZpCTJlxAbHI9GdcrlQzAeDFFjDQJEBXgKAxUTj/EQi0QoAKb4JBngUrcGCn6uZ5Ui0UC7viE1QQGyCAe/ZeTYCsF3OhRkQlwHKEp09tHJqGYhfkVAoRggBKDNleO1PBAiHBLCoBICgrTOfCfCGAkDwTAIQFgR4S4DnqRQAxKJaqeSwNjCwUSwW19er1V0gWIk+PK8xYoBYfJ9tqbJorQHAsJ/lmUqtgVKAZ+o0AKBnQLQ94G0AegB0xizN1DbSD7YJAHQYuMxiC3AI49IVWWnaeheeE9tEHwb0BxiIkEx8EzkMrPEXW5y/Yz0uvQlASmxCAKr3FIgTXFpTy1ILIBjg44B6dacaCaTdJ4A4HQoHsBDHSSthOXgJkYkC4nZirY8dBHDVyGNirZWAMtOpiwAa8yXbhNpB1brPrJGI7DWeiVtcYGCb3k4i06ldonKjKxXgOyuVzpIY4BbgcIzcEpPt3ohLiEytbsy5uk3i6jDVyOo4IG5x2YPdMnVIDTnRJlgIosV34gQ5JaFeK9oEQJRQA/6/yNorydRtAQIApUO6sYkTZOmWFOrQolpY1ToJACH8W0jLCwjCgu4PaCb1t+u2jixiXqSyIlS7as50u4WQVeSRN3eaEDq6jsVkmRI3MG5yir6qWDaEUP3o7vrwMB4//HNzd1SHH2wQp63cdjNSyGx3Sw9L43Jo+bTW4WLn8zHIoNfp9AY8/P/6B/HduOmd67HcAAAAAElFTkSuQmCC') no-repeat center;
+    background-size: contain;
+    flex-shrink: 0;
+
+    &.disabled {
+      opacity: 0.7;
+    }
+  }
+
+  .iconCut {
+    background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAABblBMVEUAAADQclPRclPRc1PQc1TOcVHWcFL9nn/9gVnRclTQc1PQclPRclPRclPQclTQc1TRclTTcVPRdVL/kGrTdVDMcFK/YED4gVr/jWj/g1z/mnv/mHX/jGP8nH3/hV3/mnr9gVj/m3r/hF3/j2n/j2n/m3v/m3r/hF3/hV3+f1n/iWL/k3D/mHj/j2v/jWj/kWz/jWf/iGH5m3z/km3/jGb/n4H/g1r/nHr/hVz9oYH/onT/k2//////lnP/nHz/kW7/l3X/iGH/nn7/kGz/mXj/jmn/jWj/imT/n4DQclP/i2b/m3v/jGf/mnr/lHL/j2r/mHb/hl//iWP/g1v/lHH/oYL/hV3/uqT/glr/iWT/vKb/ooT/8+//8e3/tp7/sJbxk3TgelnpjG3wjGvef2Dwf1rofVrWd1jUc1T/rJH3mnv7k3HoiGj5imbwhmPggWLqgl/dfV7delrdd1X/qo//qY32lXX3knH3j23ggmNgaUIIAAAAO3RSTlMA/O9fUj8Z/v3oz8W2sJJtQzQyIyMZCP34hVFHCvXx0M+6uqiGg1hYUktH9vHr69fX0M2xsaiolZWKC4MOlxYAAALWSURBVEjHhNLZV4JAGAXwznF95yHNLZeybN8XEx1A4eBCgCJa6XPv9f93ZRgBwZzn++O7HzN7oZNv1O6vLzOZi6u7Wi6/t+s0qhlZVQe9blcT2+3mWTX3b/zkhhgGBZoDmuNR6WBrnKvohBiyjDwmiCLyAK1WmYvO14u6D2gUIN/qnB9H5bPWgB+hEfJsBTqg03mXjsL5Z0uazucfDGhBMHwKfd+UpgC/XiMfkKThcGNG3dSmAEuZDgCgeQAMWIF+YA+uqC8AfgwCoIZWQKU+X+B8oGIKyC8J2bYCAF/23ZdtLgG6AIEVxgEgeDd4aJtoJOgk1MhZgYESy5/apsmjEPKz9S2IvkaSkxcU9q4eAawecQZQgHxoBYAH9z2nTQBL9wH2LgDoP6Ig9eo2ooBQEGwEILlAURS6dta2nQEQUbdAAQZAvLj/iDUitJH/aaMR2xkTbh2wvwYbD2nEHhIDk8Iqn/Tv/P31Fjqfiz4DqSRAIr3OGzLyEYLlJ5MEQNwDs50gDhDzgKxGV+IZSMVW4K+1MtlNGAiCaI8xjrwvss3XcEqEUodEisSNi9kREFYpy9+HiU16zNhRDnlnl7rL1d3TKwV8L9S54NhkgbUUmPOLQBZoSeGpTOFRVihMaXrBFpRdGHJsbGEiTVvnWgr6ILFgNLPoglEK2reTKxgk8efye2079Y5GhU+S8MwWBixo6igkSSZ67RbUjtYio2+8MVsY6BausY32HpVEmMuOGlNQYisQUYW7eikFioV+JeBJXbp0JRbjGwtD3fOniOmHAAu2oB4Y9jxBQEzu4ND0LnCBCZycFFIbCz02/qlb2CnVSAyMX/mo1tf5bg8joRsSG8td84EplrAT0kgdXIrog/Q2A5yUGsgDAZx29+VclDE/TI+ACHJqJnYBrE6H6cfmub95n26PKwBuTO1EnkAN4UX0O1noG6gw/DCjv2B1zU7H7Fr0H3wBmgjEIb8TJS0AAAAASUVORK5CYII=') no-repeat center;
+    background-size: contain;
+  }
+
+  .sliderPoint {
+    background: #FFFFFF;
+    box-shadow: 0px 2px 4px 0px rgba(102, 102, 102, 0.77);
+    border-radius: 10px;
+    font-size: 14px;
+    font-weight: 500;
+    color: #FF8057;
+    min-width: 35px;
+    text-align: center;
+    vertical-align: text-bottom;
+
+    span {
+      font-size: 12px;
+    }
+  }
+
+  :global {
+    .van-slider {
+      margin: 7px 0;
+    }
+  }
 }

+ 77 - 60
src/views/coursewarePlay/component/video-item/index.tsx

@@ -1,10 +1,12 @@
-import { defineComponent, nextTick, onMounted, reactive, toRefs, watch } from 'vue'
+import { defineComponent, nextTick, onMounted, reactive, render, toRefs, watch } from 'vue'
 import 'plyr/dist/plyr.css'
 import Plyr from 'plyr'
 import styles from './index.module.less'
-import iconSpeed from '../../image/video-speed1.png'
+import iconSpeed from '../../image/video-speed.png'
 
 import { iconVideoBg, iconLoop, iconLoopActive, iconPlay, iconPause } from '../../image/icons.json'
+import { Popup, Slider } from 'vant'
+import { useElementBounding } from '@vueuse/core'
 
 export default defineComponent({
   name: 'video-play',
@@ -29,6 +31,9 @@ export default defineComponent({
       animationState: 'start' as 'start' | 'end',
       videoItem: null as unknown as Plyr,
       speedControl: false,
+      speedStyle: {
+        left: '1px'
+      },
       defaultSpeed: 1 // 默认速度
     })
     const controlID = 'v' + Date.now() + Math.floor(Math.random() * 100)
@@ -39,6 +44,7 @@ export default defineComponent({
 
     const togglePlay = (e: Event) => {
       e.stopPropagation()
+      data.speedControl = false
       if (!data.videoContianerRef.paused) {
         data.videoItem?.pause()
       } else {
@@ -46,6 +52,7 @@ export default defineComponent({
       }
     }
     const toggleLoop = () => {
+      data.speedControl = false
       const loopBtn = document.getElementById(loopBtnId)
       if (!loopBtn || !data.videoItem) return
       const isLoop = data.videoItem.loop
@@ -59,40 +66,21 @@ export default defineComponent({
     const onDefault = () => {
       document.getElementById(controlID)?.addEventListener('click', (e: Event) => {
         e.stopPropagation()
+        data.speedControl = false
         if (data.videoContianerRef.paused) return
         emit('close')
       })
       document.getElementById(controlID)?.addEventListener('touchmove', () => {
+        data.speedControl = false
         if (data.videoContianerRef.paused) return
         emit('close')
       })
       document.getElementById(playBtnId)?.addEventListener('click', togglePlay)
       document.getElementById(loopBtnId)?.addEventListener('click', toggleLoop)
 
-      document.getElementById(speedBtnId)?.addEventListener('click', () => {
+      document.getElementById(speedBtnId)?.addEventListener('click', (e) => {
+        e.stopPropagation()
         data.speedControl = !data.speedControl
-        // const element = document.getElementById(speedPopoverId)
-        // if (data.speedControl) {
-        //   element?.classList.add(styles.active)
-        // } else {
-        //   element?.classList.remove(styles.active)
-        // }
-        toggleSpeedControl(data.speedControl)
-      })
-
-      const nodeList = document.querySelectorAll('#' + speedPopoverId + ' .videoPlaySpeedItem')
-      nodeList.forEach((item) => {
-        item?.addEventListener('click', (e) => {
-          nodeList.forEach((child) => {
-            child?.classList.remove('active')
-          })
-          const target: any = e?.target
-          item?.classList.add('active')
-          data.videoItem.speed = target?.dataset.value * 1
-          data.defaultSpeed = target?.dataset.value * 1
-          // 设置完速度之后关闭弹窗
-          toggleSpeedControl(false)
-        })
       })
 
       setName()
@@ -143,28 +131,6 @@ export default defineComponent({
                           <button id="${speedBtnId}" class="${styles.actionBtn} ${styles.speedBtn}">
                               <img class="loop" src="${iconSpeed}" />
                           </button>
-                          <div class="${styles.popoverGroup}" id="${speedPopoverId}">
-                            <div class="videoPlaySpeedItem active" data-value="1">
-                              <i class="point" data-value="1"></i>
-                              <span data-value="1">1倍</span>
-                            </div>
-                            <div class="videoPlaySpeedItem" data-value="1.25">
-                              <i class="point" data-value="1.25"></i>
-                              <span data-value="1.25">1.25倍</span>
-                            </div>
-                            <div class="videoPlaySpeedItem" data-value="1.5">
-                              <i class="point" data-value="1.5"></i>
-                              <span data-value="1.5">1.5倍</span>
-                            </div>
-                            <div class="videoPlaySpeedItem" data-value="1.75">
-                              <i class="point" data-value="1.75"></i>
-                              <span data-value="1.75">1.75倍</span>
-                            </div>
-                            <div class="videoPlaySpeedItem" data-value="2">
-                              <i class="point" data-value="2"></i>
-                              <span data-value="2">2倍</span>
-                            </div>
-                          </div>
                         </div>
                     </div>
                     <div id="videoItemName"></div>
@@ -186,22 +152,11 @@ export default defineComponent({
       })
     })
 
-    const toggleSpeedControl = (isShow: boolean) => {
-      const element = document.getElementById(speedPopoverId)
-      if (isShow) {
-        element?.classList.add(styles.active)
-        data.speedControl = true
-      } else {
-        element?.classList.remove(styles.active)
-        data.speedControl = false
-      }
-    }
-
     const toggleHideControl = (isShow: boolean) => {
       data.videoItem?.toggleControls(isShow)
 
       if (!isShow) {
-        toggleSpeedControl(isShow)
+        data.speedControl = isShow
       }
     }
     watch(
@@ -219,7 +174,7 @@ export default defineComponent({
         if (data.videoItem) data.videoItem.speed = data.defaultSpeed || 1
 
         // 切换的时候隐藏
-        toggleSpeedControl(false)
+        data.speedControl = false
       }
     )
     let videoTimer = null as any
@@ -305,6 +260,68 @@ export default defineComponent({
           }}
           onError={handleErrorVideo}
         ></video>
+
+        <div
+          style={{
+            display: data.speedControl ? 'block' : 'none'
+          }}
+        >
+          <div
+            class={styles.sliderPopup}
+            onClick={(e: Event) => {
+              e.stopPropagation()
+            }}
+          >
+            <i
+              class={styles.iconAdd}
+              onClick={() => {
+                if (data.defaultSpeed >= 1.5) {
+                  return
+                }
+
+                if (data.videoItem) {
+                  data.defaultSpeed = (data.defaultSpeed * 10 + 1) / 10
+                  data.videoItem.speed = data.defaultSpeed
+                }
+              }}
+            ></i>
+            <Slider
+              min={0.5}
+              max={1.5}
+              step={0.1}
+              v-model={data.defaultSpeed}
+              vertical
+              barHeight={5}
+              reverse
+              onChange={() => {
+                if (data.videoItem) {
+                  data.videoItem.speed = data.defaultSpeed
+                }
+              }}
+            >
+              {{
+                button: () => (
+                  <div class={styles.sliderPoint}>
+                    {data.defaultSpeed}
+                    <span>x</span>
+                  </div>
+                )
+              }}
+            </Slider>
+            <i
+              class={[styles.iconCut]}
+              onClick={() => {
+                if (data.defaultSpeed <= 0.5) {
+                  return
+                }
+                if (data.videoItem) {
+                  data.defaultSpeed = (data.defaultSpeed * 10 - 1) / 10
+                  data.videoItem.speed = data.defaultSpeed
+                }
+              }}
+            ></i>
+          </div>
+        </div>
       </div>
     )
   }

BIN
src/views/coursewarePlay/image/icon-speed-add.png


BIN
src/views/coursewarePlay/image/icon-speed-bg.png


BIN
src/views/coursewarePlay/image/icon-speed-cut.png


BIN
src/views/coursewarePlay/image/video-speed.png


BIN
src/views/coursewarePlay/image/video-speed1.png