音量大小控制

This commit is contained in:
zilong 2021-11-07 17:54:53 +08:00
parent 70cb1b3e06
commit 310cf5efad
7 changed files with 235 additions and 28 deletions

View File

@ -95,6 +95,9 @@ const token = pubsub.subscribe("zp", (msg, data) => {
case "zp.showSearch":
showSearch.value = true;
break;
case "zp.hideSearch":
showSearch.value = false;
break;
case "zp.toggleSearch":
showSearch.value = !showSearch.value;
break;

View File

@ -10,7 +10,7 @@ export default function useHotkey(){
"enter,ctrl+enter,⌘+enter",
].join(","),
throttle((e, h) => {
switch (h.key) {
switch (h.key) {
// space,ctrl+p,⌘+p
case "space":
case "ctrl+p":
@ -26,6 +26,15 @@ export default function useHotkey(){
case "⌘+right":
pubsub.publish("zp.next");
break;
// ctrl+up,⌘+up,ctrl+down,⌘+down
case "ctrl+up":
case "⌘+up":
pubsub.publish("zp.setVolume",{step: 5});
break;
case "ctrl+down":
case "⌘+down":
pubsub.publish("zp.setVolume",{step: -5});
break;
// enter,ctrl+enter,⌘+enter
case "enter":
case "ctrl+enter":
@ -36,4 +45,23 @@ export default function useHotkey(){
e.preventDefault();
}, 500)
);
hotkeys(
[
"ctrl+up,⌘+up,ctrl+down,⌘+down",
].join(","),
throttle((e, h) => {
switch (h.key) {
// ctrl+up,⌘+up,ctrl+down,⌘+down
case "ctrl+up":
case "⌘+up":
pubsub.publish("zp.setVolume",{step: 5});
break;
case "ctrl+down":
case "⌘+down":
pubsub.publish("zp.setVolume",{step: -5});
break;
}
e.preventDefault();
}, 50)
);
};

View File

@ -14,6 +14,8 @@ export default createStore({
songId: 0, //歌曲id
playing: false, //是否播放
playMode: 0, //播放模式0-3顺序循环单曲随机。
volume: 100, //音量最大100
muted: false, //静音
lastPlayed: [], //最近播放
playingList: [], //当前播放
searchHistory: [], //搜索历史

View File

@ -44,7 +44,8 @@ const result = ref({});
}
"
v-model:value="keywords"
@keyup.enter="search"
@keydown.enter="search"
@keyup.esc="pubsub.publish('zp.hideSearch');"
@input="handleInput"
style="width: 190px"
>

View File

@ -178,6 +178,9 @@ watch(playing, (val, old) => {
// console.log(audioEl.value.duration);
if (audioEl.value) {
currentTime = audioEl.value.currentTime;
audioEl.value.volume = store.state.settings.muted
? 0
: store.state.settings.volume / 100;
pubsub.publish("zp.progress", {
progress: audioEl.value.currentTime,
total: audioEl.value.duration,

View File

@ -1,25 +1,29 @@
<script setup>
import { ref, watch, toRaw } from "vue";
import {useStore} from 'vuex';
import { NButton, NIcon, NSpace } from "naive-ui";
import { ref, watch, toRaw, h } from "vue";
import { useStore } from "vuex";
import { NButton, NIcon, NSpace, NDropdown } from "naive-ui";
import PlaylistMusic from "@/assets/svgs/PlaylistMusic.svg";
import VolumeOffOutline from "@/assets/svgs/VolumeOffOutline.svg";
import VolumeMediumOutline from "@/assets/svgs/VolumeMediumOutline.svg";
import RepeatOutline from "@/assets/svgs/RepeatOutline.svg";
import RepeatOne from "@/assets/svgs/RepeatOne.svg";
import Playlist from "@/assets/svgs/Playlist.svg";
import Random from "@/assets/svgs/Random.svg";
import pubsub from 'pubsub-js';
import pubsub from "pubsub-js";
import Vol from "@/views/common/Vol.vue";
const store = useStore()
const store = useStore();
//0-3
let playMode = ref(0)
const playMode = ref(0);
const vol = ref(store.state.settings.volume);
const muted = ref(store.state.settings.muted);
const chPlayMode = (mode) => {
store.commit('saveSettings', {
playMode: mode
})
}
store.commit("saveSettings", {
playMode: mode,
});
};
watch(
() => store.state.settings.playMode,
@ -32,6 +36,43 @@ watch(
}
);
const options = [
{
key: "k",
type: "render",
render: () => h(Vol, {}),
},
];
const setVol = (step) => {
vol.value += step;
if (vol.value > 100) vol.value = 100;
if (vol.value < 0) vol.value = 0;
muted.value = vol.value <= 0
};
watch(
() => [vol.value, muted.value],
([v, m], [oldV, oldM]) => {
if(v>=0 && v<=100){
store.commit('saveSettings',{
volume: v,
muted: m,
})
}
}
);
const token = pubsub.subscribe("zp", (msg, data) => {
switch (msg) {
case "zp.setVolume":
setVol(data.step);
break;
// case "zp.setMuted":
// muted.value = !muted.value
// break;
}
});
</script>
<template>
@ -43,61 +84,72 @@ watch(
:size="[6]"
style="padding-top: 2px; padding-right: 8px"
>
<n-button circle v-if="playMode==1" @click="chPlayMode(2)">
<n-button circle v-if="playMode == 1" @click="chPlayMode(2)">
<template #icon>
<n-icon>
<RepeatOutline />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==2" @click="chPlayMode(3)">
<n-button circle v-if="playMode == 2" @click="chPlayMode(3)">
<template #icon>
<n-icon>
<RepeatOne />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==0" @click="chPlayMode(1)">
<n-button circle v-if="playMode == 0" @click="chPlayMode(1)">
<template #icon>
<n-icon>
<Playlist />
</n-icon>
</template>
</n-button>
<n-button circle v-if="playMode==3" @click="chPlayMode(0)">
<n-button circle v-if="playMode == 3" @click="chPlayMode(0)">
<template #icon>
<n-icon>
<Random />
</n-icon>
</template>
</n-button>
<n-button circle @click="pubsub.publish('zp.togglePlaying',)">
<n-button circle @click="pubsub.publish('zp.togglePlaying')">
<template #icon>
<n-icon>
<PlaylistMusic />
</n-icon>
</template>
</n-button>
<n-button circle>
<template #icon>
<n-icon>
<VolumeOffOutline />
</n-icon>
</template>
</n-button>
<NDropdown :options="options" trigger="hover" :show-arrow="true">
<n-button
circle
v-if="store.state.settings.muted"
@click="pubsub.publish('zp.setMuted')"
>
<template #icon>
<n-icon>
<VolumeOffOutline />
</n-icon>
</template>
</n-button>
<n-button circle v-else @click="pubsub.publish('zp.setMuted')">
<template #icon>
<n-icon>
<VolumeMediumOutline />
</n-icon>
</template>
</n-button>
</NDropdown>
</n-space>
<!-- </div> -->
</template>
<script>
export default {
}
export default {};
</script>
<style lang="less" scoped>
#songStatus {
flex: 2;
}
</style>
</style>

118
src/views/common/Vol.vue Normal file
View File

@ -0,0 +1,118 @@
<script setup>
import { NSlider } from "naive-ui";
import { ref, watch, onUnmounted } from "vue";
import { useStore } from "vuex";
import pubsub from 'pubsub-js'
const store = useStore();
const vol = ref(store.state.settings.volume);
const muted = ref(store.state.settings.muted);
const { primaryColor } = store.state.theme.themeOverrides.common;
const stySlider = () => {
return {
backgroundColor: primaryColor,
height: (muted.value ? 0: vol.value) + "px",
};
};
const styDot = () => {
return {
backgroundColor: primaryColor,
bottom: (muted.value ? 0: vol.value) - 6 + "px",
};
};
const setSlider = (e) => {
vol.value = 100 - e.offsetY;
muted.value = vol.value <= 0
};
watch(
() => [vol.value, muted.value],
([v, m], [oldV, oldM]) => {
// m = v <= 0
if(v>=0 && v<=100){
store.commit('saveSettings',{
volume: v,
muted: m,
})
}
}
);
const setVol = (step) => {
vol.value += step;
if (vol.value > 100) vol.value = 100;
if (vol.value < 0) vol.value = 0;
muted.value = vol.value <= 0
};
const token = pubsub.subscribe("zp", (msg, data) => {
switch (msg) {
case "zp.setVolume":
setVol(data.step);
break;
case "zp.setMuted":
muted.value = !muted.value
break;
}
});
//
onUnmounted(() => {
pubsub.unsubscribe(token);
});
</script>
<template>
<div class="wp z-slider">
<div class="bg">
<div class="content" :style="stySlider()"></div>
<div class="dot" :style="styDot()"></div>
<div class="mask" @click="setSlider"></div>
</div>
</div>
</template>
<script>
export default {};
</script>
<style lang="less" scoped>
.z-slider.wp {
position: relative;
padding: 6px;
padding-top: 10px;
width: 30px;
// height: 100px;
// border: 1px #eee solid;
.bg {
height: 100px;
position: relative;
.content {
position: absolute;
border-radius: 2px;
bottom: 0px;
left: 7px;
width: 4px;
height: 70px;
}
.dot {
position: absolute;
width: 10px;
height: 10px;
border-radius: 20px;
bottom: 67px;
left: 4px;
}
.mask {
position: absolute;
// width: 30px;
// height: 100px;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
}
}
</style>