# Isle：给其他 Agent 的复现提示词

独立实现液态玻璃灵动岛与可甩动镜片，Canvas WebGL + DOM + GSAP。可复用本目录index.html静态CSS/结构及../../isle-gallery/assets/scene-1.webm、scene-2.webm、scene-3.webm。不要读取旧JS。Inter Tight400/500/600/700。三视频object-fit cover叠层，只有选中on透明度1，过渡.8秒；所有视频同时静音循环播放。中心标题Bend the light.，字号clamp(44px,6.2vw,96px)，手机52；顶部ISLE · LIQUID GLASS，底部三枚36px圆形场景按钮。玻璃canvas z5、DOM边框/内容z6。

岛在left50%、translateX(−50%)、top70/手机48；初始250×46、圆999、仅封面/均衡器显示。点非prev/next/play控件切open，宽320/高132（关闭250/46），.7秒elastic.out(1,.62)，open圆34；原prev/next/play没有播放器动作，不新增功能。镜片190圆，默认opacity0、stage:hover时1。镜片初始中心(.62W,.62H)，resize归此位置但不重置速度。

镜片pointerdown记录lastXY、vx/vy=0、draggingtrue/capture；move dx=clientX−lastX，位置+=dx/dy，速度=本次dx/dy，更新last；up/cancel释放。未拖动每帧位置+=速度，然后速度*=.94，以offsetWidth/2为四边碰撞半径；越左/上置边界、速度=abs(v)*.78，越右/下置边界、速度=−abs(v)*.78。DOMleft=x−width/2、top=y−height/2。保留逐帧物理，不改为按dt积分。

## 玻璃位移图
settings初始refraction2/bezel1/chroma1。隐藏滑条仍保留input事件更新和2位数值。每个玻璃元素按实时DOM矩形生成map：w/h=max(8,round尺寸)，radius夹1..min(w,h)/2，bezel夹2..min(w,h)/2，thickness>=1。实际元素bezel=clamp(.42*min(w,h)*settings.bezel,6,52)，thickness=max(1,round((lens?26:17)*refraction*2)/2)，岛radius取computed borderRadius、镜片h/2。

SDF(x,y)=min(max(qx,qy),0)+hypot(max(qx,0),max(qy,0))−r，q=abs(x/y)−w/h/2+r。profile(s)=(1−(1−s)^4)^.25。96级Float32位移表：s=i/95，a=max(0,s−1/384)、b=min(1,s+1/384)，slope=thickness*(profile(b)−profile(a))/((b−a)*bezel)，cos=1/hypot(slope,1)，sin=−slope*cos，ior=2/3，k=1−ior²*(1−cos²)，k<=0则0，否则f=ior*cos−sqrt(k)，rx=f*sin、ry=−ior+f*cos，mag=−thickness*profile(s)*(rx/ry)。max基于未Float32截断的mag，scale=max(maxAbs,.5)、pad=ceil(scale)+2。图宽高w/h+2pad。

每像素px=x+.5−pad−w/2，py类同，d=−SDF。d<=0或d>=bezel：RG128，B=d>=bezel?0:128，A=d<=0?0:255。边缘d/bezel*95线性插值mag，gx=SDF(px+.75,py)−SDF(px−.75,py)、gy类同，len=hypot(gx,gy)||1；R=128+(−gx/len*mag)/scale*127、G同理、B=min(255,abs(mag)/scale*255)、A255，写入Uint8ClampedArray。缓存键round宽高/round半径/round倒角/thickness，容量超过40时淘汰最早项后新增。

## WebGL采样
上下文alpha true/premultipliedAlpha false，DPR<=2。全屏TRIANGLE_STRIP坐标[-1,-1,1,-1,-1,1,1,1]，vertex UV=((x+1)/2,(1−y)/2)。两纹理都CLAMP_TO_EDGE/LINEAR，UNPACK_FLIP_Y=false。每帧上传当前video（readyState>=2），clear透明，启用scissor。按岛、镜片顺序绘制，opacity0跳过。视频cover fit：va=videoW/H、sa=stageW/H；va>sa取(sa/va,1,(1−sa/va)/2,0)，否则(1,va/sa,0,(1−va/sa)/2)。

片元local=vUv*viewport−rectOrigin，mapUV=(local+pad)/(rectSize+2pad)，d=(texture(map).rg−.5019608)*2.0078740，base=rectOrigin+local。分别用base+d*scale*(1+.05chroma)、base+d*scale、base+d*scale*(1−.05chroma)取R/G/B。背景取样坐标clamp(point/viewport*fit.xy+fit.zw,0,1)。map alpha<.01 discard，否则输出对应RGB和alpha。scissor=(round(x*dpr),round((H−y−h)*dpr),round(w*dpr),round(h*dpr))。清理GL纹理、buffer、shader/program、事件和tweens。

验收1440×1000/390×844、16ms帧。测试视频全部seek至.5秒并pause（生产正常播放）；初始640ms、hover镜片320ms、岛展开320/960ms、镜片拖(+190,+110)后64ms、释放480/2080ms，参数2.8/1.6/2.4，切场景1/2各1000ms，收起1000ms。运行 ../scripts/check-isle.mjs，玻璃Canvas像素、镜片/岛状态与场景均一致。

## 本地图片与中英文（2026-09-21 更新）

本轮已接入本地公开图片和中英双语。复现时同时遵循 [共享规范](../../shared/README.md)：沿用当前本地图片路径，使用共享词典与语言偏好（`zh` / `en`），覆盖动态内容、辅助标签和 Canvas 文字；不要恢复旧的远程图片链接。中文拆字标题应先翻译再拆分，并保持原有动画机制。图片来源与替换映射在共享规范中列出。
