feat(registry): polish Liquid Glass catalog blocks

This commit is contained in:
Miguel Ángel
2026-05-23 19:34:00 -04:00
parent eb7ca3c1c0
commit 3224a5d581
65 changed files with 2880 additions and 947 deletions
@@ -4,10 +4,6 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=1920, height=1080" />
<title>Liquid Glass Media Controls</title>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script src="lib/liquid-glass.iife.js"></script>
@@ -65,41 +61,41 @@
--lg-saturation: 0.25;
}
.search-panel {
width: 480px;
height: 56px;
--lg-corner-radius: 18;
width: 640px;
height: 72px;
--lg-corner-radius: 24;
}
.toggle-panel {
width: 480px;
height: 50px;
width: 640px;
height: 64px;
--lg-corner-radius: 44;
}
.media-panel {
width: 480px;
height: 88px;
width: 640px;
height: 116px;
--lg-corner-radius: 44;
}
.slider-panel {
width: 480px;
height: 58px;
--lg-corner-radius: 22;
width: 640px;
height: 76px;
--lg-corner-radius: 28;
}
#glass-search {
top: 400px;
left: 720px;
top: 300px;
left: 640px;
}
#glass-toggle {
top: 470px;
left: 720px;
top: 390px;
left: 640px;
}
#glass-media {
top: 534px;
left: 720px;
top: 476px;
left: 640px;
}
#glass-slider {
top: 636px;
left: 720px;
top: 616px;
left: 640px;
}
/* ── Text Overlays ── */
@@ -111,85 +107,131 @@
/* Search bar */
.search-text {
width: 480px;
height: 56px;
width: 640px;
height: 72px;
display: flex;
align-items: center;
gap: 12px;
padding: 0 20px;
gap: 16px;
padding: 0 28px;
background: #02040a;
border-radius: 24px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.search-text svg {
width: 18px;
height: 18px;
stroke: rgba(255, 255, 255, 0.45);
width: 22px;
height: 22px;
stroke: rgba(255, 255, 255, 0.86);
fill: none;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
flex-shrink: 0;
}
.search-text span {
font-size: 15px;
font-weight: 500;
color: rgba(255, 255, 255, 0.4);
.search-label {
font-size: 19px;
font-weight: 650;
color: #fff;
}
.search-caret {
width: 2px;
height: 25px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.82);
opacity: 0;
}
#text-search {
top: 400px;
left: 720px;
top: 300px;
left: 640px;
}
/* Toggle row */
.toggle-text {
width: 480px;
height: 50px;
width: 640px;
height: 64px;
display: flex;
align-items: center;
justify-content: center;
gap: 0;
position: relative;
padding: 6px;
background: rgba(5, 10, 20, 0.52);
border-radius: 44px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18);
}
.toggle-active-pill {
position: absolute;
top: 6px;
left: 6px;
z-index: 0;
width: 209px;
height: 52px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.16);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.22);
}
.toggle-item {
flex: 1;
position: relative;
z-index: 1;
text-align: center;
font-size: 13px;
font-weight: 600;
color: rgba(255, 255, 255, 0.45);
line-height: 50px;
font-size: 16px;
font-weight: 700;
color: rgba(255, 255, 255, 0.96);
line-height: 52px;
}
.toggle-item.active {
color: #fff;
background: rgba(255, 255, 255, 0.1);
border-radius: 44px;
}
#text-toggle {
top: 470px;
left: 720px;
top: 390px;
left: 640px;
}
/* Media pill */
.media-text {
width: 480px;
height: 88px;
width: 640px;
height: 116px;
display: flex;
align-items: center;
gap: 16px;
padding: 0 16px;
gap: 22px;
padding: 0 24px;
background: rgba(5, 10, 20, 0.56);
border-radius: 44px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.album-art {
width: 60px;
height: 60px;
border-radius: 14px;
background: linear-gradient(135deg, #6366f1, #ec4899);
position: relative;
overflow: hidden;
width: 78px;
height: 78px;
border-radius: 20px;
background:
radial-gradient(circle at 70% 28%, rgba(255, 255, 255, 0.78), transparent 16%),
conic-gradient(from 210deg, #06e3fa, #4fdb5e, #f59e0b, #ec4899, #06e3fa);
flex-shrink: 0;
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.28),
0 12px 26px rgba(0, 0, 0, 0.24);
}
.album-sheen {
position: absolute;
top: -10px;
left: -70px;
width: 38px;
height: 110px;
background: rgba(255, 255, 255, 0.34);
filter: blur(8px);
transform: rotate(24deg);
}
.media-info {
display: flex;
flex-direction: column;
gap: 2px;
gap: 7px;
flex: 1;
min-width: 0;
}
.media-title {
font-size: 15px;
font-size: 22px;
font-weight: 700;
color: #fff;
white-space: nowrap;
@@ -197,45 +239,72 @@
text-overflow: ellipsis;
}
.media-artist {
font-size: 13px;
font-weight: 500;
color: rgba(255, 255, 255, 0.5);
font-size: 16px;
font-weight: 600;
color: rgba(255, 255, 255, 0.84);
}
.media-meta-row {
display: flex;
align-items: center;
gap: 9px;
}
.live-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #4ade80;
box-shadow: 0 0 14px rgba(74, 222, 128, 0.76);
}
.sound-wave {
display: flex;
align-items: end;
gap: 3px;
height: 16px;
}
.sound-wave span {
width: 3px;
height: 7px;
border-radius: 999px;
background: rgba(255, 255, 255, 0.74);
}
.transport {
display: flex;
align-items: center;
gap: 18px;
gap: 24px;
margin-left: auto;
padding-right: 4px;
}
.transport svg {
width: 22px;
height: 22px;
width: 28px;
height: 28px;
fill: #fff;
stroke: none;
}
.transport .play-btn svg {
width: 30px;
height: 30px;
width: 38px;
height: 38px;
}
#text-media {
top: 534px;
left: 720px;
top: 476px;
left: 640px;
}
/* Brightness slider */
.slider-text {
width: 480px;
height: 58px;
width: 640px;
height: 76px;
display: flex;
align-items: center;
gap: 14px;
padding: 0 22px;
gap: 18px;
padding: 0 28px;
background: rgba(5, 10, 20, 0.56);
border-radius: 28px;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2);
}
.slider-text svg {
width: 20px;
height: 20px;
stroke: rgba(255, 255, 255, 0.6);
width: 26px;
height: 26px;
stroke: rgba(255, 255, 255, 0.88);
fill: none;
stroke-width: 2;
stroke-linecap: round;
@@ -244,31 +313,32 @@
}
.slider-track {
flex: 1;
height: 6px;
background: rgba(255, 255, 255, 0.12);
border-radius: 3px;
height: 8px;
background: rgba(255, 255, 255, 0.22);
border-radius: 4px;
position: relative;
}
.slider-fill {
position: absolute;
top: 0;
left: 0;
width: 68%;
width: 34%;
height: 100%;
background: #fff;
border-radius: 3px;
box-shadow: 0 0 14px rgba(255, 255, 255, 0.5);
}
.slider-pct {
font-size: 14px;
font-size: 17px;
font-weight: 600;
color: rgba(255, 255, 255, 0.7);
color: rgba(255, 255, 255, 0.9);
font-variant-numeric: tabular-nums;
width: 36px;
width: 42px;
text-align: right;
}
#text-slider {
top: 636px;
left: 720px;
top: 616px;
left: 640px;
}
</style>
</head>
@@ -297,11 +367,13 @@
<circle cx="11" cy="11" r="8" />
<line x1="21" y1="21" x2="16.65" y2="16.65" />
</svg>
<span>Search</span>
<span id="search-label" class="search-label">Search</span>
<span id="search-caret" class="search-caret"></span>
</div>
<!-- Toggle row -->
<div id="text-toggle" class="text-overlay toggle-text">
<div id="toggle-pill" class="toggle-active-pill"></div>
<div class="toggle-item active">All</div>
<div class="toggle-item">Favorites</div>
<div class="toggle-item">Recent</div>
@@ -309,10 +381,16 @@
<!-- Media pill -->
<div id="text-media" class="text-overlay media-text">
<div class="album-art"></div>
<div class="album-art"><span id="album-sheen" class="album-sheen"></span></div>
<div class="media-info">
<div class="media-title">Midnight Drive</div>
<div class="media-artist">Glass Resonance</div>
<div class="media-meta-row">
<span id="live-dot" class="live-dot"></span>
<div class="media-artist">Glass Resonance</div>
<div id="sound-wave" class="sound-wave">
<span></span><span></span><span></span><span></span>
</div>
</div>
</div>
<div class="transport">
<span>
@@ -346,8 +424,8 @@
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36" />
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22" />
</svg>
<div class="slider-track"><div class="slider-fill"></div></div>
<span class="slider-pct">68%</span>
<div class="slider-track"><div id="slider-fill" class="slider-fill"></div></div>
<span id="slider-pct" class="slider-pct">34%</span>
</div>
<div
@@ -450,8 +528,10 @@
var glassCanvas = document.getElementById("glass-canvas");
var ctx = glassCanvas.getContext("2d");
var lg = new LiquidGlass.LiquidGlassCanvas(glassCanvas);
var lgReady = false;
function renderGlass(time) {
if (!lgReady) return;
uniforms.uTime.value = time;
renderer.render(scene, camera);
ctx.clearRect(0, 0, W, H);
@@ -459,6 +539,23 @@
lg.renderGlassElements();
}
function requestGlassRender(time) {
if (glassCanvas.requestPaint) {
glassCanvas.onpaint = function () {
renderGlass(time);
};
glassCanvas.requestPaint();
return;
}
renderGlass(time);
}
lg.waitForInit().then(function (ok) {
if (!ok) return;
lgReady = true;
requestGlassRender(0);
});
/* ── GSAP Timeline ──────────────────────────────────────────────── */
window.__timelines = window.__timelines || {};
var tl = gsap.timeline({ paused: true });
@@ -471,99 +568,81 @@
var tt = document.getElementById("text-toggle");
var tm = document.getElementById("text-media");
var tsl = document.getElementById("text-slider");
var searchLabel = document.getElementById("search-label");
var sliderPct = document.getElementById("slider-pct");
var sliderValue = { value: 34 };
/* All panels start stacked at center */
var cx = 720,
cy = 496;
gsap.set([gs, ts, gt, tt, gm, tm, gsl, tsl], { top: 1160, opacity: 1 });
gsap.set("#sound-wave span", { height: 7 });
/* Search: drifts upper-left */
tl.fromTo(
[gs, ts],
{ left: cx, top: cy },
{ left: 180, top: 180, duration: 3, ease: "power2.out" },
0,
tl.to([gs, ts], { top: 300, duration: 0.48, ease: "power3.out" }, 0.12);
tl.to([gt, tt], { top: 390, duration: 0.44, ease: "power3.out" }, 0.22);
tl.to([gm, tm], { top: 476, duration: 0.44, ease: "power3.out" }, 0.32);
tl.to([gsl, tsl], { top: 616, duration: 0.46, ease: "power3.out" }, 0.42);
tl.call(
function () {
searchLabel.textContent = "Search Music";
},
null,
0.9,
);
tl.to(
[gs, ts],
{ left: 320, top: 260, duration: 5, ease: "sine.inOut", yoyo: true, repeat: 1 },
3,
"#search-caret",
{ opacity: 1, duration: 0.1, yoyo: true, repeat: 5, ease: "none" },
0.94,
);
tl.fromTo(
[gs, ts],
{ top: "+=0" },
{ top: "+=50", duration: 2.2, ease: "sine.inOut", yoyo: true, repeat: 2 },
1,
tl.call(
function () {
searchLabel.textContent = "Midnight Drive";
},
null,
1.55,
);
/* Toggle: drifts upper-right */
tl.fromTo(
[gt, tt],
{ left: cx, top: cy },
{ left: 1340, top: 220, duration: 3.2, ease: "back.out(1.2)" },
0,
tl.to("#toggle-pill", { left: 215, duration: 0.24, ease: "power2.out" }, 1.82);
tl.to(
".play-btn",
{ scale: 0.86, duration: 0.12, ease: "power2.out", yoyo: true, repeat: 1 },
2.18,
);
tl.to("#album-sheen", { left: 112, duration: 0.75, ease: "power2.out" }, 2.2);
tl.to(
"#sound-wave span",
{ height: 15, duration: 0.22, ease: "power2.inOut", stagger: 0.05, yoyo: true, repeat: 12 },
2.2,
);
tl.to(
[gt, tt],
{ left: 1200, top: 300, duration: 4.8, ease: "sine.inOut", yoyo: true, repeat: 1 },
3.2,
);
tl.fromTo(
[gt, tt],
{ top: "+=0" },
{ top: "+=40", duration: 1.9, ease: "sine.inOut", yoyo: true, repeat: 3 },
0.5,
);
/* Media: drifts lower-left */
tl.fromTo(
[gm, tm],
{ left: cx, top: cy },
{ left: 200, top: 740, duration: 2.8, ease: "expo.out" },
0,
sliderValue,
{
value: 82,
duration: 4.4,
ease: "none",
onUpdate: function () {
sliderPct.textContent = Math.round(sliderValue.value) + "%";
},
},
1.2,
);
tl.to("#slider-fill", { width: "82%", duration: 4.4, ease: "none" }, 1.2);
tl.to(
[gm, tm],
{ left: 400, top: 680, duration: 5.2, ease: "sine.inOut", yoyo: true, repeat: 1 },
2.8,
);
tl.fromTo(
[gm, tm],
{ top: "+=0" },
{ top: "+=55", duration: 2.5, ease: "sine.inOut", yoyo: true, repeat: 2 },
0.8,
"#live-dot",
{ scale: 1.45, duration: 0.24, ease: "power2.out", yoyo: true, repeat: 4 },
2.6,
);
tl.to("#toggle-pill", { left: 425, duration: 0.24, ease: "power2.out" }, 4.15);
/* Slider: drifts lower-right */
tl.fromTo(
[gsl, tsl],
{ left: cx, top: cy },
{ left: 1280, top: 800, duration: 3.5, ease: "circ.out" },
0,
);
tl.to(
[gsl, tsl],
{ left: 1100, top: 720, duration: 4.5, ease: "sine.inOut", yoyo: true, repeat: 1 },
3.5,
);
tl.fromTo(
[gsl, tsl],
{ top: "+=0" },
{ top: "+=45", duration: 2.0, ease: "sine.inOut", yoyo: true, repeat: 2 },
0.3,
);
var stack = [gs, ts, gt, tt, gm, tm, gsl, tsl];
tl.to(stack, { top: "-=8", duration: 0.22, ease: "power2.out", yoyo: true, repeat: 1 }, 5.55);
tl.to(stack, { top: "+=760", duration: 0.42, ease: "power2.in" }, 6.72);
/* Duration driver */
tl.to({ v: 0 }, { v: 1, duration: DURATION, ease: "none" }, 0);
tl.eventCallback("onUpdate", function () {
renderGlass(tl.time());
requestGlassRender(tl.time());
});
window.__timelines["liquid-glass-media-controls"] = tl;
setTimeout(function () {
renderGlass(0);
}, 0);
</script>
</body>
</html>
@@ -10,7 +10,7 @@
"height": 1080
},
"duration": 8,
"tags": ["liquid-glass-html-in-canvas", "webgpu"],
"tags": ["html-in-canvas", "liquid-glass-html-in-canvas", "webgpu"],
"files": [
{
"path": "liquid-glass-media-controls.html",