Design-Update 3: neue Liquid-Glass-Nav (bl-glass-distortion), Nav auf Design-Hoehe, Feed-Animationen
- Nav: Specular-Lighting-Glasfilter + Weiss-Layer rgba(255,255,255,.25) + Kanten-Ring + Aussenschatten; bottom:14px ohne Safe-Area-Aufschlag (= exakt die Hoehe aus BrandLoop.dc.html), Bounce-Transition - Fling: Top-Karte fadet aus (.3s), Stack rueckt mit Settle-Animation nach (.45s cubic-bezier(.22,1,.36,1)), 4 Karten im Stack, Snap-back weicher - Tab-Wechsel: Deck+Blur Crossfade (180ms), Hood animiert sofort - Blur-Layer: background .7s ease + opacity .25s ease - x-actions Abstand auf Design-Wert 84px Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -178,7 +178,8 @@
|
||||
#explore{padding:0; --xs:max(env(safe-area-inset-top, 0px), 64px);}
|
||||
#explore.active{display:flex; flex-direction:column; height:100dvh; overflow:hidden;}
|
||||
.x-blur{position:absolute; inset:-50px; pointer-events:none; z-index:0;
|
||||
filter:blur(36px) brightness(.78) saturate(1.15); transform:scale(1.08); transition:background .3s;}
|
||||
filter:blur(36px) brightness(.78) saturate(1.15); transform:scale(1.08);
|
||||
transition:background .7s ease, opacity .25s ease;}
|
||||
.x-hood{position:absolute; inset:0; pointer-events:none; z-index:2;}
|
||||
.x-hood svg{position:absolute; top:calc(var(--xs) - 14px); left:0; display:block; width:100%; height:120px;}
|
||||
.x-hood .solid{position:absolute; top:calc(var(--xs) + 105px); left:0; right:0; bottom:0; background:var(--bg);}
|
||||
@@ -216,7 +217,7 @@
|
||||
.x-empty{position:absolute; inset:0; border-radius:26px; background:#141414; border:1px dashed rgba(255,255,255,.15);
|
||||
display:flex; flex-direction:column; align-items:center; justify-content:center; gap:14px;}
|
||||
.x-actions{position:relative; z-index:3; display:flex; justify-content:center; align-items:center; gap:22px;
|
||||
padding:6px 0 calc(96px + env(safe-area-inset-bottom));}
|
||||
padding:6px 0 84px;}
|
||||
.x-act{width:56px; height:56px; border-radius:100px; background:rgba(255,255,255,.08); border:1px solid rgba(255,255,255,.12);
|
||||
display:grid; place-items:center; cursor:pointer; font-size:20px; color:rgba(255,255,255,.8); transition:transform .12s;}
|
||||
.x-act:active{transform:scale(.92);}
|
||||
@@ -251,21 +252,19 @@
|
||||
.p-hero p{color:var(--mut); font-size:13px; margin-top:3px;}
|
||||
|
||||
/* ================= Bottom-Navigation ================= */
|
||||
/* Liquid-Glass-Nav (aus BrandLoop.dc.html): Turbulenz-Filter als backdrop,
|
||||
blur(20px) als Fallback falls der Browser url()-backdrop-filter nicht kann */
|
||||
/* Liquid-Glass-Nav (aus BrandLoop.dc.html): verzerrter Glas-Backdrop
|
||||
(bl-glass-distortion mit Specular-Highlight) + heller Weiss-Layer + Kanten-Ring.
|
||||
bottom:14px OHNE Safe-Area-Aufschlag = exakt die Hoehe aus dem Design. */
|
||||
.nav{position:fixed; bottom:14px; left:50%; transform:translateX(-50%); z-index:30;
|
||||
display:flex; align-items:center; gap:6px; padding:8px 10px; border-radius:100px;
|
||||
margin-bottom:env(safe-area-inset-bottom);}
|
||||
.nav::before{content:''; position:absolute; inset:0; z-index:-1; border-radius:100px;
|
||||
background:rgba(10,10,10,.18);
|
||||
-webkit-backdrop-filter:blur(20px); backdrop-filter:blur(20px);
|
||||
-webkit-backdrop-filter:url(#bl-liquid-glass); backdrop-filter:url(#bl-liquid-glass);}
|
||||
background:rgba(255,255,255,.25);
|
||||
box-shadow:0 6px 6px rgba(0,0,0,.2), 0 0 20px rgba(0,0,0,.1);
|
||||
transition:all .7s cubic-bezier(.175,.885,.32,2.2);}
|
||||
.nav::before{content:''; position:absolute; inset:0; z-index:-1; border-radius:100px; overflow:hidden;
|
||||
-webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
|
||||
filter:url(#bl-glass-distortion); isolation:isolate;}
|
||||
.nav::after{content:''; position:absolute; inset:0; z-index:2; border-radius:100px; pointer-events:none;
|
||||
box-shadow:0 0 8px rgba(0,0,0,.03), 0 2px 6px rgba(0,0,0,.08),
|
||||
inset 3px 3px .5px -3.5px rgba(255,255,255,.09), inset -3px -3px .5px -3.5px rgba(255,255,255,.85),
|
||||
inset 1px 1px 1px -.5px rgba(255,255,255,.6), inset -1px -1px 1px -.5px rgba(255,255,255,.6),
|
||||
inset 0 0 6px 6px rgba(255,255,255,.12), inset 0 0 2px 2px rgba(255,255,255,.06),
|
||||
0 0 12px rgba(0,0,0,.15);}
|
||||
box-shadow:inset 2px 2px 1px 0 rgba(255,255,255,.5), inset -1px -1px 1px 1px rgba(255,255,255,.5);}
|
||||
.nav button{display:flex; align-items:center; gap:8px; background:none; border:none; font-family:inherit;
|
||||
width:40px; height:40px; justify-content:center; border-radius:100px; color:rgba(255,255,255,.6);
|
||||
font-size:13.5px; font-weight:600; cursor:pointer; transition:background .2s, color .2s, width .2s;}
|
||||
@@ -299,12 +298,19 @@
|
||||
<!-- Lucide-Icon-Sprite + Liquid-Glass-Filter -->
|
||||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||||
<defs>
|
||||
<filter id="bl-liquid-glass" x="0%" y="0%" width="100%" height="100%" color-interpolation-filters="sRGB">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.05 0.05" numOctaves="1" seed="1" result="turbulence"/>
|
||||
<feGaussianBlur in="turbulence" stdDeviation="2" result="blurredNoise"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="blurredNoise" scale="70" xChannelSelector="R" yChannelSelector="B" result="displaced"/>
|
||||
<feGaussianBlur in="displaced" stdDeviation="4" result="finalBlur"/>
|
||||
<feComposite in="finalBlur" in2="finalBlur" operator="over"/>
|
||||
<filter id="bl-glass-distortion" x="0%" y="0%" width="100%" height="100%" filterUnits="objectBoundingBox">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.001 0.005" numOctaves="1" seed="17" result="turbulence"/>
|
||||
<feComponentTransfer in="turbulence" result="mapped">
|
||||
<feFuncR type="gamma" amplitude="1" exponent="10" offset="0.5"/>
|
||||
<feFuncG type="gamma" amplitude="0" exponent="1" offset="0"/>
|
||||
<feFuncB type="gamma" amplitude="0" exponent="1" offset="0.5"/>
|
||||
</feComponentTransfer>
|
||||
<feGaussianBlur in="turbulence" stdDeviation="3" result="softMap"/>
|
||||
<feSpecularLighting in="softMap" surfaceScale="5" specularConstant="1" specularExponent="100" lighting-color="white" result="specLight">
|
||||
<fePointLight x="-200" y="-200" z="300"/>
|
||||
</feSpecularLighting>
|
||||
<feComposite in="specLight" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litImage"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="softMap" scale="200" xChannelSelector="R" yChannelSelector="G"/>
|
||||
</filter>
|
||||
<symbol id="i-back" viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></symbol>
|
||||
<symbol id="i-chev" viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></symbol>
|
||||
@@ -1002,7 +1008,12 @@ function renderBlur(){
|
||||
}
|
||||
function esc(s){ return s.replace(/&/g,'&').replace(/</g,'<'); }
|
||||
|
||||
function renderDeck(){
|
||||
function cardTransform(depth){
|
||||
return depth===0 ? 'translateX(0px) rotate(0deg)' : 'scale('+(1-depth*.06)+') translateY('+(-depth*34)+'px)';
|
||||
}
|
||||
/* settle=true: Karten starten eine Position tiefer und gleiten nach vorn
|
||||
(Nachrueck-Animation aus dem Design nach Fling/Tab-Wechsel) */
|
||||
function renderDeck(settle){
|
||||
var host=document.getElementById('xDeck');
|
||||
var d=deck();
|
||||
renderBlur();
|
||||
@@ -1017,16 +1028,17 @@ function renderDeck(){
|
||||
return;
|
||||
}
|
||||
var html='';
|
||||
var slice=d.slice(X.idx, X.idx+3);
|
||||
var slice=d.slice(X.idx, X.idx+4);
|
||||
for(var i=slice.length-1; i>=0; i--){
|
||||
var p=slice[i], top=(i===0);
|
||||
var imgI=top?Math.min(X.imgIdx,p.imgs.length-1):0;
|
||||
var u=pic(p,imgI);
|
||||
var hue=p.h+imgI*25;
|
||||
var tf=top
|
||||
var depth=settle?i+1:i;
|
||||
var tf=(top&&!settle)
|
||||
? 'translateX('+X.dx+'px) rotate('+(X.dx/22)+'deg)'
|
||||
: 'scale('+(1-i*.06)+') translateY('+(-i*34)+'px)';
|
||||
html+='<div class="x-card'+(top?' top':'')+'" data-i="'+i+'" style="z-index:'+(4-i)+'; transform:'+tf+'; transition:transform .28s ease; cursor:'+(top?'grab':'default')+';">';
|
||||
: cardTransform(depth);
|
||||
html+='<div class="x-card'+(top?' top':'')+'" data-i="'+i+'" style="z-index:'+(5-i)+'; transform:'+tf+'; transition:'+(settle?'none':'transform .45s cubic-bezier(.22,1,.36,1)')+'; cursor:'+(top?'grab':'default')+';">';
|
||||
var bg=u ? '#141414 url("'+u+'") center / cover no-repeat' : dummy(hue);
|
||||
html+='<div class="img" style="background:'+bg+';'+(top?'':' filter:brightness(.85);')+'"></div>';
|
||||
if(top){
|
||||
@@ -1054,6 +1066,14 @@ function renderDeck(){
|
||||
host.innerHTML=html;
|
||||
var topEl=host.querySelector('.x-card.top');
|
||||
if(topEl) topEl.addEventListener('pointerdown', onDown);
|
||||
if(settle){
|
||||
requestAnimationFrame(function(){ requestAnimationFrame(function(){
|
||||
host.querySelectorAll('.x-card').forEach(function(el){
|
||||
el.style.transition='transform .45s cubic-bezier(.22,1,.36,1)';
|
||||
el.style.transform=cardTransform(+el.dataset.i);
|
||||
});
|
||||
});});
|
||||
}
|
||||
}
|
||||
|
||||
function fling(dir){
|
||||
@@ -1062,14 +1082,15 @@ function fling(dir){
|
||||
X.anim=true;
|
||||
var topEl=document.querySelector('#xDeck .x-card.top');
|
||||
if(topEl){
|
||||
topEl.style.transition='transform .28s ease';
|
||||
topEl.style.transition='transform .3s cubic-bezier(.4,0,.7,1), opacity .3s ease';
|
||||
topEl.style.transform='translateX('+(dir*640)+'px) rotate('+(dir*640/22)+'deg)';
|
||||
topEl.style.opacity='0';
|
||||
}
|
||||
setTimeout(function(){
|
||||
if(dir>0 && post) X.liked.push(post.id);
|
||||
X.idx++; X.dx=0; X.imgIdx=0; X.anim=false;
|
||||
renderDeck();
|
||||
},280);
|
||||
renderDeck(true);
|
||||
},300);
|
||||
}
|
||||
|
||||
function onDown(e){
|
||||
@@ -1093,7 +1114,7 @@ function onDown(e){
|
||||
var d=ev.clientX-sx;
|
||||
if(Math.abs(d)>110){ fling(d>0?1:-1); return; }
|
||||
X.dx=0;
|
||||
topEl.style.transition='transform .28s ease';
|
||||
topEl.style.transition='transform .45s cubic-bezier(.22,1,.36,1)';
|
||||
topEl.style.transform='translateX(0) rotate(0)';
|
||||
if(likeB) likeB.style.opacity=0;
|
||||
if(skipB) skipB.style.opacity=0;
|
||||
@@ -1108,8 +1129,17 @@ function onDown(e){
|
||||
|
||||
document.querySelectorAll('.x-tab').forEach(function(el){
|
||||
el.addEventListener('click',function(){
|
||||
X.tab=el.dataset.tab; X.idx=0; X.dx=0; X.imgIdx=0;
|
||||
renderTabs(); renderDeck(); animateHood(centerOf(X.tab), halfOf(X.tab));
|
||||
if(X.tab===el.dataset.tab) return;
|
||||
var k=el.dataset.tab;
|
||||
var deckEl=document.getElementById('xDeck'), blurEl=document.getElementById('xBlur');
|
||||
animateHood(centerOf(k), halfOf(k));
|
||||
deckEl.style.transition='opacity .18s ease';
|
||||
deckEl.style.opacity='0'; blurEl.style.opacity='0';
|
||||
setTimeout(function(){
|
||||
X.tab=k; X.idx=0; X.dx=0; X.imgIdx=0;
|
||||
renderTabs(); renderDeck(true);
|
||||
deckEl.style.opacity='1'; blurEl.style.opacity='1';
|
||||
},180);
|
||||
});
|
||||
});
|
||||
window.addEventListener('resize',function(){
|
||||
|
||||
Reference in New Issue
Block a user