如何在重新渲染时将 fixed-size-div 从一个容器平滑过渡到另一个容器?
How do I smoothly transition fixed-size-div from one container to another on re-render?
摘要
Expected transition
不准确,但与我的示例相关:
- State0:假设您有一个 container1(棋盘上有 div 个棋子)和 dead-pieces-view(container2)。 container1 和 container2 的位置取决于 CSS 和 device/media 个变量,由浏览器处理。
- 状态1:棋子被砸碎,所以它应该顺利地从棋盘移动到相应占位符上的死棋子视图。
我有能力通过独特的 ids/keys 积极识别移动 div。
其他先决条件:
我正在使用 React,所以我希望仅通过两个渲染的差异完成平滑过渡:render(State0) -> render(State1)。 (或者,至少,使用最少的命令式代码注入)
这是我的沙箱:https://codesandbox.io/s/crazy-pasteur-lr4ku
我还尝试了什么:
- 我尝试使用反应键和 ID 来识别移动 div。但这不是反应问题:使用纯 js (appendChild) 移动 div 也不能提供平滑过渡。
- 我尝试使用 react-pose,因为它似乎是我需要的东西。但仅限于分组 ul/li 元素,其他动画 examples/elements 独立于其他页面元素(或者我没有适当研究框架的能力)。
我找到了可能适合我的概念。
摘要:
每当 div1 将位置更改为 div1' 时,立即杀死 div1,同时使用关键帧从最后一个已知位置为 div1' 提供动画, 1 次迭代。
技术:
React: componentWillUnmount => 保存唯一标识的元素的当前位置
React:componentDidMount => 计算差异,即时创建动画,setState 以重新渲染动画。
不幸的是,它也需要一些全局状态和其他反模式,但有效。
工作示例(基于问题):https://codesandbox.io/s/muddy-hill-ti6bs
要点:
- 任何地方都没有绝对定位
- 我可以调整大小 page/browser/viewport,容器根据 CSS 属性重新渲染
- 目标 div 重新渲染后成功移动到新位置。如果之前的动画没有完成,可以继续。
您需要:
- 确保父级在重新渲染之间保持不变(如果父级不同,React 将 delete/create 一个新的子级,因此 "existing" 子级的过渡是不可能的 - 父级需要有永久键,例如
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} />;
};
摘要
Expected transition
不准确,但与我的示例相关:
- State0:假设您有一个 container1(棋盘上有 div 个棋子)和 dead-pieces-view(container2)。 container1 和 container2 的位置取决于 CSS 和 device/media 个变量,由浏览器处理。
- 状态1:棋子被砸碎,所以它应该顺利地从棋盘移动到相应占位符上的死棋子视图。
我有能力通过独特的 ids/keys 积极识别移动 div。
其他先决条件: 我正在使用 React,所以我希望仅通过两个渲染的差异完成平滑过渡:render(State0) -> render(State1)。 (或者,至少,使用最少的命令式代码注入)
这是我的沙箱:https://codesandbox.io/s/crazy-pasteur-lr4ku
我还尝试了什么:
- 我尝试使用反应键和 ID 来识别移动 div。但这不是反应问题:使用纯 js (appendChild) 移动 div 也不能提供平滑过渡。
- 我尝试使用 react-pose,因为它似乎是我需要的东西。但仅限于分组 ul/li 元素,其他动画 examples/elements 独立于其他页面元素(或者我没有适当研究框架的能力)。
我找到了可能适合我的概念。
摘要:
每当 div1 将位置更改为 div1' 时,立即杀死 div1,同时使用关键帧从最后一个已知位置为 div1' 提供动画, 1 次迭代。
技术:
React: componentWillUnmount => 保存唯一标识的元素的当前位置
React:componentDidMount => 计算差异,即时创建动画,setState 以重新渲染动画。
不幸的是,它也需要一些全局状态和其他反模式,但有效。
工作示例(基于问题):https://codesandbox.io/s/muddy-hill-ti6bs
要点:
- 任何地方都没有绝对定位
- 我可以调整大小 page/browser/viewport,容器根据 CSS 属性重新渲染
- 目标 div 重新渲染后成功移动到新位置。如果之前的动画没有完成,可以继续。
您需要:
- 确保父级在重新渲染之间保持不变(如果父级不同,React 将 delete/create 一个新的子级,因此 "existing" 子级的过渡是不可能的 - 父级需要有永久键,例如
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} />;
};