forked from UniverseBow/wa2k.com-Website
navigation bar finished
This commit is contained in:
parent
63a3fda67c
commit
b22976bf85
2 changed files with 70 additions and 51 deletions
|
|
@ -11,28 +11,18 @@
|
||||||
<img src="banner.png" alt="banner" />
|
<img src="banner.png" alt="banner" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- SVG filter definition — hidden, just provides the filter for Chrome -->
|
|
||||||
<svg id="liquid-glass-svg" xmlns="http://www.w3.org/2000/svg" style="position:absolute;width:0;height:0;overflow:hidden;">
|
<svg id="liquid-glass-svg" xmlns="http://www.w3.org/2000/svg" style="position:absolute;width:0;height:0;overflow:hidden;">
|
||||||
<defs>
|
<defs>
|
||||||
|
|
||||||
<filter id="liquid-glass-nav" x="0" y="0" width="100%" height="100%" color-interpolation-filters="sRGB">
|
<filter id="liquid-glass-nav" x="0" y="0" width="100%" height="100%" color-interpolation-filters="sRGB">
|
||||||
<feImage id="nav-disp-img" result="disp_map" />
|
<feImage id="nav-disp-img" result="disp_map" />
|
||||||
<feDisplacementMap in="SourceGraphic" in2="disp_map" id="nav-disp-filter" xChannelSelector="R" yChannelSelector="G" result="refracted" />
|
<feDisplacementMap in="SourceGraphic" in2="disp_map" id="nav-disp-filter" xChannelSelector="R" yChannelSelector="G" result="refracted" />
|
||||||
<feImage id="nav-spec-img" result="spec_map" />
|
<feImage id="nav-spec-img" result="spec_map" />
|
||||||
<feBlend in="refracted" in2="spec_map" mode="screen" result="with_specular" />
|
<feBlend in="refracted" in2="spec_map" mode="screen" result="with_specular" />
|
||||||
<feComposite in="with_specular" in2="SourceGraphic" operator="atop" />
|
<feComposite in="with_specular" in2="SourceGraphic" operator="atop" />
|
||||||
</filter>
|
</filter>
|
||||||
|
|
||||||
<filter id="liquid-glass" x="0" y="0" width="100%" height="100%" color-interpolation-filters="sRGB">
|
<filter id="liquid-glass" x="0" y="0" width="100%" height="100%" color-interpolation-filters="sRGB">
|
||||||
<feImage id="displacement-map-img" result="disp_map" />
|
<feImage id="displacement-map-img" result="disp_map" />
|
||||||
<feDisplacementMap
|
<feDisplacementMap in="SourceGraphic" in2="disp_map" id="displacement-map-filter" xChannelSelector="R" yChannelSelector="G" result="refracted" />
|
||||||
in="SourceGraphic"
|
|
||||||
in2="disp_map"
|
|
||||||
id="displacement-map-filter"
|
|
||||||
xChannelSelector="R"
|
|
||||||
yChannelSelector="G"
|
|
||||||
result="refracted"
|
|
||||||
/>
|
|
||||||
<feImage id="specular-map-img" result="spec_map" />
|
<feImage id="specular-map-img" result="spec_map" />
|
||||||
<feBlend in="refracted" in2="spec_map" mode="screen" result="with_specular" />
|
<feBlend in="refracted" in2="spec_map" mode="screen" result="with_specular" />
|
||||||
<feComposite in="with_specular" in2="SourceGraphic" operator="atop" />
|
<feComposite in="with_specular" in2="SourceGraphic" operator="atop" />
|
||||||
|
|
@ -287,9 +277,15 @@ function applyLiquidGlass() {
|
||||||
|
|
||||||
// ─── Nav glass ────────────────────────────────────────────────────────────────
|
// ─── Nav glass ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
const NAV_TRANSITION_MS = 300; // Must match CSS transition duration
|
// Phase durations in ms — keep in sync with CSS transitions
|
||||||
|
const OPEN_WIDTH_MS = 250; // width/radius expand duration
|
||||||
|
const OPEN_DROPDOWN_MS = 300; // dropdown slide-down duration
|
||||||
|
const OPEN_DROPDOWN_DELAY = 220; // CSS delay before dropdown opens
|
||||||
|
const CLOSE_DROPDOWN_MS = 200; // dropdown collapse duration (no CSS delay)
|
||||||
|
const CLOSE_WIDTH_MS = 250; // width/radius collapse duration
|
||||||
|
const CLOSE_WIDTH_DELAY = 200; // wait for dropdown to finish before collapsing width
|
||||||
|
|
||||||
// Build and apply nav glass maps at a specific border-radius value
|
// Build and apply nav glass maps at a specific border-radius
|
||||||
function applyNavGlassAt(radius) {
|
function applyNavGlassAt(radius) {
|
||||||
const pill = document.getElementById('nav-pill');
|
const pill = document.getElementById('nav-pill');
|
||||||
const w = pill.offsetWidth;
|
const w = pill.offsetWidth;
|
||||||
|
|
@ -326,18 +322,13 @@ function applyNavGlassAt(radius) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rebuild maps across the transition so refraction tracks the shape live
|
// Animate refraction maps across a time window
|
||||||
function animateNavGlass(startRadius, targetRadius) {
|
function scheduleNavGlassFrames(startRadius, targetRadius, delayMs, durationMs, steps = 14) {
|
||||||
const steps = 12;
|
|
||||||
const interval = NAV_TRANSITION_MS / steps;
|
|
||||||
|
|
||||||
for (let i = 1; i <= steps; i++) {
|
for (let i = 1; i <= steps; i++) {
|
||||||
setTimeout(() => {
|
const t = i / steps;
|
||||||
const progress = i / steps;
|
const eased = 1 - Math.pow(1 - t, 3);
|
||||||
const eased = 1 - Math.pow(1 - progress, 3); // ease-out cubic
|
const radius = startRadius + (targetRadius - startRadius) * eased;
|
||||||
const radius = startRadius + (targetRadius - startRadius) * eased;
|
setTimeout(() => applyNavGlassAt(radius), delayMs + t * durationMs);
|
||||||
applyNavGlassAt(radius);
|
|
||||||
}, i * interval);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -369,14 +360,31 @@ const navBar = document.getElementById('nav-pill-bar');
|
||||||
navBar.addEventListener('click', () => {
|
navBar.addEventListener('click', () => {
|
||||||
const opening = !navPill.classList.contains('open');
|
const opening = !navPill.classList.contains('open');
|
||||||
navPill.classList.toggle('open');
|
navPill.classList.toggle('open');
|
||||||
// 999 = collapsed pill, 22 = expanded rounded rect (must match CSS)
|
|
||||||
animateNavGlass(opening ? 999 : 22, opening ? 22 : 999);
|
if (opening) {
|
||||||
|
// Phase 1: width expands (0 → OPEN_WIDTH_MS)
|
||||||
|
scheduleNavGlassFrames(999, 25, 0, OPEN_WIDTH_MS);
|
||||||
|
// Phase 2: dropdown falls (OPEN_DROPDOWN_DELAY → +OPEN_DROPDOWN_MS)
|
||||||
|
// refraction height grows as the pill gets taller — track it live
|
||||||
|
scheduleNavGlassFrames(25, 25, OPEN_DROPDOWN_DELAY, OPEN_DROPDOWN_MS);
|
||||||
|
// Final settle
|
||||||
|
setTimeout(applyNavGlass, OPEN_DROPDOWN_DELAY + OPEN_DROPDOWN_MS + 50);
|
||||||
|
} else {
|
||||||
|
// Phase 1: dropdown collapses (0 → CLOSE_DROPDOWN_MS)
|
||||||
|
scheduleNavGlassFrames(25, 25, 0, CLOSE_DROPDOWN_MS);
|
||||||
|
// Phase 2: width shrinks after dropdown finishes
|
||||||
|
scheduleNavGlassFrames(25, 999, CLOSE_WIDTH_DELAY, CLOSE_WIDTH_MS);
|
||||||
|
// Final settle
|
||||||
|
setTimeout(applyNavGlass, CLOSE_WIDTH_DELAY + CLOSE_WIDTH_MS + 50);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.addEventListener('click', (e) => {
|
document.addEventListener('click', (e) => {
|
||||||
if (!navPill.contains(e.target) && navPill.classList.contains('open')) {
|
if (!navPill.contains(e.target) && navPill.classList.contains('open')) {
|
||||||
navPill.classList.remove('open');
|
navPill.classList.remove('open');
|
||||||
animateNavGlass(22, 999);
|
scheduleNavGlassFrames(25, 25, 0, CLOSE_DROPDOWN_MS);
|
||||||
|
scheduleNavGlassFrames(25, 999, CLOSE_WIDTH_DELAY, CLOSE_WIDTH_MS);
|
||||||
|
setTimeout(applyNavGlass, CLOSE_WIDTH_DELAY + CLOSE_WIDTH_MS + 50);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ body {
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner {
|
.banner {
|
||||||
width: 70%;
|
width: 99%;
|
||||||
max-height: 280px;
|
max-height: 280px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin: 5px 5px 10px 5px; /* 5px on top/left/right, 10px on bottom */
|
margin: 5px 5px 10px 5px; /* 5px on top/left/right, 10px on bottom */
|
||||||
|
|
@ -128,8 +128,8 @@ p {
|
||||||
inset 1px 1px 0 rgba(255, 255, 255, 0.45),
|
inset 1px 1px 0 rgba(255, 255, 255, 0.45),
|
||||||
inset -1px -1px 0 rgba(0, 0, 0, 0.10);
|
inset -1px -1px 0 rgba(0, 0, 0, 0.10);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
border-radius 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
border-radius 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Pill expands and corners soften when open ── */
|
/* ── Pill expands and corners soften when open ── */
|
||||||
|
|
@ -173,8 +173,9 @@ p {
|
||||||
max-height: 0;
|
max-height: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),
|
/* Opening: wait for width to finish first, then drop down */
|
||||||
opacity 0.2s ease;
|
transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1) 0.22s,
|
||||||
|
opacity 0.25s ease 0.22s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-pill.open .nav-dropdown {
|
.nav-pill.open .nav-dropdown {
|
||||||
|
|
@ -182,6 +183,18 @@ p {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Closing: dropdown collapses immediately (no delay), width waits after */
|
||||||
|
.nav-pill:not(.open) .nav-dropdown {
|
||||||
|
transition: max-height 0.2s cubic-bezier(0.4, 0, 0.2, 1),
|
||||||
|
opacity 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Width/radius collapse waits for dropdown to finish */
|
||||||
|
.nav-pill:not(.open) {
|
||||||
|
transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1) 0.2s,
|
||||||
|
border-radius 0.25s cubic-bezier(0.4, 0, 0.2, 1) 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
.nav-divider {
|
.nav-divider {
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background: rgba(255, 255, 255, 0.12);
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
|
@ -193,8 +206,7 @@ p {
|
||||||
padding: 11px 18px;
|
padding: 11px 18px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
text-align: center;
|
color: rgba(255, 255, 255, 0.70);
|
||||||
color: rgba(2, 2, 5, 1);
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.15s ease,
|
transition: color 0.15s ease,
|
||||||
background 0.15s ease;
|
background 0.15s ease;
|
||||||
|
|
@ -204,4 +216,3 @@ p {
|
||||||
color: rgba(255, 255, 255, 0.95);
|
color: rgba(255, 255, 255, 0.95);
|
||||||
background: rgba(255, 255, 255, 0.06);
|
background: rgba(255, 255, 255, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue