QiuVisionINTERACTION STUDY / 015

CONTAINER TRANSFORM

同一块表面,
两种展开的旅程。

按钮长成面板,卡片抵达浮层。点一下,跟随容器的边缘,观察内容如何在形变之间安静地换场。

播放
慢放时更容易看清内容的进退顺序
A

留在原地,向内展开

ANCHORED EXPANSION

阅读清单 03

点击「筛选」,再试试「更多标签」。
右上角留在原位,面板向左下方生长。

A / closed目标尺寸

一个节点,两层内容。外框直接改变宽高;面板常驻测量,展开完成后再恢复交互。

B

离开原位,抵达中央

RECTANGLE MIGRATION

光影观察手册02 PLACES

    点击任意卡片,留意标题与原位的空隙。
    按 Esc 或点击背景,让它回到出发的地方。

    B / closed目标矩形

    布局占位,视觉迁移。原位保留按钮;视觉层移动到视口坐标,返回前重新测量起点。

    01 / 先看边缘

    宽高按数值变化,圆角保持稳定。容器没有整体 scale,文字也就不会被一起拉长。

    02 / 再看内容

    标题始终可见,辅助内容错峰淡入。开启慢放,观察容器先行、内容跟随的时序。

    03 / 最后看回程

    浮层内可以增加内容。改变窗口大小再关闭,卡片仍会回到重新测量后的位置。

    展开实现笔记 · 与博客代码的对应关系

    本页内嵌 Motion 12.23.15,使用原生 JavaScript 的 animate(),无需构建或联网。策略 A 对应博客的 motion.div + ResizeObserver;策略 B 将同一个视觉节点临时挂到 body,以 fixed 定位统一使用视口坐标。标题与徽章始终复用原 DOM,单独改变位置;这里没有调用 React 的 layoutId。两种写法保持相同的几何与内容编排原则。

    // A:右上角锚定,同一外壳
    animate(shell, {
      width: panel.offsetWidth,
      height: panel.offsetHeight
    }, { type: "spring", duration: .4, bounce: 0 });
    // ResizeObserver 监听面板的自然尺寸
    // 过渡中 inert,完成后解除
    // B:占位按钮 + 独立视觉层
    const origin = trigger.getBoundingClientRect();
    // body / fixed,起终点都是视口坐标
    animate(visual, centeredRect(), spring);
    // 关闭前重测;动画完成后还原焦点
    // closed → opening → open → closing → closed

    正常速度:A 几何 400ms,B 几何 480ms,bounce = 0;内容入场延迟 80–120ms,离场无延迟。以动画完成回调推进相位,动画被打断时通过版本号丢弃过期回调。系统或手动开启减少动态效果时,所有时长和延迟归零,焦点与模态语义保持不变。