React at 60fps — Building a Medium-Inspired Zoom with React-Pose
source link: https://www.tuicool.com/articles/aAbu2qR
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
What I will be building
You might have noticed that Medium has a pretty great image preview UI and this is what I will be implementing today:
And if you would like to see my final implementation of if, this is it:
Tip: Use Bit ( Github ) to easily share and reuse your React components between your apps, and build faster as a team with a shared component hub.
Picking React & React-Pose
I decided to go with react for this one. The algorithm could be easily ported to Angular, Vue or even pure web components but I think React is the main web standard at the moment.
In terms of the transitions, I don’t think this type can be easily done with CSS, so I needed to pick between JS animation solutions for React and decided to go with react-pose as I already used it before and it’s a pretty great library which is also available for other libraries and pure JS.
Implementation
Now, let’s get started. Firstly, I created a simple image component that just allows you to toggle zoom on press, but doesn’t cause any visual changes.
Then I can simply switch the <img>
tag with a posed.img
. When the image is in it’s normal state, it should have a static position, width matching the parent and the height adjusted to its aspect ratio. The difference between that and the zoomed state is that when zoomed, the position should be fixed.
React-pose allows you to pass the current “pose” state to tell it which state should be rendered on the screen.
I also added some styles so that the cursor suggests that you can zoom in/out.
And this simple implementation shows very promising results:
However there are still things that need to be fixed. Firstly, if the image has an odd aspect ratio the zoomed image is stretched. To fix this, I need to make sure that the original aspect ratio is kept. Before doing that however, I will just add an utility hook that allows me to create event listeners.
I also decided to make the transition key frames closer to the medium transition. The important change however is to the width and height of the zoom state, where it will allow to specify whether the image has a full width or full height.
Now, the most important change. Firstly, I added a ref element to the image and another boolean state variable called fullWidth
. This is used in the updateSizing
function in order to check the size of the image and tell us whether the image has to be stretched vertically or horizontally. This updates when the image loads or the user changes the size of the browser (e.g. changes phone rotation, goes fullscreen, etc). I also implemented a feature allowing the user to scroll to unzoom the image.
And here is what this looks like:
As you can see, the issue with the odd scaling has been resolved, but we still see the content below the image shifting up. The solution to this, is doing exactly what the developers at Medium did, which is blank out the background.
And it’s all done, we did it You can find a live demo right here:
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK