diff --git a/components.d.ts b/components.d.ts
index cee876bf..a20eff95 100644
--- a/components.d.ts
+++ b/components.d.ts
@@ -79,7 +79,9 @@ declare module 'vue' {
NText: typeof import('naive-ui')['NText']
NThing: typeof import('naive-ui')['NThing']
Pagination: typeof import('./src/components/Global/Pagination.vue')['default']
+ PlayCover: typeof import('./src/components/Player/PlayCover.vue')['default']
PlayerControl: typeof import('./src/components/Player/PlayerControl.vue')['default']
+ PlayerCover: typeof import('./src/components/Player/PlayerCover.vue')['default']
Playlist: typeof import('./src/components/Global/Playlist.vue')['default']
PlaylistUpdate: typeof import('./src/components/Modal/PlaylistUpdate.vue')['default']
PrivateFm: typeof import('./src/components/Player/PrivateFm.vue')['default']
diff --git a/package.json b/package.json
index 7ece3d0d..d60999f2 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "splayer",
- "version": "2.0.0-beta.3",
+ "version": "2.0.0-beta.4",
"description": "A minimalist music player",
"main": "./out/main/index.js",
"author": "imsyy",
diff --git a/public/images/pic/pointer.png b/public/images/pic/pointer.png
new file mode 100644
index 00000000..8bec5cbe
Binary files /dev/null and b/public/images/pic/pointer.png differ
diff --git a/src/components/Global/Menu.vue b/src/components/Global/Menu.vue
index b911775f..4a452d25 100644
--- a/src/components/Global/Menu.vue
+++ b/src/components/Global/Menu.vue
@@ -6,7 +6,7 @@
class="main-menu"
:root-indent="36"
:indent="0"
- :collapsed="status.asideMenuCollapsed"
+ :collapsed="asideMenuCollapsed.value"
:defaultExpandedKeys="['user-playlists', 'favorite-playlists']"
:collapsed-width="64"
:collapsed-icon-size="22"
@@ -36,6 +36,7 @@ const router = useRouter();
const data = siteData();
const music = musicData();
const status = siteStatus();
+const { asideMenuCollapsed } = storeToRefs(status);
const { userData, userLikeData } = storeToRefs(data);
const { playList, playListOld, playIndex, playSongData, playHeartbeatMode, playMode } =
storeToRefs(music);
@@ -90,7 +91,7 @@ const menuOptions = computed(() => [
label: "在线音乐",
key: "online",
children: [],
- show: !status.asideMenuCollapsed,
+ show: !asideMenuCollapsed.value,
},
{
label: () =>
@@ -143,7 +144,7 @@ const menuOptions = computed(() => [
label: "我的音乐",
key: "user",
children: [],
- show: !status.asideMenuCollapsed,
+ show: !asideMenuCollapsed.value,
},
{
label: () =>
@@ -157,19 +158,33 @@ const menuOptions = computed(() => [
menuid: "like-songs",
},
() => [
- h(NText, null, () => ["喜欢的音乐"]),
- h(NButton, {
- size: "small",
- type: "tertiary",
- round: true,
- strong: true,
- secondary: true,
- renderIcon: renderIcon("heartbit", "26"),
- onclick: (event) => {
- event.stopPropagation();
- startHeartRate();
+ h(
+ "div",
+ {
+ style: {
+ width: "100%",
+ display: "flex",
+ alignItems: "center",
+ justifyContent: "space-between",
+ },
},
- }),
+ [
+ h("span", null, ["喜欢的音乐"]),
+ h(NButton, {
+ size: "small",
+ type: "tertiary",
+ round: true,
+ strong: true,
+ secondary: true,
+ class: asideMenuCollapsed.value ? "heart-rate-btn collapsed" : "heart-rate-btn",
+ renderIcon: renderIcon("heartbit", "26"),
+ onclick: (event) => {
+ event.stopPropagation();
+ startHeartRate();
+ },
+ }),
+ ],
+ ),
],
),
key: "like-songs",
@@ -222,8 +237,8 @@ const menuOptions = computed(() => [
key: "divider-2",
type: "divider",
},
- { ...userPlaylists.value, show: !status.asideMenuCollapsed },
- { ...favoritePlaylists.value, show: !status.asideMenuCollapsed },
+ { ...userPlaylists.value, show: !asideMenuCollapsed.value },
+ { ...favoritePlaylists.value, show: !asideMenuCollapsed.value },
]);
// 更改用户的歌单
@@ -446,3 +461,22 @@ onMounted(() => {
}
}
+
+
+
diff --git a/src/components/List/CommentList.vue b/src/components/List/CommentList.vue
index aee23006..7290b01f 100644
--- a/src/components/List/CommentList.vue
+++ b/src/components/List/CommentList.vue
@@ -293,7 +293,7 @@ const toLikeComment = throttle(
width: 100%;
padding: 4px 8px;
border-radius: 8px;
- background-color: var(--n-border-color);
+ background-color: var(--main-second-color);
font-size: 13px;
margin-top: 6px;
box-sizing: border-box;
diff --git a/src/components/Player/FullPlayer.vue b/src/components/Player/FullPlayer.vue
index c3b8d099..4e8abd24 100644
--- a/src/components/Player/FullPlayer.vue
+++ b/src/components/Player/FullPlayer.vue
@@ -68,61 +68,105 @@
+
+
-
-
{
- e.target.style.opacity = 1;
- }
- "
- >
-
-
-
+
+
+
+
{{ music.getPlaySongData.name || "未知曲目" }}
+
+
+
+ 其他音源
+
+
+
+ 该歌曲暂时无法播放,为您采用其他音源,可能会与原曲存在差别
+
+
+
+
+ {{ music.getPlaySongData.alia }}
+
+
+
+
+
+
+ {
+ showFullPlayer = false;
+ router.push(`/artist?id=${ar.id}`);
+ }
+ "
+ >
+ {{ ar.name }}
+
-
-
-
-
-
-
-
-
-
-
-
{{ music.getPlaySongData.name || "未知曲目" }}
-
-
- 其他音源
-
-
-
该歌曲暂时无法播放,为您采用其他音源,可能会与原曲存在差别
+
+ {{ music.getPlaySongData.artists || "未知艺术家" }}
-
+
+ {
+ if (typeof music.getPlaySongData.album !== 'string') {
+ showFullPlayer = false;
+ router.push(`/album?id=${music.getPlaySongData?.album.id}`);
+ }
+ }
+ "
+ >
+
+
+
+
+ {{
+ typeof music.getPlaySongData.album === "string"
+ ? music.getPlaySongData.album
+ : music.getPlaySongData.album.name
+ }}
+
+ 未知专辑
+
-
+
+
+
+
+
+
+
+ {{ music.getPlaySongData.name || "未知曲目" }}
+
{{ music.getPlaySongData.alia }}
+
+
+
+
-
-
@@ -192,7 +236,7 @@ const music = musicData();
const status = siteStatus();
const settings = siteSettings();
const { playList, playSongLyric } = storeToRefs(music);
-const { playerBackgroundType, showYrc } = storeToRefs(settings);
+const { playerBackgroundType, showYrc, playCoverType } = storeToRefs(settings);
const {
playerControlShow,
controlTimeOut,
@@ -202,6 +246,11 @@ const {
coverBackground,
} = storeToRefs(status);
+// 是否有歌词
+const isHasLrc = computed(() => {
+ return playSongLyric.value.lrc?.[0] && playSongLyric.value.lrc?.length > 4;
+});
+
// 全屏状态
const screenfullStatus = ref(false);
@@ -375,44 +424,6 @@ onUnmounted(() => {
&.no-lrc {
transform: translateX(50%);
}
- .cover {
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 70%;
- max-width: 55vh;
- height: auto;
- aspect-ratio: 1 / 1;
- .cover-img {
- width: 100%;
- height: 100%;
- border-radius: 32px;
- overflow: hidden;
- z-index: 1;
- box-shadow: 0 0 10px 6px #00000008;
- transition: opacity 0.1s ease-in-out;
- :deep(img) {
- width: 100%;
- height: 100%;
- opacity: 0;
- transition: opacity 0.3s ease-in-out;
- }
- }
- .cover-shadow {
- position: absolute;
- top: 12px;
- height: 100%;
- width: 100%;
- filter: blur(20px) opacity(0.6);
- transform: scale(0.95);
- z-index: 0;
- :deep(img) {
- width: 100%;
- height: 100%;
- }
- }
- }
.data {
width: 70%;
max-width: 55vh;
@@ -426,14 +437,14 @@ onUnmounted(() => {
display: flex;
align-items: center;
margin-left: 4px;
- .n-text {
+ .name {
font-size: 26px;
font-weight: bold;
color: var(--cover-main-color);
-webkit-line-clamp: 2;
}
.n-tag {
- margin-left: 6px;
+ margin-left: 12px;
cursor: pointer;
}
}
@@ -498,6 +509,88 @@ onUnmounted(() => {
}
}
}
+ &.record {
+ margin-top: 60px;
+ .desc {
+ align-items: center;
+ }
+ }
+ }
+ }
+ .right {
+ width: 50%;
+ .data {
+ padding: 0 24px;
+ margin-bottom: 40px;
+ .name {
+ display: flex;
+ flex-direction: column;
+ font-size: 30px;
+ font-weight: bold;
+ .name-text {
+ -webkit-line-clamp: 2;
+ }
+ .name-alias {
+ margin-top: 6px;
+ font-size: 18px;
+ font-weight: normal;
+ opacity: 0.6;
+ }
+ }
+ .other {
+ display: flex;
+ flex-direction: column;
+ margin-top: 8px;
+ font-size: 16px;
+ .n-icon {
+ margin-right: 4px;
+ color: var(--cover-main-color);
+ }
+ .artist {
+ display: flex;
+ align-items: center;
+ margin-right: 12px;
+ .all-ar {
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 2;
+ overflow: hidden;
+ word-break: break-all;
+ .ar {
+ opacity: 0.7;
+ display: inline-flex;
+ transition: opacity 0.3s;
+ cursor: pointer;
+ &::after {
+ content: "/";
+ margin: 0 4px;
+ transition: none;
+ }
+ &:last-child {
+ &::after {
+ display: none;
+ }
+ }
+ &:hover {
+ opacity: 1;
+ }
+ }
+ }
+ }
+ .album {
+ display: flex;
+ align-items: center;
+ margin-top: 4px;
+ .al {
+ opacity: 0.7;
+ transition: opacity 0.3s;
+ cursor: pointer;
+ &:hover {
+ opacity: 1;
+ }
+ }
+ }
+ }
}
}
// 全局
@@ -513,7 +606,6 @@ onUnmounted(() => {
.title-tip {
width: 200px;
padding: 12px 20px;
- background-color: var(--main-second-color);
border-radius: 12px;
.n-text {
display: initial;
diff --git a/src/components/Player/Lyric.vue b/src/components/Player/Lyric.vue
index b59aeb54..ac6900ee 100644
--- a/src/components/Player/Lyric.vue
+++ b/src/components/Player/Lyric.vue
@@ -4,7 +4,7 @@
:style="{
cursor: cursorShow ? 'pointer' : 'none',
}"
- :class="['lyric', `lyric-${lyricsPosition}`]"
+ :class="['lyric', `lyric-${lyricsPosition}`, playCoverType]"
@mouseenter="lrcMouseStatus = lrcMousePause ? true : false"
@mouseleave="lrcAllLeave"
>
@@ -13,6 +13,8 @@
v-if="playSongLyric.lrc?.[0] && playSongLyric.lrc?.length > 4"
:key="playSongLyric.lrc?.[0]"
class="lyric-all"
+ @after-enter="lyricsScroll(playSongLyricIndex)"
+ @after-leave="lyricsScroll(playSongLyricIndex)"
>
@@ -154,6 +156,7 @@ const {
lyricsBlur,
showTransl,
showRoma,
+ playCoverType,
} = storeToRefs(settings);
// 歌词滚动数据
@@ -188,14 +191,14 @@ const getYrcStyle = (wordData, lyricIndex) => {
// 如果当前歌词索引与播放歌曲的歌词索引不匹配
if (playSongLyricIndex.value !== lyricIndex) {
return {
- transitionDuration: `0ms, 0ms, 0.5s`,
+ transitionDuration: `0ms, 0ms, 0.35s`,
transitionDelay: `0ms`,
};
}
// 如果播放状态不是加载中,且当前单词的时间加上持续时间减去播放进度大于 0
if (status.playLoading === false && wordData.time + wordData.duration - playSeek.value > 0) {
return {
- transitionDuration: `0s, 0s, 0.5s`,
+ transitionDuration: `0s, 0s, 0.35s`,
transitionDelay: `0ms`,
WebkitMaskPositionX: `${
100 - Math.max(((playSeek.value - wordData.time) / wordData.duration) * 100, 0)
@@ -204,7 +207,7 @@ const getYrcStyle = (wordData, lyricIndex) => {
}
// 如果以上条件都不满足
return {
- transitionDuration: `${wordData.duration}ms, ${wordData.duration * 0.8}ms, 0.5s`,
+ transitionDuration: `${wordData.duration}ms, ${wordData.duration * 0.8}ms, 0.35s`,
transitionDelay: `${wordData.time - playSeek.value}ms, ${
wordData.time - playSeek.value + wordData.duration * 0.5
}ms, 0ms`,
@@ -251,7 +254,7 @@ onMounted(() => {
diff --git a/src/components/Player/PlayerCover.vue b/src/components/Player/PlayerCover.vue
new file mode 100644
index 00000000..a3103c4d
--- /dev/null
+++ b/src/components/Player/PlayerCover.vue
@@ -0,0 +1,212 @@
+
+
+
+
+
+
+
+
{
+ e.target.style.opacity = 1;
+ }
+ "
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/stores/musicData.js b/src/stores/musicData.js
index 0fc870d8..6992cb0b 100644
--- a/src/stores/musicData.js
+++ b/src/stores/musicData.js
@@ -2,7 +2,7 @@
import { defineStore } from "pinia";
import { getPersonalFm, setFmToTrash } from "@/api/recommend";
import { changePlayIndex } from "@/utils/Player";
-// import { isLogin } from "@/utils/auth";
+import { isLogin } from "@/utils/auth";
import formatData from "@/utils/formatData";
const useMusicDataStore = defineStore("musicData", {
@@ -197,6 +197,7 @@ const useMusicDataStore = defineStore("musicData", {
// 私人FM垃圾桶
async setPersonalFmToTrash(id) {
try {
+ if (!isLogin()) return $message.warning("请登录后使用");
const result = await setFmToTrash(id);
if (result.code === 200) {
$message.success("已移至垃圾桶");
diff --git a/src/stores/siteSettings.js b/src/stores/siteSettings.js
index 533e495e..30d819cb 100644
--- a/src/stores/siteSettings.js
+++ b/src/stores/siteSettings.js
@@ -18,6 +18,7 @@ const useSiteSettingsStore = defineStore("siteSettings", {
themeTypeData: {},
themeAutoCover: true, // 主题色跟随封面
// 播放部分
+ playCoverType: "cover", // 播放器样式
songLevel: "exhigh", // 歌曲音质
autoPlay: false, // 程序启动时自动播放
songVolumeFade: true, // 歌曲渐入渐出
diff --git a/src/style/animate.scss b/src/style/animate.scss
index a389d47a..05bea710 100644
--- a/src/style/animate.scss
+++ b/src/style/animate.scss
@@ -83,3 +83,12 @@
transform: rotate(360deg) scale(1) translateX(0);
}
}
+
+@keyframes playerCoverRotate {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/src/utils/formatData.js b/src/utils/formatData.js
index 21e40030..b9eedcf9 100644
--- a/src/utils/formatData.js
+++ b/src/utils/formatData.js
@@ -57,7 +57,7 @@ const formatData = (data, type = "playlist", noTracks = false) => {
cover,
coverSize,
mv: v.mv,
- alia: v.alias?.[0] || v.transNames?.[0],
+ alia: v.alia?.[0] || v.alias?.[0] || v.transNames?.[0],
fee: v.fee,
pc: v.pc,
size: v.size,
diff --git a/src/views/Setting/index.vue b/src/views/Setting/index.vue
index ab7efac5..469a9942 100644
--- a/src/views/Setting/index.vue
+++ b/src/views/Setting/index.vue
@@ -169,6 +169,26 @@
+
+
+ 播放器样式
+ 播放器左侧区域样式
+
+
+
播放背景样式
@@ -470,6 +490,7 @@ const {
downloadPath,
memorySeek,
showGithub,
+ playCoverType,
} = storeToRefs(settings);
// 标签页数据