diff --git a/index.html b/index.html
index 81c1ece..3da0d01 100644
--- a/index.html
+++ b/index.html
@@ -2978,6 +2978,32 @@
+
+
+ Tilt Distance
+ Max tilt distance (default: 10)
+
+
+
+
+
+ Tilt Speed
+ Tilt animation speed in ms (default: 240)
+
+
+
diff --git a/js/settings.js b/js/settings.js
index 111c2ee..d6c6bc3 100644
--- a/js/settings.js
+++ b/js/settings.js
@@ -37,6 +37,8 @@ import {
preferDolbyAtmosSettings,
fullscreenCoverNoRoundSettings,
fullscreenCoverVanillaTiltSettings,
+ fullscreenCoverTiltDistanceSettings,
+ fullscreenCoverTiltSpeedSettings,
} from './storage.js';
import { audioContextManager, getPresetsForBandCount } from './audio-context.js';
import { calculateBiquadResponse, interpolate, getNormalizationOffset, runAutoEqAlgorithm } from './autoeq-engine.js';
@@ -4626,6 +4628,26 @@ export async function initializeSettings(scrobbler, player, api, ui) {
});
}
+ // Fullscreen Cover Tilt Distance
+ const fullscreenCoverTiltDistanceSlider = document.getElementById('fullscreen-cover-tilt-distance');
+ if (fullscreenCoverTiltDistanceSlider) {
+ fullscreenCoverTiltDistanceSlider.value = fullscreenCoverTiltDistanceSettings.getValue();
+ fullscreenCoverTiltDistanceSlider.addEventListener('input', (e) => {
+ fullscreenCoverTiltDistanceSettings.setValue(parseInt(e.target.value));
+ window.dispatchEvent(new CustomEvent('fullscreen-cover-settings-changed'));
+ });
+ }
+
+ // Fullscreen Cover Tilt Speed
+ const fullscreenCoverTiltSpeedSlider = document.getElementById('fullscreen-cover-tilt-speed');
+ if (fullscreenCoverTiltSpeedSlider) {
+ fullscreenCoverTiltSpeedSlider.value = fullscreenCoverTiltSpeedSettings.getValue();
+ fullscreenCoverTiltSpeedSlider.addEventListener('input', (e) => {
+ fullscreenCoverTiltSpeedSettings.setValue(parseInt(e.target.value));
+ window.dispatchEvent(new CustomEvent('fullscreen-cover-settings-changed'));
+ });
+ }
+
// Waveform Toggle
const waveformToggle = document.getElementById('waveform-toggle');
if (waveformToggle) {
diff --git a/js/storage.js b/js/storage.js
index f42992b..246fd07 100644
--- a/js/storage.js
+++ b/js/storage.js
@@ -622,6 +622,40 @@ export const fullscreenCoverVanillaTiltSettings = {
},
};
+export const fullscreenCoverTiltDistanceSettings = {
+ STORAGE_KEY: 'fullscreen-cover-tilt-distance',
+
+ getValue() {
+ try {
+ const val = parseInt(localStorage.getItem(this.STORAGE_KEY));
+ return val !== null && !isNaN(val) ? val : 10;
+ } catch {
+ return 10;
+ }
+ },
+
+ setValue(value) {
+ localStorage.setItem(this.STORAGE_KEY, value);
+ },
+};
+
+export const fullscreenCoverTiltSpeedSettings = {
+ STORAGE_KEY: 'fullscreen-cover-tilt-speed',
+
+ getValue() {
+ try {
+ const val = parseInt(localStorage.getItem(this.STORAGE_KEY));
+ return val !== null && !isNaN(val) ? val : 240;
+ } catch {
+ return 240;
+ }
+ },
+
+ setValue(value) {
+ localStorage.setItem(this.STORAGE_KEY, value);
+ },
+};
+
export const cardSettings = {
COMPACT_ARTIST_KEY: 'card-compact-artist',
COMPACT_ALBUM_KEY: 'card-compact-album',
diff --git a/js/ui.js b/js/ui.js
index c1cf338..1fd79d0 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -28,6 +28,8 @@ import {
settingsUiState,
fullscreenCoverNoRoundSettings,
fullscreenCoverVanillaTiltSettings,
+ fullscreenCoverTiltDistanceSettings,
+ fullscreenCoverTiltSpeedSettings,
} from './storage.js';
import { db } from './db.js';
import { getVibrantColorFromImage } from './vibrant-color.js';
@@ -179,9 +181,12 @@ export class UIRenderer {
}
if (coverImage) {
if (fullscreenCoverVanillaTiltSettings.isEnabled() && window.VanillaTilt) {
+ if (coverImage.vanillaTilt) {
+ coverImage.vanillaTilt.destroy();
+ }
window.VanillaTilt.init(coverImage, {
- max: 15,
- speed: 400,
+ max: fullscreenCoverTiltDistanceSettings.getValue(),
+ speed: fullscreenCoverTiltSpeedSettings.getValue(),
glare: true,
'max-glare': 0.3,
});
@@ -1267,8 +1272,8 @@ export class UIRenderer {
const coverImage = document.getElementById('fullscreen-cover-image');
if (fullscreenCoverVanillaTiltSettings.isEnabled() && coverImage && window.VanillaTilt) {
window.VanillaTilt.init(coverImage, {
- max: 15,
- speed: 400,
+ max: fullscreenCoverTiltDistanceSettings.getValue(),
+ speed: fullscreenCoverTiltSpeedSettings.getValue(),
glare: true,
'max-glare': 0.3,
});
diff --git a/styles.css b/styles.css
index 0ad2aee..75aada6 100644
--- a/styles.css
+++ b/styles.css
@@ -2950,6 +2950,30 @@ body.multi-select-mode .track-item:hover {
width: 100px;
}
+.setting-item input[type='range'] {
+ width: 120px;
+ accent-color: var(--accent);
+ appearance: none;
+ height: 6px;
+ background: var(--border);
+ border-radius: var(--radius-full);
+ outline: none;
+}
+
+.setting-item input[type='range']::-webkit-slider-thumb {
+ appearance: none;
+ width: 18px;
+ height: 18px;
+ background: var(--primary);
+ border-radius: var(--radius-full);
+ cursor: pointer;
+ transition: background-color var(--transition-fast);
+}
+
+.setting-item input[type='range']::-webkit-slider-thumb:hover {
+ background: var(--highlight);
+}
+
.playback-speed-control {
display: flex;
align-items: center;