|
@@ -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 {
|
|
@@ -15,26 +20,37 @@ import {
|
|
|
onMounted,
|
|
|
} from "vue";
|
|
|
import { bool, number } from "vue-types";
|
|
|
+import { MusicOptions } from "./localMusic";
|
|
|
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 = () => {
|
|
|
audioBgm.value = null;
|
|
|
+ const curAudio = MusicOptions.find((e) => {
|
|
|
+ return e.value == rootComp?.value.music;
|
|
|
+ });
|
|
|
+ const src = curAudio?.src || "";
|
|
|
audioBgm.value = new Howl({
|
|
|
- src: [rootComp?.value.music],
|
|
|
+ src: [src],
|
|
|
loop: store.isEditMode ? false : true,
|
|
|
preload: true,
|
|
|
HTML5: true,
|
|
|
+ volume: volume,
|
|
|
});
|
|
|
controls.mediaCtrl.setMediasInstance(audioKey, audioBgm.value);
|
|
|
audioBgm.value.on("load", () => {
|
|
@@ -111,7 +127,6 @@ export const PageMusic = defineComponent({
|
|
|
audioRest();
|
|
|
}
|
|
|
let playing = audioBgm.value.playing();
|
|
|
- console.log(playing);
|
|
|
if (status && playing) {
|
|
|
state.playStatus = true;
|
|
|
return;
|
|
@@ -137,6 +152,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;
|
|
@@ -157,8 +179,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}
|
|
|
/>
|
|
@@ -180,11 +204,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);
|
|
@@ -192,6 +217,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";
|
|
@@ -207,6 +235,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}>
|
|
@@ -236,11 +281,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;
|
|
|
`;
|