我正在尝试使用 React 创建一个动画,用于将子元素从一个父元素移动到另一个父元素。
用户应该能够点击一个元素并看到它移动到另一个 div 中。
我制作了一个简单的演示组件(没有动画)来展示我的意思。单击元素时,状态会更新,并且元素会在正确的位置重新呈现。
class App extends React.Component {
state = {
list: ['Alice', 'Bob', 'Charlie', 'David', 'Emily', 'Frank'],
top: [0, 1, 2],
bottom: [3, 4, 5]
}
moveDown = (item) => {
let { top, bottom } = this.state
this.setState({
top: top.filter(x => x !== item),
bottom: [...bottom, item]
})
}
moveUp = (item) => {
let { top, bottom } = this.state
this.setState({
top: [...top, item],
bottom: bottom.filter(x => x !== item)
})
}
render() {
let { top, bottom, list } = this.state
return (
<div style={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'center',
height: '90vh',
width: '100%'
}}>
<div>
{top.map((item) =>
<div
onClick={() => this.moveDown(item)}
style={{color:'red'}}>{list[item]}</div>
)}
</div>
<div>
{bottom.map((item) =>
<div
onClick={() => this.moveUp(item)}
style={{color:'green'}}>{list[item]}</div>
)}
</div>
</div>
)
}
}
Codepen 演示:https://codepen.io/ee92/pen/LqrBjL?editors=0010
非常感谢并提前感谢您提供有关如何实现此 div-to-div 动画的任何帮助或建议。
最佳答案
不,这不可能
不可能以这种方式制作动画,因为 DOM 认为您正在删除一个 div
,然后添加一个新的 div
。即使它对您来说是相同的 div
,DOM 也没有那个上下文。动画由 CSS 而非 HTML 的更改控制。
...但这是如何做到的
如果您确实需要将两个列表放在不同的 div
中,您可以做的最好的是:
- 将
旧项
动画化到新项
位置,然后删除旧项
并显示新项
. - 删除
旧项
并在旧项
所在的位置创建一个新项
并将其移动到新项
位置。
相同的概念,两种实现方式。
我修改了您现有的示例以显示选项 2 的简化版本。请注意,有许多动画决策需要做出,例如当列表变小时会发生什么,元素应该如何从红色到绿色等等,我没有尝试客观地解决它们。此外,如果您可以将两个列表的所有 item
都放在一个 div
中,并控制它们的位置 absolute
,这会容易得多。但是如果他们需要在单独的 div
中结束......
https://codepen.io/sallf/pen/VgBwQr?editors=0010
发生了什么
- 将
transition
添加到.item
中,我们可以在调整transform
属性时使动画发生。 - 在元素点击时我们更新状态列表并添加...
transition.item
知道哪个元素正在动画...transition.startTop
了解元素相对于要移动到的列表底部的偏移y
位置,并且...transition.startAnim
作为控制动画的标志。- 因为
transition
在动画之前需要改变一些东西,我们使用setTimeout
来延迟transition.startAnim
的改变,这基本上使动画从计算位置开始,返回到0
。
关于javascript - 用于将元素从一个父元素移动到另一个父元素的 React 动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54660220/