Browse Source

音频播放器逻辑

黄琪勇 1 month ago
parent
commit
9d4b6ef3c2

+ 7 - 0
src/views/Editor/Toolbar/ElementStylePanel/EnjoyStylePanel.vue

@@ -0,0 +1,7 @@
+<template>
+  <div class="EnjoyStylePanel">音频播放器</div>
+</template>
+
+<script setup lang="ts"></script>
+
+<style lang="scss" scoped></style>

+ 3 - 1
src/views/Editor/Toolbar/ElementStylePanel/index.vue

@@ -21,6 +21,7 @@ import VideoStylePanel from "./VideoStylePanel.vue"
 import AudioStylePanel from "./AudioStylePanel.vue"
 import MultiStylePanel from "./MultiStylePanel.vue"
 import CloudCoachStylePanel from "./CloudCoachStylePanel.vue"
+import EnjoyStylePanel from "./EnjoyStylePanel.vue"
 
 const panelMap = {
   [ElementTypes.TEXT]: TextStylePanel,
@@ -35,7 +36,8 @@ const panelMap = {
 const elementSubtypeMap = {
   [ElementSubtypeTypes.AUDIO]: AudioStylePanel,
   [ElementSubtypeTypes.VIDEO]: VideoStylePanel,
-  [ElementSubtypeTypes.SING_PLAY]: CloudCoachStylePanel
+  [ElementSubtypeTypes.SING_PLAY]: CloudCoachStylePanel,
+  [ElementSubtypeTypes.ENJOY]: EnjoyStylePanel
 }
 const { activeElementIdList, activeElementList, handleElement, activeGroupElementId } = storeToRefs(useMainStore())
 

+ 1 - 1
src/views/Editor/Toolbar/index.vue

@@ -39,7 +39,7 @@ const elementTabs = computed<ElementTabs[]>(() => {
       { label: "动画", key: ToolbarStates.EL_ANIMATION }
     ]
   }
-  if (handleElement.value?.type === "elf" && handleElement.value?.subtype === "elf-sing-play") {
+  if (handleElement.value?.type === "elf" && ["elf-sing-play", "elf-enjoy"].includes(handleElement.value?.subtype)) {
     return [
       { label: "位置", key: ToolbarStates.EL_POSITION },
       { label: "动画", key: ToolbarStates.EL_ANIMATION }

+ 3 - 1
src/views/Mobile/MobileEditor/MobileEditableElement.vue

@@ -23,6 +23,7 @@ import LatexElement from "@/views/components/element/LatexElement/index.vue"
 import VideoElement from "@/views/components/element/VideoElement/index.vue"
 import AudioElement from "@/views/components/element/AudioElement/index.vue"
 import cloudCoachElement from "@/views/components/element/cloudCoachElement"
+import enjoyElement from "@/views/components/element/enjoyElement"
 
 const props = defineProps<{
   elementInfo: PPTElement
@@ -44,7 +45,8 @@ const currentElementComponent = computed<unknown>(() => {
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: AudioElement,
     [ElementSubtypeTypes.VIDEO]: VideoElement,
-    [ElementSubtypeTypes.SING_PLAY]: cloudCoachElement
+    [ElementSubtypeTypes.SING_PLAY]: cloudCoachElement,
+    [ElementSubtypeTypes.ENJOY]: enjoyElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 3 - 1
src/views/Screen/ScreenElement.vue

@@ -33,6 +33,7 @@ import BaseLatexElement from "@/views/components/element/LatexElement/BaseLatexE
 import ScreenVideoElement from "@/views/components/element/VideoElement/ScreenVideoElement.vue"
 import ScreenAudioElement from "@/views/components/element/AudioElement/ScreenAudioElement.vue"
 import ScreenCloudCoachElement from "@/views/components/element/cloudCoachElement/ScreenCloudCoachElement.vue"
+import ScreenEnjoyElement from "@/views/components/element/enjoyElement/ScreenEnjoyElement.vue"
 
 const props = defineProps<{
   elementInfo: PPTElement
@@ -56,7 +57,8 @@ const currentElementComponent = computed<unknown>(() => {
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: ScreenAudioElement,
     [ElementSubtypeTypes.VIDEO]: ScreenVideoElement,
-    [ElementSubtypeTypes.SING_PLAY]: ScreenCloudCoachElement
+    [ElementSubtypeTypes.SING_PLAY]: ScreenCloudCoachElement,
+    [ElementSubtypeTypes.ENJOY]: ScreenEnjoyElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 3 - 1
src/views/components/ThumbnailSlide/ThumbnailElement.vue

@@ -24,6 +24,7 @@ import BaseLatexElement from "@/views/components/element/LatexElement/BaseLatexE
 import BaseVideoElement from "@/views/components/element/VideoElement/BaseVideoElement.vue"
 import BaseAudioElement from "@/views/components/element/AudioElement/BaseAudioElement.vue"
 import BaseCloudCoachElement from "@/views/components/element/cloudCoachElement/BaseCloudCoachElement.vue"
+import BaseEnjoyElement from "@/views/components/element/enjoyElement/BaseEnjoyElement.vue"
 
 const props = defineProps<{
   elementInfo: PPTElement
@@ -44,7 +45,8 @@ const currentElementComponent = computed<unknown>(() => {
   const elementSubtypeMap = {
     [ElementSubtypeTypes.AUDIO]: BaseAudioElement,
     [ElementSubtypeTypes.VIDEO]: BaseVideoElement,
-    [ElementSubtypeTypes.SING_PLAY]: BaseCloudCoachElement
+    [ElementSubtypeTypes.SING_PLAY]: BaseCloudCoachElement,
+    [ElementSubtypeTypes.ENJOY]: BaseEnjoyElement
   }
   return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
 })

+ 41 - 0
src/views/components/element/enjoyElement/BaseEnjoyElement.vue

@@ -0,0 +1,41 @@
+<template>
+  <div
+    class="base-element-enjoy"
+    :style="{
+      top: elementInfo.top + 'px',
+      left: elementInfo.left + 'px',
+      width: elementInfo.width + 'px',
+      height: elementInfo.height + 'px'
+    }"
+  >
+    <div class="rotate-wrapper" :style="{ transform: `rotate(${elementInfo.rotate}deg)` }">
+      <div class="element-content">
+        <enjoyPlayer :elementInfo="elementInfo" :isBase="true" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import type { PPTEnjoyElement } from "@/types/slides"
+import enjoyPlayer from "./enjoyPlayer.vue"
+
+defineProps<{
+  elementInfo: PPTEnjoyElement
+}>()
+</script>
+
+<style lang="scss" scoped>
+.base-element-enjoy {
+  position: absolute;
+}
+.rotate-wrapper {
+  width: 100%;
+  height: 100%;
+}
+.element-content {
+  width: 100%;
+  height: 100%;
+  position: relative;
+}
+</style>

+ 44 - 0
src/views/components/element/enjoyElement/ScreenEnjoyElement.vue

@@ -0,0 +1,44 @@
+<template>
+  <div
+    class="base-element-enjoy screen-element-enjoy"
+    :style="{
+      top: elementInfo.top + 'px',
+      left: elementInfo.left + 'px',
+      width: elementInfo.width + 'px',
+      height: elementInfo.height + 'px'
+    }"
+  >
+    <div class="rotate-wrapper" :style="{ transform: `rotate(${elementInfo.rotate}deg)` }">
+      <div class="element-content">
+        <enjoyPlayer :elementInfo="elementInfo" :scale="scale" :isScreening="true" />
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { inject, ref } from "vue"
+import type { PPTEnjoyElement } from "@/types/slides"
+import enjoyPlayer from "./enjoyPlayer.vue"
+import { injectKeySlideScale } from "@/types/injectKey"
+
+defineProps<{
+  elementInfo: PPTEnjoyElement
+}>()
+
+const scale = inject(injectKeySlideScale) || ref(1)
+</script>
+
+<style lang="scss" scoped>
+.screen-element-enjoy {
+  position: absolute;
+}
+.rotate-wrapper {
+  width: 100%;
+  height: 100%;
+}
+.element-content {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 16 - 4
src/views/components/element/enjoyElement/enjoyPlayer.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="enjoyPlayer">
-    <div v-show="isShowEnjoyPlayerList" class="enjoyPlayerList">
+    <div v-if="!isBase" v-show="isShowEnjoyPlayerList" class="enjoyPlayerList">
       <div class="titNameCon">
         <div class="titName">
           {{ `音频列表 (${elementInfo.enjoyList?.length || 0})` }}
@@ -22,8 +22,10 @@
                 {{ element.title }}
               </div>
               <div class="itemRight">
-                <div class="itemListBtn drag-handle_enjoyPlayer" @click.stop></div>
-                <div class="itemCloseBtn" @click.stop="handleEnjoyDel(element.id)"></div>
+                <template v-if="!isScreening">
+                  <div class="itemListBtn drag-handle_enjoyPlayer" @click.stop></div>
+                  <div class="itemCloseBtn" @click.stop="handleEnjoyDel(element.id)"></div>
+                </template>
               </div>
             </div>
           </template>
@@ -31,6 +33,7 @@
       </div>
     </div>
     <audio
+      v-if="!isBase"
       ref="audioRef"
       :src="elementInfo.src"
       @durationchange="handleDurationchange()"
@@ -79,9 +82,13 @@ const props = withDefaults(
   defineProps<{
     scale?: number
     elementInfo: PPTEnjoyElement
+    isScreening?: boolean
+    isBase?: boolean
   }>(),
   {
-    scale: 1
+    scale: 1,
+    isScreening: false,
+    isBase: false
   }
 )
 
@@ -499,8 +506,13 @@ const handleMousedownPlayBar = () => {
           font-size: 20px;
           color: #131415;
           line-height: 28px;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
         }
         .itemRight {
+          margin-left: 10px;
+          flex-shrink: 0;
           display: flex;
           .itemListBtn {
             width: 34px;