- oil-ui-pro 升到 0.22.2:references 13→28 份(新增 16、删 imagery.md)、assets 增 cards/(22 组)与 fonts/、SKILL.md 顶层五步结构未改名。 - 升级路径:官方 `npx github:oil-oil/oil-cli update` 稳定失败(error=replace、报「检查目录权限」)。 真身为 EXDEV —— 解压在 os.tmpdir()(C 盘)、技能目录在 E 盘,Windows 上 rename 不能跨盘; CLI 的 catch 把非 CliError 原生异常一律兜底成 replaceFailed,真错误一个字不吐。 做法=借其 prepare() 只做下载+校验,再 cp 到同盘 stage、rename 交换;官方命令复验 up_to_date。 - 回归:product-planning 按名引用的 visual-review.md/tools.md/design-direction.md/style-explorer.md 全部健在;命名闸门 2061|0|27。 - session-mechanism/references/pitfalls.md 新增 P0-98(含通则:更新器把原生错误兜底成指错方向的人话)。
28 lines
1.8 KiB
JavaScript
28 lines
1.8 KiB
JavaScript
import {loop, watchColors, shell, mix, clamp, staticMotion} from '../shared/runtime.js';
|
|
import {coatedSurface} from './material.js';
|
|
|
|
export function mount(element, options = {}) {
|
|
const variant=options.variant ?? element.dataset.variant ?? 'token';
|
|
const cleanShell=shell(element,{...options,variant:variant==='card'?'card':'token'});
|
|
const surface=coatedSurface(element.querySelector('.flow-surface'));
|
|
const card=element.querySelector('.physical-card');
|
|
let palette,x=0,y=0,tx=0,ty=0;
|
|
const still=staticMotion(element,options);
|
|
const draw=(time,dt)=>{
|
|
if(still())x=y=tx=ty=0;
|
|
if(dt || still()){
|
|
const ease=1-Math.exp(-dt*7);x=mix(x,tx,ease);y=mix(y,ty,ease);
|
|
card.style.transform=`rotateX(${-y*5}deg) rotateY(${x*7}deg)`;
|
|
}
|
|
surface.draw(time,palette,[x,y]);
|
|
element.style.setProperty('--token-pulse',still()?.8:.65+.35*(.5+.5*Math.sin(time*2.2)));
|
|
};
|
|
const clock=loop(element,draw,{...options,settled:()=>Math.abs(x-tx)+Math.abs(y-ty)<.001});
|
|
const off=watchColors(element,p=>{palette=p;clock.invalidate();});
|
|
const ro=new ResizeObserver(()=>{surface.resize();clock.invalidate();});ro.observe(card);
|
|
const move=e=>{if(e.pointerType==='touch' || still())return;const r=element.getBoundingClientRect();tx=clamp((e.clientX-r.left)/r.width*2-1,-1,1);ty=clamp((e.clientY-r.top)/r.height*2-1,-1,1);};
|
|
const leave=()=>{tx=ty=0;};
|
|
element.addEventListener('pointermove',move);element.addEventListener('pointerleave',leave);element.addEventListener('pointercancel',leave);
|
|
return {destroy(){clock.destroy();off();ro.disconnect();surface.destroy();cleanShell();element.removeEventListener('pointermove',move);element.removeEventListener('pointerleave',leave);element.removeEventListener('pointercancel',leave);card.style.removeProperty('transform');element.style.removeProperty('--token-pulse');}};
|
|
}
|