zhuyuan-ice-gl-zy001/skills-mirror/guanghu-ui-brain/implementation-patterns.md

7 KiB
Raw Blame History

光湖 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 · 验收截图流程

  1. 本地起静态服务预览(实时接口不在本地时走优雅降级文案,不用假数据冒充)。
  2. 桌面 1440×900 截图:首屏、每个内容区、交互展开态。
  3. 移动 390×844 截图:首屏、内容区、页尾。
  4. 对照 SKILL.md 自检清单逐条过,再呈冰朔判。