请制作一个可以在浏览器直接打开的单文件 HTML 动态示例，实现「分块展开」（结构转场）。

视觉目标：小块从中心展开，重新拼成完整照片。
适用场景：旅行卡点、片头、图片合集
输入素材：使用两张高清照片，保持比例居中裁切，不拉伸画面。
实现要求：原生 JavaScript + Canvas 2D，画布 960×540，requestAnimationFrame 按秒驱动，循环周期 4.8 秒。支持暂停、重播，文字效果支持编辑文字。画布缩放时保持 16:9，不依赖框架、在线字体或 AI 接口。

效果边界：可直接用图片。图块先分离，再落回原位。

请按下列现有核心逻辑复现，并补齐共享变量与渲染初始化；需要精确复现时配合图鉴中的完整 HTML，不要只复制片段：
// fx-0 · 分块展开
// 摘自 fx(i, t)；依赖该函数的时间、画布及素材初始化。
// 完整可运行版本请切换「完整 HTML」。
if(i===0){ctx.fillStyle='#101316';ctx.fillRect(0,0,W,H);const q=(t%4.8),order=[7,2,3,8,13,12,11,6,1,0,5,10,14,9,4];
  order.forEach((id,k)=>{const n=1-Math.pow(1-clamp((q-.065*k)/.75),3);if(!n)return;const c=id%5,r=Math.floor(id/5),cw=W/5,ch=H/3,sc=.12+.88*n,x=(W/2-cw*sc/2)*(1-n)+c*cw*n,y=(H/2-ch*sc/2)*(1-n)+r*ch*n;ctx.save();ctx.translate(x,y);ctx.scale(sc,sc);withClip(()=>ctx.rect(0,0,cw,ch),()=>imageFit(a,-c*cw,-r*ch));ctx.restore()});
 }

// 每帧调用，t 的单位是秒：
clean();
fx(0, t);

交付完整可运行代码，解释可调参数；先确保上述效果，再调整速度、颜色或强度。检查循环首尾、暂停状态、图片载入失败和短标题可读性。