diff --git a/THEMES.md b/THEMES.md index 4704a5b..7047f0e 100644 --- a/THEMES.md +++ b/THEMES.md @@ -19,3 +19,7 @@ Here you can find a preview of all the themes. Some of them may have different c #### Psycho ![Psycho Screenshot](Sleek/psycho.png) + +## Turntable + +![Turntable](Turntable/screenshots/full_app_display_vertical_mode.png) diff --git a/Turntable/LICENSE b/Turntable/LICENSE new file mode 100644 index 0000000..52ab52a --- /dev/null +++ b/Turntable/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Grason Chan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Turntable/README.md b/Turntable/README.md new file mode 100644 index 0000000..e0786c6 --- /dev/null +++ b/Turntable/README.md @@ -0,0 +1,86 @@ +# Turntable + +Based on Spotify original theme. + +**Note:** Require Spicetify **v2.2.0** or higher! Otherwise, performance problems will happen when the turntable rotate! + +## Screenshots + +
+ turntable +
+
+ full app display +
+
+ full app display - vertical mode +
+ + +## More + +### About Turntable + +Use CSS to achieve, not picture. This means it can be scaled to any size, but make sure the album cover is not blurry. + +Actually, the rotation of the turntable was created at spicetify v1, but in some cases, animation is affected by other factors. I think "fullAppDisplay.js high GPU usage" is the reason. Fortunately, it's normal now! + +### Info + +Designed and developed by [Grason Chan](https://github.com/grasonchan). + +The turntable inspired by [Netease Music](https://music.163.com) and [Smartisan OS build-in Music Player](https://www.smartisan.com/os/#/beauty) (not include code). + +Develop and test on macOS. If there's any problem, please open issue or PR. + +### Installation + +1. add extension - [Full App Display](https://github.com/khanhas/spicetify-cli/wiki/Extensions#full-app-display) + +```shell +spicetify config extensions fullAppDisplay.js +spicetify apply +``` + +2. put **Turntable** and **rotateTurntable.js** into the **spicetify_data** + +```shell +cd spicetify-themes +cp -r Turntable ~/spicetify_data/Themes +cp Turntable/rotateTurntable.js ~/spicetify_data/Extensions +``` + +3. select the theme and extension, then apply + +```shell +spicetify config current_theme Turntable +spicetify config extensions rotateTurntable.js +spicetify apply +``` + +### How to Uninstall + +1. remove **Turntable** and **rotateTurntable.js** + +```shell +rm -r ~/spicetify_data/Themes/Turntable +rm ~/spicetify_data/Extensions/rotateTurntable.js +``` + +2. config to spicetify default theme + +```shell +spicetify config current_theme SpicetifyDefault +``` + +3. remove extension - Full App Display (optional) + +```shell +spicetify config extensions fullAppDisplay.js- +``` + +4. apply + +```shell +spicetify apply +``` diff --git a/Turntable/rotateTurntable.js b/Turntable/rotateTurntable.js new file mode 100644 index 0000000..125b94a --- /dev/null +++ b/Turntable/rotateTurntable.js @@ -0,0 +1,30 @@ +window.addEventListener("load", () => { + (function rotateTurntable() { + if (!Spicetify.Player.origin || !document.querySelector("#fad-art-image")) { + setTimeout(rotateTurntable, 250); + return; + } + + const fullAppDisplay = document.querySelector("#full-app-display"); + + function handleRotate() { + const fadArt = document.querySelector("#fad-art-image"); + + Spicetify.Player.isPlaying() + ? fadArt.style.animationPlayState = "running" + : fadArt.style.animationPlayState = "paused"; + } + + handleRotate(); + + Spicetify.Player.addEventListener("onplaypause", () => setTimeout(handleRotate)); + + fullAppDisplay.addEventListener("contextmenu", () => { + const configSwitchBtns = document.querySelectorAll("#popup-config-container button.switch"); + + for (const configSwitch of configSwitchBtns) { + configSwitch.addEventListener("click", handleRotate); + } + }); + })(); +}); diff --git a/Turntable/screenshots/full_app_display.png b/Turntable/screenshots/full_app_display.png new file mode 100644 index 0000000..eba90fc Binary files /dev/null and b/Turntable/screenshots/full_app_display.png differ diff --git a/Turntable/screenshots/full_app_display_vertical_mode.png b/Turntable/screenshots/full_app_display_vertical_mode.png new file mode 100644 index 0000000..e924c7a Binary files /dev/null and b/Turntable/screenshots/full_app_display_vertical_mode.png differ diff --git a/Turntable/screenshots/turntable.png b/Turntable/screenshots/turntable.png new file mode 100644 index 0000000..02cd00e Binary files /dev/null and b/Turntable/screenshots/turntable.png differ diff --git a/Turntable/user.css b/Turntable/user.css new file mode 100644 index 0000000..3b866c3 --- /dev/null +++ b/Turntable/user.css @@ -0,0 +1,305 @@ +:root { + --spotify-main-color: #1db954; + --round-value: 50%; + --main-blur-backdrop: blur(20px) saturate(180%) +} + + +/* remove upgrade button, user name */ +.main-topBar-UpgradeButton, +.main-userWidget-displayName { + display: none +} + + +/* Navbar */ +.Root__nav-bar { + background-color: #0f0f0f +} + +.main-rootlist-rootlistDividerGradient { + display: none +} + + +/* Search Input */ +.x-searchInput-searchInputInput { + background-color: #2a2a2a +} + +.x-searchInput-searchInputInput, +.x-searchInput-searchInputSearchIcon, +.x-searchInput-searchInputClearButton { + color: #c0c0c0 !important +} + +.x-searchInput-searchInputInput::placeholder { + color: #888 +} + + +/* Playlist */ +.main-entityHeader-backgroundColor, +.main-actionBarBackground-background, +.main-topBar-overlay { + background-color: unset !important +} + +.main-entityHeader-overlay { + background: unset +} + +.main-actionBarBackground-background { + background-image: unset +} + +.main-entityHeader-shadow { + box-shadow: unset +} + +.main-topBar-background { + background-color: #181818 !important +} + +.main-virtualScrollList-wrapper [role="row"]:nth-child(odd) { + background: linear-gradient(to right, #121212, #191919, #121212) +} + + +/* cover image */ +.main-nowPlayingWidget-coverExpanded{ + transform: translateX(-78px) +} + +.main-coverSlotCollapsed-container { + margin-right: 5px +} + +.main-nowPlayingWidget-coverArt .cover-art.shadow, +.main-nowPlayingWidget-coverArt .cover-art-image { + border-radius: var(--round-value) +} + +.main-nowPlayingWidget-coverArt .cover-art.shadow { + box-shadow: unset +} + +.main-nowPlayingWidget-coverArt .cover-art-image { + border: 2px solid #aaa; + transform: scale(1.1); + filter: drop-shadow(0 0 3px rgba(255, 255, 255, .2)) +} + +/* expand & collapse button */ +.main-coverSlotCollapsed-expandButton { + top: 50%; + left: 50%; + transform: translate(-50%, -50%) !important +} + +.main-coverSlotCollapsed-expandButton, +.main-coverSlotExpandedCollapseButton-collapseButton { + backdrop-filter: var(--main-blur-backdrop); + background: unset; + background-color: rgba(9, 9, 9, .2); + transition: background-color .5s, opacity .5s; + border-radius: var(--round-value) +} + +.main-coverSlotCollapsed-expandButton:hover, +.main-coverSlotExpandedCollapseButton-collapseButton:hover { + background: unset; + background-color: rgba(9, 9, 9, .3); + transform: unset +} + +.main-coverSlotCollapsed-chevron, +.main-coverSlotExpandedCollapseButton-chevron { + padding: 5px; + fill: #fff; + transition: fill .5s +} + +.main-coverSlotCollapsed-expandButton:hover .main-coverSlotCollapsed-chevron, +.main-coverSlotExpandedCollapseButton-collapseButton:hover .main-coverSlotExpandedCollapseButton-chevron { + fill: #ddd +} + + +/* progress bar */ +.Root__now-playing-bar { + position: relative +} + +.playback-bar { + width: 100%; + position: absolute; + top: 0; + left: 0 +} + +.progress-bar-wrapper { + height: 4px +} + +.playback-bar .progress-bar__fg { + background-color: var(--spotify-main-color) +} + +.playback-bar__progress-time, +.main-playbackBarRemainingTime-container { + position: absolute; + top: 12px; + left: 50% +} + +.playback-bar__progress-time { + transform: translateX(-45px) +} + +.playback-bar__progress-time::after { + position: absolute; + right: -5px; + font-weight: bold; + color: var(--spotify-main-color); + content: "/" +} + +.main-playbackBarRemainingTime-container { + transform: translateX(-1px) +} + +.player-controls { + margin-top: 38px +} + + +/* modal backdrop */ +.GenericModal__overlay { + backdrop-filter: var(--main-blur-backdrop); + background-color: rgba(9, 9, 9, .2) +} + + +/* full app display */ +#full-app-display { + background-color: #222 +} + +#fad-background { + display: none +} + +#fad-art, +#fad-art-image, +#fad-art-inner { + border-radius: var(--round-value) !important +} + +#fad-art { + width: 300px !important; + margin: 60px 80px; + position: relative; + transform: scale(.85) +} + +#fad-art-image { + box-shadow: 0 0 10px rgba(3, 3, 3, .5) inset +} + +#fad-art-inner { + display: none +} + +#fad-art::before, #fad-art::after { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; + border-radius: 50%; + content: '' +} + +#fad-art::before { + background: radial-gradient(#333, #000); + box-shadow: 0 0 10px #000; + transform: scale(1.5) +} + +#fad-art::after { + background-color: #252525; + transform: scale(1.65); + z-index: -1 +} + +#fad-details { + max-width: 520px !important +} + +#fad-details #fad-title { + font-size: 38px +} + +#fad-details #fad-artist { + margin-top: 10px; + font-size: 24px +} + +#fad-details #fad-album { + margin-top: 6px; + font-size: 16px +} + +#fad-details #fad-artist > *, +#fad-details #fad-album > *, +#fad-details #fad-status > #fad-controls > * > svg { + vertical-align: middle +} + +#fad-details #fad-artist > svg { + width: 24px; + height: 24px +} + +#fad-details #fad-album > svg { + width: 16px; + height: 16px; + margin-left: 4px; + margin-right: 9px +} + +#fad-play > svg { + width: 24px; + height: 24px +} + +#fad-controls > button > svg { + fill: #ccc +} + +#fad-controls > button:hover > svg { + fill: #fff +} + + +@media (min-width: 1460px) and (min-height: 960px) { + #fad-foreground { + transform: scale(1.2) + } +} + + +/* rotate turntable */ +#fad-art-image { + animation: rotate-cover_img 20s linear infinite paused +} + +@keyframes rotate-cover_img { + from { + transform: rotate(0) + } + to { + transform: rotate(360deg) + } +}