抽象
预期过渡
不准确,但与我的例子相关:
- 状态 0:假设你有一个容器 1(棋盘上有棋子的div)和死棋视图(容器 2)。容器 1 和容器 2 的位置取决于 CSS 和设备/媒体变量,由浏览器处理。
- 状态 1:棋子被砸碎,因此应该顺利地从棋盘移动到相应占位符上的死块视图。
我有能力使用唯一的 ID/键积极识别移动的div。
其他前提条件: 我正在使用 React,所以我希望仅从两个渲染的差异中完成平滑过渡:render(State0) -> render(State1)。(或者,至少,使用最少的命令式代码注入)
这是我的沙盒:https://codesandbox.io/s/crazy-pasteur-lr4ku
我还尝试过什么:
- 我尝试使用反应键和 id 来识别移动的div。但这不是反应问题:使用纯 js (appendChild) 移动div 也不能提供平滑过渡。
- 我尝试使用反应姿势,因为它似乎是我需要的东西。但它仅限于对 ul/li 元素进行分组,其他动画示例/元素独立于其他页面元素(或者我没有正确研究框架的能力)。
我找到了可能适合我的概念。
摘要:
每当div1将位置更改为div1' 时,立即杀死div1,同时使用关键帧为div1' 提供动画,从最后一个已知位置开始,1 次迭代。
技术:
反应:组件将卸载 => 保存唯一标识的元素的当前位置
反应:组件DidMount =>计算差异,动态创建动画,设置状态以使用动画重新渲染。
不幸的是,也需要一些全局状态和其他反模式,但有效。
工作示例(基于问题): https://codesandbox.io/s/muddy-hill-ti6bs
要点:
- 在任何地方都没有绝对定位
- 我能够调整页面/浏览器/视口的大小,容器根据 CSS 属性重新渲染
- 目标div 在重新渲染时成功移动到新位置。如果上一个动画未完成,则能够继续。
您需要:
确保父级- 在重新渲染之间保持不变(如果父级不同,React 会删除/创建一个新的子项,因此不可能转换"现有"子项 - 父级需要具有持久键,例如
key: idx === parentContainer ? "withBlock" : idx
) - 具有一些可转换属性(自动静态位置无法转换),例如
position: absolute
样式和可修改top
然后,您可以在每次渲染后修改可转换属性,例如:
const Block = () => {
const ref = useRef();
useEffect(() => {
if (!ref.current) {
return;
}
const el = ref.current;
const {top} = el.parentNode.getBoundingClientRect();
el.style.top = `${top + border}px`;
});
return <div className="block" ref={ref} />;
};
https://codesandbox.io/s/busy-mendeleev-7s2zg