如何在重新渲染时将固定大小的 div 从一个容器平滑过渡到另一个容器?



抽象

预期过渡

不准确,但与我的例子相关:

  1. 状态 0:假设你有一个容器 1(棋盘上有棋子的div)和死棋视图(容器 2)。容器 1 和容器 2 的位置取决于 CSS 和设备/媒体变量,由浏览器处理。
  2. 状态 1:棋子被砸碎,因此应该顺利地从棋盘移动到相应占位符上的死块视图。

我有能力使用唯一的 ID/键积极识别移动的div。

其他前提条件: 我正在使用 React,所以我希望仅从两个渲染的差异中完成平滑过渡:render(State0) -> render(State1)。(或者,至少,使用最少的命令式代码注入)

这是我的沙盒:https://codesandbox.io/s/crazy-pasteur-lr4ku

我还尝试过什么

  1. 我尝试使用反应键和 id 来识别移动的div。但这不是反应问题:使用纯 js (appendChild) 移动div 也不能提供平滑过渡。
  2. 我尝试使用反应姿势,因为它似乎是我需要的东西。但它仅限于对 ul/li 元素进行分组,其他动画示例/元素独立于其他页面元素(或者我没有正确研究框架的能力)。

我找到了可能适合我的概念。

摘要

每当div1将位置更改为div1' 时,立即杀死div1,同时使用关键帧为div1' 提供动画,从最后一个已知位置开始,1 次迭代。

技术

反应:组件将卸载 => 保存唯一标识的元素的当前位置

反应:组件DidMount =>计算差异,动态创建动画,设置状态以使用动画重新渲染。

不幸的是,也需要一些全局状态和其他反模式,但有效。

工作示例(基于问题): https://codesandbox.io/s/muddy-hill-ti6bs

要点:

  1. 在任何地方都没有绝对定位
  2. 我能够调整页面/浏览器/视口的大小,容器根据 CSS 属性重新渲染
  3. 目标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

相关内容

  • 没有找到相关文章

最新更新