feat(visualizer): visualizer dimming
This commit is contained in:
parent
3685e33b48
commit
4762dea607
6 changed files with 83 additions and 2 deletions
29
index.html
29
index.html
|
|
@ -119,7 +119,9 @@
|
|||
|
||||
<div id="fullscreen-cover-overlay" style="display: none">
|
||||
<div class="fullscreen-cover-content">
|
||||
<canvas id="visualizer-canvas"></canvas>
|
||||
<div id="visualizer-container">
|
||||
<canvas id="visualizer-canvas"></canvas>
|
||||
</div>
|
||||
<button id="toggle-ui-btn" class="fullscreen-ui-toggle" title="Toggle UI">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
|
|
@ -3743,6 +3745,31 @@
|
|||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-item" id="visualizer-dimming-setting">
|
||||
<div class="info">
|
||||
<span class="label">Visualizer Brightness</span>
|
||||
<span class="description"
|
||||
>Adjust the brightness of the visualizer. Lower this if the visualizer
|
||||
is too bright for you.</span
|
||||
>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; gap: 10px">
|
||||
<input
|
||||
type="range"
|
||||
id="visualizer-dimming-slider"
|
||||
min="0.1"
|
||||
max="1.0"
|
||||
step="0.05"
|
||||
value="1.0"
|
||||
style="width: 100px"
|
||||
/>
|
||||
<span
|
||||
id="visualizer-dimming-value"
|
||||
style="font-size: 0.9rem; min-width: 3em; text-align: right"
|
||||
>100%</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Butterchurn Settings -->
|
||||
<div class="setting-item" id="butterchurn-cycle-setting" style="display: none">
|
||||
<div class="info">
|
||||
|
|
|
|||
|
|
@ -2110,6 +2110,23 @@ export function initializeSettings(scrobbler, player, api, ui) {
|
|||
});
|
||||
}
|
||||
|
||||
const visualizerDimmingSlider = document.getElementById('visualizer-dimming-slider');
|
||||
const visualizerDimmingValue = document.getElementById('visualizer-dimming-value');
|
||||
if (visualizerDimmingSlider && visualizerDimmingValue) {
|
||||
const currentDimming = visualizerSettings.getDimAmount();
|
||||
visualizerDimmingSlider.value = currentDimming;
|
||||
visualizerDimmingValue.textContent = `${(currentDimming * 100).toFixed(0)}%`;
|
||||
|
||||
visualizerDimmingSlider.addEventListener('input', (e) => {
|
||||
const newDimming = parseFloat(e.target.value);
|
||||
visualizerSettings.setDimAmount(newDimming);
|
||||
visualizerDimmingValue.textContent = `${(newDimming * 100).toFixed(0)}%`;
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('visualizer-dim-change', { detail: { dimAmount: newDimming } })
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Visualizer Smart Intensity
|
||||
const smartIntensityToggle = document.getElementById('smart-intensity-toggle');
|
||||
if (smartIntensityToggle) {
|
||||
|
|
|
|||
|
|
@ -763,6 +763,7 @@ export const visualizerSettings = {
|
|||
MODE_KEY: 'visualizer-mode', // 'solid' or 'blended'
|
||||
PRESET_KEY: 'visualizer-preset',
|
||||
BUTTERCHURN_CYCLE_KEY: 'butterchurn-cycle-duration',
|
||||
DIM_AMOUNT_KEY: 'visualizer-dim-amount',
|
||||
|
||||
getPreset() {
|
||||
try {
|
||||
|
|
@ -828,6 +829,20 @@ export const visualizerSettings = {
|
|||
localStorage.setItem(this.SMART_INTENSITY_KEY, enabled);
|
||||
},
|
||||
|
||||
getDimAmount() {
|
||||
try {
|
||||
const val = localStorage.getItem(this.DIM_AMOUNT_KEY);
|
||||
if (val === null) return 1.0;
|
||||
return parseFloat(val);
|
||||
} catch {
|
||||
return 1.0;
|
||||
}
|
||||
},
|
||||
|
||||
setDimAmount(value) {
|
||||
localStorage.setItem(this.DIM_AMOUNT_KEY, value);
|
||||
},
|
||||
|
||||
// Butterchurn preset cycle duration in seconds
|
||||
getButterchurnCycleDuration() {
|
||||
try {
|
||||
|
|
|
|||
6
js/ui.js
6
js/ui.js
|
|
@ -120,6 +120,12 @@ export class UIRenderer {
|
|||
window.addEventListener('theme-changed', () => {
|
||||
this.updateGlobalTheme();
|
||||
});
|
||||
|
||||
window.addEventListener('visualizer-dim-change', () => {
|
||||
if (this.visualizer) {
|
||||
this.visualizer.updateDimming();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Helper for Heart Icon
|
||||
|
|
|
|||
|
|
@ -51,6 +51,12 @@ export class Visualizer {
|
|||
this._resizeBound = () => this.resize();
|
||||
}
|
||||
|
||||
updateDimming() {
|
||||
if (!this.canvas || !this.canvas.parentElement) return;
|
||||
const dimAmount = visualizerSettings.getDimAmount();
|
||||
this.canvas.parentElement.style.opacity = dimAmount.toString();
|
||||
}
|
||||
|
||||
get activePreset() {
|
||||
return this.presets[this.activePresetKey] || this.presets['lcd'];
|
||||
}
|
||||
|
|
@ -150,6 +156,8 @@ export class Visualizer {
|
|||
this.audioContext.resume();
|
||||
}
|
||||
|
||||
this.updateDimming();
|
||||
|
||||
// Set canvas dimensions before preset init so WebGL framebuffers are created at correct size
|
||||
this.resize();
|
||||
window.addEventListener('resize', this._resizeBound);
|
||||
|
|
|
|||
10
styles.css
10
styles.css
|
|
@ -3483,13 +3483,21 @@ input:checked + .slider::before {
|
|||
transition: background-image var(--transition);
|
||||
}
|
||||
|
||||
#visualizer-canvas {
|
||||
#visualizer-container {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
pointer-events: none;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
#visualizer-canvas {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fullscreen-cover-content {
|
||||
|
|
|
|||
Loading…
Reference in a new issue