Add cursor-tracking card glare and accent-linked background blobs
- Subtle radial glare follows cursor over card/template-card elements using a single document-level mousemove listener (event delegation) - Ambient background blob colors now derive from the selected accent color with hue-shifted variants - Glare intensity kept very subtle (3.5% dark / 12% light theme) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,9 @@ import { Modal } from './core/modal.js';
|
||||
import { loadServerInfo, loadDisplays, configureApiKey, startConnectionMonitor, stopConnectionMonitor } from './core/api.js';
|
||||
import { t, initLocale, changeLocale } from './core/i18n.js';
|
||||
|
||||
// Layer 1.5: visual effects
|
||||
import { initCardGlare } from './core/card-glare.js';
|
||||
|
||||
// Layer 2: ui
|
||||
import {
|
||||
toggleHint, lockBody, unlockBody, closeLightbox,
|
||||
@@ -528,6 +531,9 @@ document.addEventListener('DOMContentLoaded', async () => {
|
||||
// Show content now that translations are loaded and tabs are set
|
||||
document.body.style.visibility = 'visible';
|
||||
|
||||
// Initialize card glare effect
|
||||
initCardGlare();
|
||||
|
||||
// Set CSS variable for sticky header height (header now includes tab bar)
|
||||
const headerEl = document.querySelector('header');
|
||||
if (headerEl) {
|
||||
|
||||
44
server/src/wled_controller/static/js/core/card-glare.js
Normal file
44
server/src/wled_controller/static/js/core/card-glare.js
Normal file
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Card glare effect — cursor-tracking spotlight on .card and .template-card elements.
|
||||
*
|
||||
* Uses a single document-level mousemove listener (event delegation) and
|
||||
* CSS custom properties (--glare-x, --glare-y) to position a radial gradient
|
||||
* overlay via the ::after pseudo-element defined in cards.css.
|
||||
*/
|
||||
|
||||
const CARD_SEL = '.card, .template-card';
|
||||
|
||||
let _active = null; // currently illuminated card element
|
||||
|
||||
function _onMove(e) {
|
||||
const card = e.target.closest(CARD_SEL);
|
||||
|
||||
if (card && !card.classList.contains('add-device-card')) {
|
||||
const rect = card.getBoundingClientRect();
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
card.style.setProperty('--glare-x', `${x}px`);
|
||||
card.style.setProperty('--glare-y', `${y}px`);
|
||||
|
||||
if (_active !== card) {
|
||||
if (_active) _active.classList.remove('card-glare');
|
||||
card.classList.add('card-glare');
|
||||
_active = card;
|
||||
}
|
||||
} else if (_active) {
|
||||
_active.classList.remove('card-glare');
|
||||
_active = null;
|
||||
}
|
||||
}
|
||||
|
||||
function _onLeave() {
|
||||
if (_active) {
|
||||
_active.classList.remove('card-glare');
|
||||
_active = null;
|
||||
}
|
||||
}
|
||||
|
||||
export function initCardGlare() {
|
||||
document.addEventListener('mousemove', _onMove, { passive: true });
|
||||
document.addEventListener('mouseleave', _onLeave);
|
||||
}
|
||||
Reference in New Issue
Block a user