From 42f3da9b375a38c7db9aaf003456b73ceeeb3510 Mon Sep 17 00:00:00 2001 From: GalvinGao Date: Fri, 14 Jan 2022 15:30:19 +0800 Subject: [PATCH] feat: add reversed mode & improvements to lyrics animation (#1226) * feat(reversed-mode): add reversed mode & improvements to lyrics animation * feat(lyrics-animation): improve `:active` style * fix: extra white space after artist in lyrics view * refactor: remove unused function * feat: slightly add duration of transition to improve replication from Apple Music style --- src/assets/icons/sort-up.svg | 2 ++ src/components/Player.vue | 7 ++++ src/locale/lang/en.js | 6 ++-- src/locale/lang/zh-CN.js | 2 ++ src/locale/lang/zh-TW.js | 2 ++ src/store/initLocalStorage.js | 1 + src/utils/Player.js | 48 ++++++++++++++++++++++----- src/views/lyrics.vue | 61 +++++++++++++++++++++++++---------- src/views/settings.vue | 32 ++++++++++++++++++ 9 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 src/assets/icons/sort-up.svg diff --git a/src/assets/icons/sort-up.svg b/src/assets/icons/sort-up.svg new file mode 100644 index 0000000..3efe4cf --- /dev/null +++ b/src/assets/icons/sort-up.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/components/Player.vue b/src/components/Player.vue index 4ee8c54..ff92882 100644 --- a/src/components/Player.vue +++ b/src/components/Player.vue @@ -132,6 +132,13 @@ @click.native="player.switchShuffle" > +
diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js index fd33dc4..087f7c5 100644 --- a/src/locale/lang/en.js +++ b/src/locale/lang/en.js @@ -100,6 +100,7 @@ export default { repeat: 'Repeat', repeatTrack: 'Repeat Track', shuffle: 'Shuffle', + reversed: 'Reversed', play: 'Play', pause: 'Pause', mute: 'Mute', @@ -154,8 +155,9 @@ export default { showPlaylistsByAppleMusic: 'Show playlists by Apple Music', enableDiscordRichPresence: 'Enable Discord Rich Presence', enableGlobalShortcut: 'Enable Global Shortcut', - showLibraryDefault: 'Show library default', - subTitleDefault: 'Sub title alia default', + showLibraryDefault: 'Show Library after App Launched', + subTitleDefault: 'Show Alias for Subtitle by default', + enableReversedMode: 'Enable Reversed Mode (Experimental)', lyricsBackground: { text: 'Show Lyrics Background', off: 'Off', diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js index 084c94a..cb077ad 100644 --- a/src/locale/lang/zh-CN.js +++ b/src/locale/lang/zh-CN.js @@ -101,6 +101,7 @@ export default { repeat: '循环播放', repeatTrack: '单曲循环', shuffle: '随机播放', + reversed: '倒序播放', play: '播放', pause: '暂停', mute: '静音', @@ -157,6 +158,7 @@ export default { enableGlobalShortcut: '启用全局快捷键', showLibraryDefault: '启动后显示音乐库', subTitleDefault: '副标题使用别名', + enableReversedMode: '启用倒序播放功能 (实验性功能)', lyricsBackground: { text: '显示歌词背景', off: '关闭', diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js index 06ac527..55fa5d3 100644 --- a/src/locale/lang/zh-TW.js +++ b/src/locale/lang/zh-TW.js @@ -97,6 +97,7 @@ export default { repeat: '循環播放', repeatTrack: '單曲循環', shuffle: '隨機播放', + reversed: '倒序播放', play: '播放', pause: '暫停', mute: '靜音', @@ -154,6 +155,7 @@ export default { enableGlobalShortcut: '啟用全域快捷鍵', showLibraryDefault: '啟動後顯示音樂庫', subTitleDefault: '副標題使用別名', + enableReversedMode: '啟用倒序播放功能 (實驗性功能)', lyricsBackground: { text: '顯示歌詞背景', off: '關閉', diff --git a/src/store/initLocalStorage.js b/src/store/initLocalStorage.js index 5fa494a..b16e847 100644 --- a/src/store/initLocalStorage.js +++ b/src/store/initLocalStorage.js @@ -19,6 +19,7 @@ let localStorage = { enableUnblockNeteaseMusic: true, automaticallyCacheSongs: true, cacheLimit: 8192, + enableReversedMode: false, nyancatStyle: false, showLyricsTranslation: true, lyricsBackground: true, diff --git a/src/utils/Player.js b/src/utils/Player.js index c6d9fda..5bb7cd9 100644 --- a/src/utils/Player.js +++ b/src/utils/Player.js @@ -28,6 +28,7 @@ export default class { this._enabled = false; // 是否启用Player this._repeatMode = 'off'; // off | on | one this._shuffle = false; // true | false + this._reversed = false; this._volume = 1; // 0 to 1 this._volumeBeforeMuted = 1; // 用于保存静音前的音量 this._personalFMLoading = false; // 是否正在私人FM中加载新的track @@ -91,6 +92,18 @@ export default class { this._shuffleTheList(); } } + get reversed() { + return this._reversed; + } + set reversed(reversed) { + if (this._isPersonalFM) return; + if (reversed !== true && reversed !== false) { + console.warn('reversed: invalid args, must be Boolean'); + return; + } + console.log('changing reversed to:', reversed); + this._reversed = reversed; + } get volume() { return this._volume; } @@ -191,27 +204,43 @@ export default class { }, 1000); } _getNextTrack() { + const next = this._reversed ? this.current - 1 : this.current + 1; + if (this._playNextList.length > 0) { let trackID = this._playNextList.shift(); return [trackID, this.current]; } - // 当歌曲是列表最后一首 && 循环模式开启 - if (this.list.length === this.current + 1 && this.repeatMode === 'on') { - return [this.list[0], 0]; + // 循环模式开启,则重新播放当前模式下的相对的下一首 + if (this.repeatMode === 'on') { + if (this._reversed && this.current === 0) { + // 倒序模式,当前歌曲是第一首,则重新播放列表最后一首 + return [this.list[this.list.length - 1], this.list.length - 1]; + } else if (this.list.length === this.current + 1) { + // 正序模式,当前歌曲是最后一首,则重新播放第一首 + return [this.list[0], 0]; + } } // 返回 [trackID, index] - return [this.list[this.current + 1], this.current + 1]; + return [this.list[next], next]; } _getPrevTrack() { - // 当歌曲是列表第一首 && 循环模式开启 - if (this.current === 0 && this.repeatMode === 'on') { - return [this.list[this.list.length - 1], this.list.length - 1]; + const next = this._reversed ? this.current + 1 : this.current - 1; + + // 循环模式开启,则重新播放当前模式下的相对的下一首 + if (this.repeatMode === 'on') { + if (this._reversed && this.current === 0) { + // 倒序模式,当前歌曲是最后一首,则重新播放列表第一首 + return [this.list[0], 0]; + } else if (this.list.length === this.current + 1) { + // 正序模式,当前歌曲是第一首,则重新播放列表最后一首 + return [this.list[this.list.length - 1], this.list.length - 1]; + } } // 返回 [trackID, index] - return [this.list[this.current - 1], this.current - 1]; + return [this.list[next], next]; } async _shuffleTheList(firstTrackID = this._currentTrack.id) { let list = this._list.filter(tid => tid !== firstTrackID); @@ -726,6 +755,9 @@ export default class { switchShuffle() { this.shuffle = !this.shuffle; } + switchReversed() { + this.reversed = !this.reversed; + } clearPlayNextList() { this._playNextList = []; diff --git a/src/views/lyrics.vue b/src/views/lyrics.vue index 7cf9817..d7f4216 100644 --- a/src/views/lyrics.vue +++ b/src/views/lyrics.vue @@ -59,8 +59,8 @@ {{ artist.name }} - + >{{ artist.name }} -
+ > + {{ line.contents[0] }} +
+ {{ line.contents[1] }} + @@ -400,16 +410,6 @@ export default { } }, 50); }, - formatLine(line) { - const showLyricsTranslation = this.$store.state.settings - .showLyricsTranslation; - if (showLyricsTranslation && line.contents[1]) { - return `${line.contents[0]}
${line.contents[1]}
`; - } else if (line.contents[0] !== undefined) { - return `${line.contents[0]}`; - } - return 'unknown'; - }, moveToFMTrash() { this.player.moveToFMTrash(); }, @@ -673,17 +673,28 @@ export default { scrollbar-width: none; // firefox .line { - padding: 18px; - transition: 0.2s; + margin: 2px 0; + padding: 12px 18px; + transition: 0.5s; border-radius: 12px; &:hover { background: var(--color-secondary-bg-for-transparent); } + &:active { + transform: scale(0.95); + } span { opacity: 0.28; cursor: default; + font-size: 1em; + transition: all 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94); + } + + span.translation { + opacity: 0.2; + font-size: 0.95em; } } @@ -691,9 +702,19 @@ export default { background: unset; } + .translation { + margin-top: 0.1em; + } + .highlight span { opacity: 0.98; - transition: 0.5s; + display: inline-block; + font-size: 1.25em; + } + + .highlight span.translation { + opacity: 0.65; + font-size: 1.1em; } } @@ -755,6 +776,12 @@ export default { } } +@media screen and (min-width: 1200px) { + .right-side .lyrics-container { + max-width: 600px; + } +} + .slide-up-enter-active, .slide-up-leave-active { transition: all 0.4s; diff --git a/src/views/settings.vue b/src/views/settings.vue index 37da6a9..a36ec7b 100644 --- a/src/views/settings.vue +++ b/src/views/settings.vue @@ -384,6 +384,23 @@ +
+
+
{{ $t('settings.enableReversedMode') }}
+
+
+
+ + +
+
+
+
🐈️ 🏳️‍🌈
@@ -805,6 +822,21 @@ export default { }); }, }, + enableReversedMode: { + get() { + if (this.settings.enableReversedMode === undefined) return false; + return this.settings.enableReversedMode; + }, + set(value) { + this.$store.commit('updateSettings', { + key: 'enableReversedMode', + value, + }); + if (value === false) { + this.$store.state.player.reversed = false; + } + }, + }, enableGlobalShortcut: { get() { return this.settings.enableGlobalShortcut;