我正在尝试创建动画,以使用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-div动画的任何帮助或建议。
答案 0 :(得分:1)
不可能
无法以这种方式进行动画处理,因为DOM认为您正在删除="BMI "&choose(match(A2,{0,18.5,25,30,35,99}),"<18.5","≥ 18.5 - 24.9","≥ 25 - 29.9","≥ 30 - 34.9","≥ 35")
,然后添加新的div
。即使您使用相同的div
,但DOM没有该上下文。动画是通过更改CSS(而不是HTML)来控制的。
...但是这是操作方法
如果您实际上需要两个列表都保留在不同的div
中,那么您最好的选择是:
div
设置为old item
的位置,然后删除new item
并显示old item
。new item
,并在old item
所在的位置创建一个new item
,并将其移至old item
位置。相同的概念,两种实现方式。
我修改了您现有的样本,以显示选项2的简化版本。请注意,有许多动画决策可以做出来,例如列表变小时会发生什么,项目应如何从红色到绿色等,我没有尝试客观地解决它们。另外,如果您可以将两个列表的所有new item
都放在一个item
中,并div
来控制它们的位置,那将容易得多。但是如果他们需要结束在单独的absolute
中...
https://codepen.io/sallf/pen/VgBwQr?editors=0010
发生了什么事
div
添加transition
可以在调整.item
属性时使动画发生。transform
知道哪个项目正在制作动画... transition.item
知道项目应相对于要移动的列表底部的偏移transition.startTop
位置,然后... y
作为控制动画的标志。transition.startAnim
的动画需要进行某些更改,因此我们使用transition
来延迟setTimeout
的更改,这基本上会使动画从计算的位置返回到{ {1}}。