Browse Source

ppt播放器优化

黄琪勇 4 weeks ago
parent
commit
1a387b7762

+ 7 - 1
src/store/main.ts

@@ -36,6 +36,7 @@ export interface MainState {
   showSelectPanel: boolean
   showSearchPanel: boolean
   showNotesPanel: boolean
+  isPPTWheelPage: boolean
 }
 
 const nanoid = customAlphabet("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
@@ -69,7 +70,8 @@ export const useMainStore = defineStore("main", {
     shapeFormatPainter: null, // 形状格式刷
     showSelectPanel: false, // 打开选择面板
     showSearchPanel: false, // 打开查找替换面板
-    showNotesPanel: false // 打开批注面板
+    showNotesPanel: false, // 打开批注面板
+    isPPTWheelPage: true //控制ppt能不能滚轮翻页,音频播放器列表页使用
   }),
 
   getters: {
@@ -194,6 +196,10 @@ export const useMainStore = defineStore("main", {
 
     setNotesPanelState(show: boolean) {
       this.showNotesPanel = show
+    },
+
+    setIsPPTWheelPageState(isWheel: boolean) {
+      this.isPPTWheelPage = isWheel
     }
   }
 })

+ 6 - 3
src/views/Editor/Canvas/index.vue

@@ -134,7 +134,8 @@ const {
   creatingElement,
   creatingCustomShape,
   canvasScale,
-  textFormatPainter
+  textFormatPainter,
+  isPPTWheelPage
 } = storeToRefs(mainStore)
 const { currentSlide } = storeToRefs(useSlidesStore())
 const { ctrlKeyState, spaceKeyState } = storeToRefs(useKeyboardStore())
@@ -230,15 +231,17 @@ const throttleScaleCanvas = throttle(scaleCanvas, 100, { leading: true, trailing
 const throttleUpdateSlideIndex = throttle(updateSlideIndex, 300, { leading: true, trailing: false })
 
 const handleMousewheelCanvas = (e: WheelEvent) => {
-  e.preventDefault()
-
   // 按住Ctrl键时:缩放画布
   if (ctrlKeyState.value) {
+    e.preventDefault()
     if (e.deltaY > 0) throttleScaleCanvas("-")
     else if (e.deltaY < 0) throttleScaleCanvas("+")
   }
   // 上下翻页
   else {
+    // 控制能不能翻页
+    if (!isPPTWheelPage.value) return
+    e.preventDefault()
     if (e.deltaY > 0) throttleUpdateSlideIndex(KEYS.DOWN)
     else if (e.deltaY < 0) throttleUpdateSlideIndex(KEYS.UP)
   }

+ 5 - 1
src/views/Screen/hooks/useExecPlay.ts

@@ -1,7 +1,7 @@
 import { onMounted, onUnmounted, ref } from "vue"
 import { throttle } from "lodash"
 import { storeToRefs } from "pinia"
-import { useSlidesStore, useScreenStore } from "@/store"
+import { useSlidesStore, useScreenStore, useMainStore } from "@/store"
 import { KEYS } from "@/configs/hotkey"
 import { ANIMATION_CLASS_PREFIX } from "@/configs/animation"
 import message from "@/utils/message"
@@ -9,7 +9,9 @@ import { changePageSlideMes } from "@/messageHooks/pptScreen"
 
 export default () => {
   const slidesStore = useSlidesStore()
+  const mainStore = useMainStore()
   const { slides, slideIndex, formatedAnimations } = storeToRefs(slidesStore)
+  const { isPPTWheelPage } = storeToRefs(mainStore)
 
   // 当前页的元素动画执行到的位置
   const animationIndex = ref(0)
@@ -175,6 +177,8 @@ export default () => {
   // 鼠标滚动翻页
   const mousewheelListener = throttle(
     function (e: WheelEvent) {
+      // 控制能不能翻页
+      if (!isPPTWheelPage.value) return
       if (e.deltaY < 0) execPrev()
       else if (e.deltaY > 0) execNext()
     },

+ 10 - 3
src/views/components/element/enjoyElement/ScreenEnjoyElement.vue

@@ -10,23 +10,30 @@
   >
     <div class="rotate-wrapper" :style="{ transform: `rotate(${elementInfo.rotate}deg)` }">
       <div class="element-content">
-        <enjoyPlayer :elementInfo="elementInfo" :scale="scale" :isScreening="true" />
+        <enjoyPlayer v-if="inCurrentSlide" :elementInfo="elementInfo" :scale="scale" :isScreening="true" />
       </div>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
-import { inject, ref } from "vue"
+import { inject, ref, computed } from "vue"
+import { storeToRefs } from "pinia"
+import { useSlidesStore } from "@/store"
 import type { PPTEnjoyElement } from "@/types/slides"
 import enjoyPlayer from "./enjoyPlayer.vue"
-import { injectKeySlideScale } from "@/types/injectKey"
+import { injectKeySlideScale, injectKeySlideId } from "@/types/injectKey"
 
 defineProps<{
   elementInfo: PPTEnjoyElement
 }>()
 
+const { currentSlide } = storeToRefs(useSlidesStore())
+
 const scale = inject(injectKeySlideScale) || ref(1)
+const slideId = inject(injectKeySlideId) || ref("")
+
+const inCurrentSlide = computed(() => currentSlide.value.id === slideId.value)
 </script>
 
 <style lang="scss" scoped>

+ 160 - 141
src/views/components/element/enjoyElement/enjoyPlayer.vue

@@ -3,7 +3,7 @@
     <div v-if="!isBase" v-show="isShowEnjoyPlayerList" class="enjoyPlayerList">
       <div class="titNameCon">
         <div class="titName">
-          {{ `音频列表 (${elementInfo.enjoyList?.length || 0})` }}
+          <div class="tit">{{ `音频列表 (${elementInfo.enjoyList?.length || 0})` }}</div>
         </div>
       </div>
       <div class="enjoyPlayerListCon">
@@ -44,40 +44,43 @@
       @progress="handleProgress()"
       @error="handleError()"
     ></audio>
-    <img class="tipImg" src="./imgs/tip.png" alt="" />
-    <div class="operateBtn" :class="{ paused: paused }" @click="toggle"></div>
-    <div class="operateMidCon">
-      <div class="titleCon">
-        <div class="title">{{ elementInfo.title }}</div>
-        <div class="timesCon">
-          {{ `${ptime}/${dtime}` }}
+    <div class="playerCon">
+      <img class="tipImg" src="./imgs/tip.png" alt="" />
+      <div class="operateBtn" :class="{ paused: paused }" @click="toggle"></div>
+      <div class="operateMidCon">
+        <div class="titleCon">
+          <div class="title">{{ elementInfo.title }}</div>
+          <div class="timesCon">
+            {{ `${ptime}/${dtime}` }}
+          </div>
         </div>
-      </div>
-      <div class="bar-wrap" ref="playBarWrap" @mousedown="handleMousedownPlayBar()" @touchstart="handleMousedownPlayBar()">
-        <div class="bar">
-          <div class="loaded" :style="{ width: loadedBarWidth }"></div>
-          <div class="played" :style="{ width: playedBarWidth }">
-            <div class="thumb"></div>
+        <div class="bar-wrap" ref="playBarWrap" @mousedown="handleMousedownPlayBar()" @touchstart="handleMousedownPlayBar()">
+          <div class="bar">
+            <div class="loaded" :style="{ width: loadedBarWidth }"></div>
+            <div class="played" :style="{ width: playedBarWidth }">
+              <div class="thumb"></div>
+            </div>
           </div>
         </div>
       </div>
-    </div>
-    <div class="operateRightBtn">
-      <div class="preBtn" @click="handleChangeMusic('pre')"></div>
-      <div class="nextBtn" @click="handleChangeMusic('next')"></div>
-      <div class="listBtn" @click="isShowEnjoyPlayerList = !isShowEnjoyPlayerList"></div>
+      <div class="operateRightBtn">
+        <div class="preBtn" @click="handleChangeMusic('pre')"></div>
+        <div class="nextBtn" @click="handleChangeMusic('next')"></div>
+        <div class="listBtn" @click="hanleEnjoyList"></div>
+      </div>
     </div>
   </div>
 </template>
 
 <script setup lang="ts">
-import { computed, ref } from "vue"
+import { computed, ref, onUnmounted } from "vue"
 import message from "@/utils/message"
 import type { PPTEnjoyElement } from "@/types/slides"
-import { useSlidesStore } from "@/store"
+import { useSlidesStore, useMainStore } from "@/store"
 import draggable from "vuedraggable"
 
 const slidesStore = useSlidesStore()
+const mainStore = useMainStore()
 const props = withDefaults(
   defineProps<{
     scale?: number
@@ -94,6 +97,17 @@ const props = withDefaults(
 
 const isShowEnjoyPlayerList = ref(false)
 
+function hanleEnjoyList() {
+  if (props.isBase) {
+    return
+  }
+  isShowEnjoyPlayerList.value = !isShowEnjoyPlayerList.value
+  mainStore.setIsPPTWheelPageState(!isShowEnjoyPlayerList.value)
+}
+// 卸载之后让ppt能滚动
+onUnmounted(() => {
+  mainStore.setIsPPTWheelPageState(true)
+})
 function handleDragEnd() {
   slidesStore.updateElement({
     id: props.elementInfo.id,
@@ -318,135 +332,138 @@ const handleMousedownPlayBar = () => {
 <style lang="scss" scoped>
 .enjoyPlayer {
   transform-origin: left top;
-  background: linear-gradient(180deg, #ffffff 0%, #dfdfdf 100%);
-  box-shadow:
-    0px 3px 16px 0px rgba(0, 0, 0, 0.08),
-    inset 0px -6px 6px 0px rgba(0, 0, 0, 0.08);
-  border-radius: 112px;
-  outline: 2px solid rgba(0, 0, 0, 0.03);
-  padding: 16px 21px;
-  display: flex;
-  align-items: center;
-  width: 670px;
-  position: relative;
-  .tipImg {
-    position: absolute;
-    width: 44px;
-    height: 12px;
-    right: 47px;
-    top: 7px;
-  }
-  .operateBtn {
-    flex-shrink: 0;
-    background: url("./imgs/pause.png") no-repeat;
-    background-size: 100% 100%;
-    width: 70px;
-    height: 70px;
-    cursor: pointer;
-    &.paused {
-      background: url("./imgs/play.png") no-repeat;
-      background-size: 100% 100%;
+  .playerCon {
+    background: linear-gradient(180deg, #ffffff 0%, #dfdfdf 100%);
+    box-shadow:
+      0px 3px 16px 0px rgba(0, 0, 0, 0.08),
+      inset 0px -6px 6px 0px rgba(0, 0, 0, 0.08);
+    border-radius: 112px;
+    outline: 2px solid rgba(0, 0, 0, 0.03);
+    padding: 16px 21px;
+    width: 670px;
+    display: flex;
+    align-items: center;
+    position: relative;
+    z-index: 1;
+    .tipImg {
+      position: absolute;
+      width: 44px;
+      height: 12px;
+      right: 47px;
+      top: 7px;
     }
-  }
-  .operateMidCon {
-    margin: 0 21px;
-    flex-grow: 1;
-    .titleCon {
-      display: flex;
-      align-items: center;
-      justify-content: space-between;
-      .title {
-        width: 200px;
-        font-weight: 600;
-        font-size: 22px;
-        color: #131415;
-        line-height: 30px;
-        white-space: nowrap;
-        overflow: hidden;
-        text-overflow: ellipsis;
-      }
-      .timesCon {
-        flex-shrink: 0;
-        font-weight: 400;
-        font-size: 18px;
-        color: #999999;
-        line-height: 25px;
+    .operateBtn {
+      flex-shrink: 0;
+      background: url("./imgs/pause.png") no-repeat;
+      background-size: 100% 100%;
+      width: 70px;
+      height: 70px;
+      cursor: pointer;
+      &.paused {
+        background: url("./imgs/play.png") no-repeat;
+        background-size: 100% 100%;
       }
     }
-    .bar-wrap {
-      position: relative;
-      cursor: pointer;
-      width: 100%;
-      margin-top: 12px;
-      .bar {
+    .operateMidCon {
+      margin: 0 21px;
+      flex-grow: 1;
+      .titleCon {
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        .title {
+          width: 200px;
+          font-weight: 600;
+          font-size: 22px;
+          color: #131415;
+          line-height: 30px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+        .timesCon {
+          flex-shrink: 0;
+          font-weight: 400;
+          font-size: 18px;
+          color: #999999;
+          line-height: 25px;
+        }
+      }
+      .bar-wrap {
         position: relative;
-        height: 10px;
+        cursor: pointer;
         width: 100%;
-        background: #dcdcdc;
-        box-shadow: inset 0px 2px 3px 0px #a9a9a9;
-        border-radius: 5px;
-        outline: 2px solid rgba(255, 255, 255, 0.5);
-        .loaded {
-          position: absolute;
-          left: 0;
-          top: 0;
-          bottom: 0;
-          background: rgba(255, 255, 255, 0.4);
+        margin-top: 12px;
+        .bar {
+          position: relative;
           height: 10px;
-          transition: all 0.5s ease;
-          will-change: width;
-          border-radius: 6px;
-        }
-        .played {
-          position: absolute;
-          left: 0;
-          top: 0;
-          bottom: 0;
-          height: 10px;
-          will-change: width;
-          background: linear-gradient(270deg, #97d1fd 0%, #0d93ff 100%);
-          border-radius: 6px;
-
-          .thumb {
+          width: 100%;
+          background: #dcdcdc;
+          box-shadow: inset 0px 2px 3px 0px #a9a9a9;
+          border-radius: 5px;
+          outline: 2px solid rgba(255, 255, 255, 0.5);
+          .loaded {
             position: absolute;
-            top: -12px;
-            right: -26px;
-            cursor: pointer;
-            width: 52px;
-            height: 38px;
-            background: url("./imgs/td.png") no-repeat;
-            background-size: 100% 100%;
+            left: 0;
+            top: 0;
+            bottom: 0;
+            background: rgba(255, 255, 255, 0.4);
+            height: 10px;
+            transition: all 0.5s ease;
+            will-change: width;
+            border-radius: 6px;
+          }
+          .played {
+            position: absolute;
+            left: 0;
+            top: 0;
+            bottom: 0;
+            height: 10px;
+            will-change: width;
+            background: linear-gradient(270deg, #97d1fd 0%, #0d93ff 100%);
+            border-radius: 6px;
+
+            .thumb {
+              position: absolute;
+              top: -12px;
+              right: -26px;
+              cursor: pointer;
+              width: 52px;
+              height: 38px;
+              background: url("./imgs/td.png") no-repeat;
+              background-size: 100% 100%;
+            }
           }
         }
       }
     }
-  }
-  .operateRightBtn {
-    flex-shrink: 0;
-    display: flex;
-    align-items: center;
-    .preBtn {
-      background: url("./imgs/pre.png") no-repeat;
-      background-size: 100% 100%;
-      width: 56px;
-      height: 56px;
-      margin-right: 14px;
-      cursor: pointer;
-    }
-    .nextBtn {
-      background: url("./imgs/next.png") no-repeat;
-      background-size: 100% 100%;
-      width: 56px;
-      height: 56px;
-      margin-right: 14px;
-      cursor: pointer;
-    }
-    .listBtn {
-      background: url("./imgs/list.png") no-repeat;
-      background-size: 100% 100%;
-      width: 56px;
-      height: 56px;
-      cursor: pointer;
+    .operateRightBtn {
+      flex-shrink: 0;
+      display: flex;
+      align-items: center;
+      .preBtn {
+        background: url("./imgs/pre.png") no-repeat;
+        background-size: 100% 100%;
+        width: 56px;
+        height: 56px;
+        margin-right: 14px;
+        cursor: pointer;
+      }
+      .nextBtn {
+        background: url("./imgs/next.png") no-repeat;
+        background-size: 100% 100%;
+        width: 56px;
+        height: 56px;
+        margin-right: 14px;
+        cursor: pointer;
+      }
+      .listBtn {
+        background: url("./imgs/list.png") no-repeat;
+        background-size: 100% 100%;
+        width: 56px;
+        height: 56px;
+        cursor: pointer;
+      }
     }
   }
   .enjoyPlayerList {
@@ -458,7 +475,6 @@ const handleMousedownPlayBar = () => {
     box-shadow: 0px 3px 22px 0px rgba(0, 0, 0, 0.12);
     border-radius: 20px 20px 0px 0px;
     background-color: rgba(255, 255, 255, 0.9);
-    z-index: -1;
     padding: 20px 0 61px 10px;
     .titNameCon {
       padding-left: 10px;
@@ -473,7 +489,6 @@ const handleMousedownPlayBar = () => {
         position: relative;
         &::after {
           position: absolute;
-          z-index: -1;
           left: 0;
           bottom: 0;
           content: "";
@@ -481,6 +496,10 @@ const handleMousedownPlayBar = () => {
           height: 12px;
           background: linear-gradient(90deg, #77bbff 0%, rgba(163, 231, 255, 0.22) 100%);
         }
+        .tit {
+          position: relative;
+          z-index: 1;
+        }
       }
     }
     .enjoyPlayerListCon {