diff --git a/index.html b/index.html
index 26c5618..1e31163 100644
--- a/index.html
+++ b/index.html
@@ -262,12 +262,25 @@
diff --git a/js/settings.js b/js/settings.js
index 9e97abc..c3578bc 100644
--- a/js/settings.js
+++ b/js/settings.js
@@ -6068,6 +6068,17 @@ export async function initializeSettings(scrobbler, player, api, ui) {
observer.observe(appearanceTabContent, { attributes: true });
}
+ // Spins album cover and adds hole in fullscreen
+ const cdAlbumCoverToggle = document.getElementById("cd-album-cover-toggle");
+
+ if (cdAlbumCoverToggle) {
+ cdAlbumCoverToggle.checked = visualizerSettings.isCdAlbumCoverEnabled();
+
+ cdAlbumCoverToggle.addEventListener('change', async (e) => {
+ visualizerSettings.setCdAlbumCoverEnabled(e.target.checked);
+ });
+ }
+
// Watch for downloads tab becoming active and update setting visibility
const downloadsTabContent = document.getElementById('settings-tab-downloads');
if (downloadsTabContent) {
diff --git a/js/storage.js b/js/storage.js
index 1097cf0..c7d61c5 100644
--- a/js/storage.js
+++ b/js/storage.js
@@ -1080,6 +1080,19 @@ export const visualizerSettings = {
setButterchurnRandomizeEnabled(enabled) {
localStorage.setItem('butterchurn-randomize-enabled', enabled);
},
+
+ // Spin album cover and add hole in fullscreen
+ isCdAlbumCoverEnabled() {
+ try {
+ return localStorage.getItem('cd-album-cover-enabled') === 'true';
+ } catch {
+ return true;
+ }
+ },
+
+ setCdAlbumCoverEnabled(enabled) {
+ localStorage.setItem('cd-album-cover-enabled', enabled);
+ },
};
export const equalizerSettings = {
diff --git a/js/ui.js b/js/ui.js
index a3680b9..ed885b1 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -1355,6 +1355,14 @@ export class UIRenderer {
const lyricsPane = document.getElementById('fullscreen-lyrics-pane');
const lyricsContent = document.getElementById('fullscreen-lyrics-content');
const lyricsToggleBtn = document.getElementById('toggle-fullscreen-lyrics-btn');
+ const coverImage = document.getElementById('fullscreen-cover-image');
+ const coverCard = document.getElementById('fullscreen-artwork-card');
+ const cdRing = document.getElementById('cd-ring');
+ const isCdMode = visualizerSettings.isCdAlbumCoverEnabled();
+
+ coverImage.classList.toggle("cd", isCdMode);
+ coverCard.classList.toggle("cd", isCdMode);
+ cdRing.classList.toggle("cd", isCdMode);
await this.updateFullscreenMetadata(track, nextTrack);
@@ -1414,7 +1422,6 @@ export class UIRenderer {
overlay.classList.remove('fullscreen-cover-no-round');
}
- const coverImage = document.getElementById('fullscreen-cover-image');
if (coverImage?.vanillaTilt) {
coverImage.vanillaTilt.destroy();
}
diff --git a/styles.css b/styles.css
index e3d1672..4eb3c33 100644
--- a/styles.css
+++ b/styles.css
@@ -11491,3 +11491,32 @@ body:has(#side-panel.active) #close-fullscreen-cover-btn {
opacity: 0.8;
vertical-align: middle;
}
+
+img.cd {
+ border-radius: 50% !important;
+ box-shadow: none;
+ clip-path: url(#cd-hole-clip);
+}
+
+.fullscreen-artwork-card.cd {
+ position: relative;
+ border-radius: 50% !important;
+ border: .125vw solid #ccc;
+ animation: spin 200s linear infinite;
+}
+
+.cd-ring {
+ display: none;
+}
+
+.cd-ring.cd {
+ display: block;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 23.5%;
+ height: 23.5%;
+ border-radius: 50%;
+ border: .125vw solid #ccc;
+}
\ No newline at end of file