In Android, shared element transition allows 2 exact same elements existing in both pages to link together when transitioning pages, just like the album art in the gif shown below:
I wonder if it is possible to achieve the same kind of transition with ReactJS between classes. If so, any examples? If not, what about with jQuery?
You can do this transition almost entirely with the CSS transform
property. React JS is all about manipulating the DOM, but you don't need to do that here much.
The animation:
Of those 1 and 3 are easy with React, so you only really need the transition animation.
Here is a very very basic example using no JS at all:
body {
background-color: #ccc;
}
.card {
width: 150px;
padding: 0;
margin: 0;
background-color: #fff;
position: absolute;
top: 0: left: 0;
z-index: 1;
/* Transition properties mean changes to them are animated */
transition-property: transform;
transition-timing-function: ease-in-out;
transition-duration: 500ms;
transform-origin: top left;
}
.card>img {
width: 150px;
height: 150px;
margin: 0;
padding: 0;
}
.card>.content {
width: 150px;
height: 50px;
background-color: #fff;
margin: 0;
}
/* This is only for the purposes of this demo.
* In production you'd have an underlying grid layout and JS to figure out the position */
.card:nth-of-type(2) {
left: 175px;
}
.card:nth-of-type(3) {
top: 230px;
}
.card:nth-of-type(4) {
top: 230px;
left: 175px;
}
/* On hover transform the card to full size and translate it to the top left
* Note that translate comes before scale. */
.card:nth-of-type(1):hover {
transform: scale(2.1667);
z-index: 2;
}
.card:nth-of-type(2):hover {
transform: translate(-175px, 0) scale(2.1667);
z-index: 2;
}
.card:nth-of-type(3):hover {
transform: translate(0, -230px) scale(2.1667);
z-index: 2;
}
.card:nth-of-type(4):hover {
transform: translate(-175px, -230px) scale(2.1667);
z-index: 2;
}
<div class="card">
<img src="http://via.placeholder.com/325/F50057/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/F44336/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/1DE9B6/000000">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder.com/325/FFEB3B/000000">
<div class="content"></div>
</div>
The basic trick is to use CSS transform
with translate
and scale
- these properties can be handled by the graphics card and so keep animations smooth even on mobile.
Note that the CSS is rather clunky - I've done it like that just to show that it can be done with pure CSS. In practice you're going to want some JS to set the offset properties, hook up a click event, etc.
Another trick (which I haven't done here) is to scale the animation backwards - start with the full size control and translate
/scale
it down into the position it appears to start in. When the user clicks on it remove the transform
- that saves the browser from having to recalculate the full sized object's DOM before starting the animation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With