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?
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?
Share Improve this question edited Aug 8, 2017 at 6:25 Paolo Forgia 6,7488 gold badges50 silver badges59 bronze badges asked Jun 1, 2017 at 17:44 thousightthousight 1,1541 gold badge16 silver badges40 bronze badges 5- 3 The transaction you showed should be achievable using one element transition (image + music player) in html5/css3 while the reactjs can manage the content change of the music player sub-element. So that you don't need to find a share element transation alternative in react – Chris Chen Commented Aug 8, 2017 at 4:29
- 1 To answer your question directly, have you checked facebook.github.io/react/docs/… ? – Chris Chen Commented Aug 8, 2017 at 4:31
- 1 @ChrisChen Already checked it, I think I'm going to make my own Shared Elements Transition system. In the meantime if someone finds a library that does this already, please link it here. – Lucio Commented Aug 8, 2017 at 7:35
- @ChrisChen do you have any actual code example? – thousight Commented Aug 8, 2017 at 15:04
- Look at examples here github./joshweau/react-flip-move, github./bkazi/react-layout-transition and github./GoogleChrome/flipjs (non-react) – Dawid Karabin Commented Aug 9, 2017 at 22:17
3 Answers
Reset to default 6 +25You 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:
- Hides the text content of the small panel.
- Scales the picture and text background to fill full screen.
- Puts in the new text content.
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 es 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./325/F50057/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder./325/F44336/ffffff">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder./325/1DE9B6/000000">
<div class="content"></div>
</div>
<div class="card">
<img src="http://via.placeholder./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.
I am not sure if I understand the question correctly because I am unaware of Android framework. Here is my solution based upon ReactJS knowledge:
Steps:
- Maintain 2 state variables:
CurrentMode
&NextMode
. Possible values are1
&2
. - At the click of album change the
NextMode
to2
. And in code pare the values ofCurrentMode
&NextMode
. IfCurrentMode
<NextMode
than set the size accordingly. - Similarly when
CurrentMode
>NextMode
than set the size accordingly.
You can do this with mauerwerk: https://github./drcmda/mauerwerk
It's basically a grid where each cell gets a status whether it's in thumbnail or opened mode. You can use this status to switch or transition between contents, whether you want to fade them or let parts stand is up to you. There's an additional toggle function which you can use to toggle a cell open/closed.