Add dynamic mouse-tracking liquid glass effect (JS + CSS)

Co-authored-by: orange-cpp <59374393+orange-cpp@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-02-07 01:26:14 +00:00
parent e9c2ea7e47
commit 4ba5355837
3 changed files with 146 additions and 1 deletions

View File

@@ -0,0 +1,76 @@
/**
* Dynamic Liquid Glass — mouse-tracking specular highlight
*
* Creates a radial-gradient light spot that follows the cursor across
* glass-styled elements, giving them an interactive "liquid glass"
* refraction/reflection feel inspired by Apple's Liquid Glass design.
*/
(function () {
"use strict";
var SELECTORS = [
".md-header",
".md-content",
".md-sidebar__scrollwrap",
".highlight",
".md-search__form",
".md-footer"
];
/** Apply the radial highlight via CSS custom properties. */
function applyHighlight(el, x, y) {
var rect = el.getBoundingClientRect();
var px = x - rect.left;
var py = y - rect.top;
el.style.setProperty("--glass-x", px + "px");
el.style.setProperty("--glass-y", py + "px");
el.classList.add("glass-active");
}
function clearHighlight(el) {
el.classList.remove("glass-active");
}
/** Bind events once the DOM is ready. */
function init() {
var elements = [];
SELECTORS.forEach(function (sel) {
var nodes = document.querySelectorAll(sel);
for (var i = 0; i < nodes.length; i++) {
elements.push(nodes[i]);
}
});
var ticking = false;
document.addEventListener("mousemove", function (e) {
if (ticking) return;
ticking = true;
requestAnimationFrame(function () {
elements.forEach(function (el) {
var rect = el.getBoundingClientRect();
if (
e.clientX >= rect.left &&
e.clientX <= rect.right &&
e.clientY >= rect.top &&
e.clientY <= rect.bottom
) {
applyHighlight(el, e.clientX, e.clientY);
} else {
clearHighlight(el);
}
});
ticking = false;
});
});
document.addEventListener("mouseleave", function () {
elements.forEach(clearHighlight);
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();

View File

@@ -177,3 +177,70 @@
.md-typeset img { .md-typeset img {
border-radius: 10px; border-radius: 10px;
} }
/* ============================================================
Dynamic Liquid Glass — mouse-tracking specular highlight
============================================================ */
/* Shared: every glass surface gets a hidden radial-light overlay
that becomes visible when JS adds the .glass-active class and
sets --glass-x / --glass-y custom properties. */
.md-header,
.md-content,
.md-sidebar__scrollwrap,
.highlight,
.md-search__form,
.md-footer {
position: relative;
overflow: hidden;
}
.md-header::after,
.md-content::after,
.md-sidebar__scrollwrap::after,
.highlight::after,
.md-search__form::after,
.md-footer::after {
content: "";
position: absolute;
inset: 0;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s ease;
background: radial-gradient(
circle 220px at var(--glass-x, 50%) var(--glass-y, 50%),
rgba(255, 200, 120, 0.10) 0%,
rgba(255, 152, 0, 0.04) 40%,
transparent 70%
);
z-index: 1;
}
.md-header.glass-active::after,
.md-content.glass-active::after,
.md-sidebar__scrollwrap.glass-active::after,
.highlight.glass-active::after,
.md-search__form.glass-active::after,
.md-footer.glass-active::after {
opacity: 1;
}
/* Keep header text / nav icons above the overlay */
.md-header > *,
.md-content > *,
.md-sidebar__scrollwrap > *,
.md-search__form > *,
.md-footer > * {
position: relative;
z-index: 2;
}
/* Highlight code blocks get a slightly brighter spot */
.highlight.glass-active::after {
background: radial-gradient(
circle 180px at var(--glass-x, 50%) var(--glass-y, 50%),
rgba(255, 200, 120, 0.12) 0%,
rgba(255, 152, 0, 0.05) 35%,
transparent 65%
);
}

View File

@@ -14,4 +14,6 @@ markdown_extensions:
extra_css: extra_css:
- styles/fonts.css - styles/fonts.css
- styles/center.css - styles/center.css
- styles/liquid-glass.css - styles/liquid-glass.css
extra_javascript:
- javascripts/liquid-glass.js