7 KiB
7 KiB
光湖 UI 实现模式(代码范式)
已验证落地的实现范式。色值为当前落地取样,精确色板随版本演进;形态铁律不变: 碎光 + 雾光 + 玻璃浮面;禁机械线形、禁纯黑、禁彩虹。
1 · 色板 token(光湖·湖面映星)
:root{
--ink-0:#04060d; /* 底:极深蓝紫黑,禁纯黑 */
--ink-1:#080c1c;
--ink-2:#0d1230;
--star:#f2ead6; /* 主光:淡金白星光 */
--gold:#e6c88a; /* 唯一强调色 */
--gold-hi:#f5e3b8;
--nebula-a:rgba(94,106,222,.16); /* 蓝紫星云 */
--nebula-b:rgba(148,118,235,.12);
--text-hi:rgba(241,243,252,.96); /* 透明度宁高勿低 */
--text-mid:rgba(218,224,246,.82);
--text-low:rgba(202,210,234,.6);
--glass:rgba(13,18,42,.44); /* 玻璃浮面:必须半透明 */
--glass-brd:rgba(188,204,255,.15);
--glass-brd-hi:rgba(230,200,138,.34);
}
字体:系统无衬线中文栈;正文 ≥14.5px/字重 500 起,辅助 ≥12px,标题 600–700。
2 · 碎光星野(canvas,全页连续背景)
密度随视口,近湖心(下方中央)偏暖金;prefers-reduced-motion 时静止。
const canvas = document.getElementById('star-canvas');
const ctx = canvas.getContext('2d');
let W,H,stars=[];
function resize(){
W = canvas.width = innerWidth*devicePixelRatio;
H = canvas.height = innerHeight*devicePixelRatio;
seed();
}
function seed(){
const n = Math.min(200, Math.floor(innerWidth*innerHeight/9000));
stars = Array.from({length:n},()=>{
const x=Math.random()*W, y=Math.random()*H;
const d = Math.hypot(x-W/2, y-H*0.92)/Math.hypot(W/2,H*0.92);
const warm = Math.max(0,1-d)>.5 && Math.random()<.55;
return {x,y,r:(Math.random()*1.2+.4)*devicePixelRatio,
base:.25+Math.random()*.5, amp:.2+Math.random()*.5,
sp:.4+Math.random()*1.1, ph:Math.random()*6.28, warm};
});
}
function tick(t){
ctx.clearRect(0,0,W,H);
for(const s of stars){
const tw = Math.sin(t/1000*s.sp+s.ph)*.5+.5;
ctx.beginPath(); ctx.arc(s.x,s.y,s.r,0,6.283);
ctx.fillStyle = s.warm?`rgba(238,214,160,${s.base+s.amp*tw})`
:`rgba(226,232,252,${s.base+s.amp*tw})`;
ctx.shadowColor = s.warm?'rgba(230,200,138,.8)':'rgba(180,196,255,.7)';
ctx.shadowBlur = s.r*4; ctx.fill();
}
ctx.shadowBlur=0; requestAnimationFrame(tick);
}
resize(); addEventListener('resize',resize); requestAnimationFrame(tick);
DOM 版(轻量场景):JS 随机约 120 粒 .glint 碎光,CSS twinkle 闪烁(近湖心偏暖金)+ 大片 blur 柔光 glide 缓移。
3 · 雾光漂移(星云层)
2–3 片超大径向渐变 + blur(60–70px),60–110s 缓移往返。禁硬边形状。
.mist{position:fixed;border-radius:50%;filter:blur(70px);pointer-events:none;z-index:0}
.mist-a{width:64vw;height:64vw;left:-14vw;top:-22vh;
background:radial-gradient(closest-side,rgba(94,106,222,.16),transparent 72%);
animation:drift 84s ease-in-out infinite alternate}
@keyframes drift{from{transform:translate3d(0,0,0) scale(1)}
to{transform:translate3d(6vw,4vh,0) scale(1.12)}}
4 · 玻璃浮面(内容容器,替代卡片盒)
半透明 + 背景模糊 + 细边 + 顶部内高光 + 指针跟随辉光。禁不透明深色盒子。
.glass{
background:linear-gradient(158deg,rgba(24,32,66,.5),rgba(13,18,42,.44) 58%,rgba(10,14,34,.36));
border:1px solid rgba(188,204,255,.15);
border-radius:20px;
backdrop-filter:blur(22px) saturate(1.25);
box-shadow:0 22px 60px rgba(2,4,12,.5),inset 0 1px 0 rgba(220,230,255,.09);
position:relative;overflow:hidden;
}
.glass::before{ /* 指针跟随辉光 */
content:"";position:absolute;inset:0;pointer-events:none;
background:radial-gradient(420px circle at var(--glow-x,50%) var(--glow-y,0%),rgba(230,200,138,.08),transparent 62%);
opacity:0;transition:opacity .5s;
}
.glass:hover::before{opacity:1}
document.querySelectorAll('.glass').forEach(s=>{
s.addEventListener('pointermove',e=>{
const r=s.getBoundingClientRect();
s.style.setProperty('--glow-x',((e.clientX-r.left)/r.width*100)+'%');
s.style.setProperty('--glow-y',((e.clientY-r.top)/r.height*100)+'%');
},{passive:true});
});
5 · 柔光自转天体(星球/域)
三层结构:光晕(呼吸)+ 表面(发光渐变、边缘融入太空,内层雾化纹理旋转)+ 环绕碎星。 禁硬高光点、禁暗边、禁 drop-shadow 立体感 —— 那是塑料感的来源。
<span class="sphere d-gold"><i class="halo"></i><i class="surf"></i>
<i class="spark s1"></i><i class="spark s2"></i></span>
.sphere{width:clamp(90px,9.5vw,124px);height:clamp(90px,9.5vw,124px);
position:relative;border-radius:50%;animation:orb-float 8.4s ease-in-out infinite}
.halo{position:absolute;inset:-34px;border-radius:50%;
background:radial-gradient(circle,var(--p-halo),transparent 64%);
animation:halo-pulse 6.4s ease-in-out infinite}
.surf{position:absolute;inset:0;border-radius:50%;overflow:hidden;
background:radial-gradient(circle at 50% 44%,var(--p-hi),var(--p-mid) 38%,var(--p-lo) 62%,transparent 76%)}
.surf::before{content:"";position:absolute;inset:-30%;filter:blur(6px);opacity:.5;
background:radial-gradient(closest-side at 32% 44%,var(--p-band),transparent 60%),
radial-gradient(closest-side at 70% 60%,var(--p-band2),transparent 55%);
animation:surface-spin var(--spin,28s) linear infinite}
.spark{position:absolute;width:3px;height:3px;border-radius:50%;
background:rgba(242,234,214,.92);box-shadow:0 0 8px rgba(242,234,214,.85);
animation:spark-tw 3.6s ease-in-out infinite}
@keyframes surface-spin{to{transform:rotate(360deg)}}
@keyframes orb-float{50%{transform:translateY(-13px)}}
@keyframes halo-pulse{50%{opacity:1;transform:scale(1.08)}}
@keyframes spark-tw{50%{opacity:.95}}
/* 每颗星球一组色相变量(发光色系,边缘透明)+ 自转速度 22–38s 各不同 */
.d-gold{--p-hi:rgba(252,240,210,.95);--p-mid:rgba(226,192,128,.5);--p-lo:rgba(150,120,70,.16);
--p-band:rgba(255,244,214,.5);--p-band2:rgba(214,178,110,.4);--p-halo:rgba(233,201,139,.22);--spin:34s}
6 · 湖面呼吸(首屏底部光带)
.lake-band{position:absolute;left:0;right:0;bottom:-6%;height:44vh;pointer-events:none;
background:radial-gradient(ellipse 120% 100% at 50% 100%,
rgba(233,210,160,.15),rgba(120,132,236,.09) 46%,transparent 72%);
animation:lake-breathe 10s ease-in-out infinite}
@keyframes lake-breathe{50%{opacity:1;transform:scaleY(1.06)}}
7 · 滚动显现
IntersectionObserver 加 .in(fade-up,1s 缓动,threshold .12);reduced-motion 直接全显。
8 · 移动端
断点 960 / 560:网格单列、星球换行、按钮纵排;触控目标 ≥44px;禁止横向溢出。
9 · 验收截图流程
- 本地起静态服务预览(实时接口不在本地时走优雅降级文案,不用假数据冒充)。
- 桌面 1440×900 截图:首屏、每个内容区、交互展开态。
- 移动 390×844 截图:首屏、内容区、页尾。
- 对照 SKILL.md 自检清单逐条过,再呈冰朔判。