React animation for moving an element from one parent to another
No it's not possible
It's not possible to animate in that way because the DOM thinks you're removing a div
and then adding a new div
. Even though it's the same div
to you, the DOM doesn't have that context. Animations are controlled by changes to CSS, not HTML.
...but here's how to do it
If you actually need both lists to stay in different div
s the best you can do is either:
- Animate the
old item
to thenew item
position, then delete theold item
and show thenew item
. - Remove the
old item
and create anew item
where theold item
was and move it to thenew item
position.
Same concept, two ways of doing it.
I modified your existing sample to show a simplified version of option 2. Note that there are a number of animation decisions to make like what happens when the list gets smaller, how should the items change from red to green, etc., and I didn't try and objectively solve them. Also, this would be much easier if you could have all the item
s for both lists in one div
, and control their positions absolute
ly. But if they need to end up in separate div
s...
https://codepen.io/sallf/pen/VgBwQr?editors=0010
What's going on
- Adding a
transition
to.item
we can make the animation happen when we make adjustments to thetransform
property. - On item click we update our lists in state and add...
transition.item
to know which item is animating...transition.startTop
to know the offsety
position the item should start at relative to the bottom of the list it's moving to, and...transition.startAnim
as a flag to control the animation.- Since
transition
s need something to change before they'll animate, we usesetTimeout
to delay the change oftransition.startAnim
which basically causes the animation from the computed position, back to0
.
React - animate mount and unmount of a single component
This is a bit lengthy but I've used all the native events and methods to achieve this animation. No ReactCSSTransitionGroup
, ReactTransitionGroup
and etc.
Things I've used
- React lifecycle methods
onTransitionEnd
event
How this works
- Mount the element based on the mount prop passed(
mounted
) and with default style(opacity: 0
) - After mount or update, use
componentDidMount
(componentWillReceiveProps
for further updates)to change the style (opacity: 1
) with a timeout(to make it async). - During unmount, pass a prop to the component to identify unmount, change the style again(
opacity: 0
),onTransitionEnd
, remove unmount the element from the DOM.
Continue the cycle.
Go through the code, you'll understand. If any clarification is needed, please leave a comment.
class App extends React.Component{
constructor(props) {
super(props)
this.transitionEnd = this.transitionEnd.bind(this)
this.mountStyle = this.mountStyle.bind(this)
this.unMountStyle = this.unMountStyle.bind(this)
this.state ={ //base css
show: true,
style :{
fontSize: 60,
opacity: 0,
transition: 'all 2s ease',
}
}
}
componentWillReceiveProps(newProps) { // check for the mounted props
if(!newProps.mounted)
return this.unMountStyle() // call outro animation when mounted prop is false
this.setState({ // remount the node when the mounted prop is true
show: true
})
setTimeout(this.mountStyle, 10) // call the into animation
}
unMountStyle() { // css for unmount animation
this.setState({
style: {
fontSize: 60,
opacity: 0,
transition: 'all 1s ease',
}
})
}
mountStyle() { // css for mount animation
this.setState({
style: {
fontSize: 60,
opacity: 1,
transition: 'all 1s ease',
}
})
}
componentDidMount(){
setTimeout(this.mountStyle, 10) // call the into animation
}
transitionEnd(){
if(!this.props.mounted){ // remove the node on transition end when the mounted prop is false
this.setState({
show: false
})
}
}
render() {
return this.state.show && <h1 style={this.state.style} onTransitionEnd={this.transitionEnd}>Hello</h1>
}
}
class Parent extends React.Component{
constructor(props){
super(props)
this.buttonClick = this.buttonClick.bind(this)
this.state = {
showChild: true,
}
}
buttonClick(){
this.setState({
showChild: !this.state.showChild
})
}
render(){
return <div>
<App onTransitionEnd={this.transitionEnd} mounted={this.state.showChild}/>
<button onClick={this.buttonClick}>{this.state.showChild ? 'Unmount': 'Mount'}</button>
</div>
}
}
ReactDOM.render(<Parent />, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
What's a react.js-friendly way to animate a list-reordering?
I just released a module to tackle exactly this problem
https://github.com/joshwcomeau/react-flip-move
It does a few things differently than Magic Move / Shuffle:
- It uses the FLIP technique for hardware-accelerated 60FPS+ animations
- It offers options to "humanize" the shuffle by incrementally offsetting delay or duration
- It handles interruptions gracefully, no weird glitch effects
- Bunch of other neat stuff like start/finish callbacks
Check out the demos:
http://joshwcomeau.github.io/react-flip-move/examples/#/shuffle
How to animate the disappearance of a component in ReactJS?
TLDR
As far as I know there is
onAnimationStart
,onAnimationEnd
in React
Answer
You can use onAnimationStart
, onAnimationEnd
synthetic event listener and some props like isShowComponent
, isHideComponent
And you can use unmountComponentAtNode()
, findDOMNode()
in react-dom
Peseudo Code
handleAnimationEnd() {
const node = ReactDom.findDOMNode(this);
ReactDom.unmountComponentAtNode(node)
}
...
render(){
return (
<div onAnimtionEnd={this.handleAnimationEnd}>
/** some code**/
</div>
)
}
ETC
It is not real code but just peseudo! but I think you can do that using this api and event handler!
Good luck!
If you have any good solution. just hit me with comment!
It should be helpful to other developer struggling with this issue
Reference
- React Document
- React Dom Document
- code sandbox exmaple
- How to Trigger Animation Events using React
move an element from one div to another div with animate effect on button click using html and jquery
Got it working, here is the fiddle
http://jsfiddle.net/h7tuehmo/3/
Javscript:
var x;
var y;
$('article').each(function(index){
$(this).click(function(){
$(this).addClass('selected') ;
x = $(this).offset().left;
y = $(this).offset().top;
})
});
$('img').each(function(index){
var xi = $(this).offset().left;
var yi = $(this).offset().top;
$(this).css('left', xi).css('top', yi);
$(this).click(function(){
$(this).animate({
left: x,
top: y
})
})
});
Picture animation in React
The problem I see with the code that you are directly mutating the state. You should never mutate state and props directly. Use prevState
in the moveDown function to update the state. Please read about the updater
function from react docs
this.setState(prevState => {
const { top, rear, transition } = prevState;
return {
top: top.filter(x => x !== item),
rear: [...rear, item],
transition: {
...transition,
item,
startTop: itemTop / 5,
startAnim: false
}
};
});
Similarly in you resetState
function, the state it being mutated. Change it to :
resetState = () => {
this.setState(
prevState => ({
transition: { ...transition, startAnim: true }
}),
() => {
console.log("setState finished");
}
);
};
Related Topics
How Much of an Effect Can Different Operating Systems Have on Displaying Web Pages
Location Permission Alert on iPhone with Cordova
Ng If with Angular for String Contains
Avoid Having to Double-Click to Toggle Bootstrap Dropdown
How to Prevent Material Icon Text from Showing Up When Google's Js Fails to Convert Them
Fixed Positioned Element Flicker in Ie Only, How to Solve
How to Disable Caching of Static Assets Like .CSS and .Js in Jsf2
Workaround for Display Block and CSS Transitions Not Triggering
Get Document.Stylesheets by Name Instead of Index
Change the Fixed Navbar's Classes Depending on the Background of the Page Section It Hovers
Bootstrap 3.0 Popovers and Tooltips
Change Header CSS Upon Scrolling Down
Expand Div Over Others on Mouse Over Jquery
Screen Zooms in When a Bootstrap Modal Is Opened on iOS 9 Safari
Angularjs Bug in Ie with Style VS Ng-Style
Center Div Vertically and Horizontally Without Defined Height