浏览代码

audio volume

bianjiang 1 年之前
父节点
当前提交
1ea6536e78
共有 1 个文件被更改,包括 105 次插入7 次删除
  1. 105 7
      src/modules/editor/components/CompUI/basicUI/Page/PageMusic.tsx

+ 105 - 7
src/modules/editor/components/CompUI/basicUI/Page/PageMusic.tsx

@@ -1,9 +1,14 @@
 import { IconMusic } from "@/assets/icons";
 import { isWeixinBrowser } from "@/controllers/wxController";
 import { useEditor } from "@/modules/editor";
-import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons-vue";
+import {
+  PauseCircleOutlined,
+  PlayCircleOutlined,
+  SoundOutlined,
+} from "@ant-design/icons-vue";
 import { css } from "@linaria/core";
-import { Button, Slider } from "ant-design-vue";
+
+import { Button, Dropdown, Slider } from "ant-design-vue";
 import { Howl } from "howler";
 import { nanoid } from "nanoid";
 import {
@@ -18,14 +23,18 @@ import { bool, number } from "vue-types";
 declare const WeixinJSBridge: any;
 export const PageMusic = defineComponent({
   setup() {
-    const { store, helper, controls } = useEditor();
+    const { store, helper, controls, actions } = useEditor();
+    const rootComp = helper.findRootComp();
+    const volume =
+      rootComp?.value.volume != undefined ? rootComp?.value.volume : 0.3;
     const state = reactive({
       playStatus: false,
       duration: 0,
       currentTime: 0,
       muted: true,
+      volume: volume,
     });
-    const rootComp = helper.findRootComp();
+
     let audioKey = nanoid();
     let audioBgm = ref();
     const initAudioBgm = () => {
@@ -35,7 +44,7 @@ export const PageMusic = defineComponent({
         loop: store.isEditMode ? false : true,
         preload: true,
         HTML5: true,
-        volume: 0.3,
+        volume: volume,
       });
       controls.mediaCtrl.setMediasInstance(audioKey, audioBgm.value);
       audioBgm.value.on("load", () => {
@@ -112,7 +121,6 @@ export const PageMusic = defineComponent({
         audioRest();
       }
       let playing = audioBgm.value.playing();
-      console.log(playing);
       if (status && playing) {
         state.playStatus = true;
         return;
@@ -138,6 +146,13 @@ export const PageMusic = defineComponent({
       state.currentTime = v;
       audioBgm.value && audioBgm.value.seek(v);
     };
+    const volumeChange = (v: number) => {
+      state.volume = v;
+      if (rootComp) {
+        actions.updateCompData(rootComp, "value.volume", v);
+      }
+      audioBgm.value && audioBgm.value.volume(v);
+    };
     const audioRest = () => {
       if (!audioBgm.value) {
         return;
@@ -158,8 +173,10 @@ export const PageMusic = defineComponent({
             <AudioPlayer
               key={music}
               playStatus={state.playStatus}
+              volume={state.volume}
               onStatus={playAudio}
               onSeekChange={seekChange}
+              onVolumeChange={volumeChange}
               duration={state.duration}
               currentTime={state.currentTime}
             />
@@ -181,11 +198,12 @@ export const PageMusic = defineComponent({
 
 const AudioPlayer = defineComponent({
   props: {
+    volume: number(),
     playStatus: bool(),
     currentTime: number(),
     duration: number(),
   },
-  emits: ["status", "seekChange"],
+  emits: ["status", "seekChange", "volumeChange"],
   setup(props, { emit }) {
     const audioControl = (playStatus: boolean) => {
       emit("status", playStatus);
@@ -193,6 +211,9 @@ const AudioPlayer = defineComponent({
     const seekChange = (v: any) => {
       emit("seekChange", v);
     };
+    const volumeChange = (v: any) => {
+      emit("volumeChange", v);
+    };
     const formatTime = (secs?: number) => {
       if (!secs) {
         return "00:00";
@@ -208,6 +229,23 @@ const AudioPlayer = defineComponent({
         String(seconds).padStart(2, "0")
       );
     };
+    const volumeSlider = () => {
+      return (
+        <div class={[VolumeSliderStyle]}>
+          <div class={"h-100px pb-8px"}>
+            <Slider
+              tooltipVisible={false}
+              min={0}
+              max={1}
+              step={0.1}
+              vertical={true}
+              value={props.volume}
+              onChange={volumeChange}
+            ></Slider>
+          </div>
+        </div>
+      );
+    };
     return () => {
       return (
         <div class={AudioPlayerStyle}>
@@ -237,11 +275,71 @@ const AudioPlayer = defineComponent({
           <div>
             {formatTime(props.currentTime)}/{formatTime(props.duration)}
           </div>
+          <div>
+            <Dropdown
+              disabled={!props.playStatus}
+              overlay={volumeSlider()}
+              trigger="click"
+              placement="top"
+            >
+              <Button
+                type="link"
+                icon={<SoundOutlined style={{ fontSize: "18px" }} />}
+              ></Button>
+            </Dropdown>
+          </div>
         </div>
       );
     };
   },
 });
+const VolumeSliderStyle = css`
+  margin-bottom: -4px;
+  padding: 8px 4px;
+  background-color: #303030;
+  border-radius: 4px;
+  box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2);
+  /* slider style */
+  .ant-slider-disabled {
+    opacity: 0.7;
+  }
+  .ant-slider-step {
+    background-color: rgba(255, 255, 255, 0.27);
+  }
+  .ant-slider-track {
+    border-radius: 4px;
+    background-color: rgba(255, 255, 255, 1);
+  }
+
+  .ant-slider:not(.ant-slider-disabled):hover {
+    .ant-slider-handle {
+      background-color: @inf-primary-color;
+      &:not(.ant-tooltip-open) {
+        border-color: #fff;
+      }
+    }
+  }
+  .ant-slider {
+    &.ant-slider-disabled {
+      .ant-slider-handle {
+        background-color: #bbb;
+        opacity: 0.8;
+      }
+    }
+  }
+  .ant-slider-handle {
+    width: 14px;
+    height: 8px;
+    border-radius: 2px;
+    border-color: #fff;
+    background-color: #fff;
+  }
+
+  .ant-slider-handle-click-focused {
+    border-color: #fff;
+    background-color: @inf-primary-color;
+  }
+`;
 const MusicEditStyle = css`
   flex: 1;
 `;