Skip to content

Instantly share code, notes, and snippets.

@cladley
Created May 21, 2019 11:25
Show Gist options
  • Save cladley/dae87891b59ea6ea87359de288412e4e to your computer and use it in GitHub Desktop.
Save cladley/dae87891b59ea6ea87359de288412e4e to your computer and use it in GitHub Desktop.
Folding image effect using react spring
import React from 'react';
import {useSpring, animated, config} from 'react-spring';
import Slider from './Slider';
const convertPercentageToRotation = percentage => {
return percentage * 1.8;
}
function norm(value, min, max) {
return (value - min) / (max - min);
}
function lerp(norm, min, max) {
return (max - min ) * norm + min;
}
const Foldable = ({width, height, src}) => {
const [percentage, setPercentage] = React.useState(0);
const [props, set] = useSpring(() => ({percentage: 0, config: config.gentle}));
const sharedStyles = {
width,
height: height / 2,
backgroundSize: `${width}px ${height}px`,
backgroundImage: `url(${src})`
};
return (
<div style={{
perspective: 500,
width: width,
transform: `translateY(${lerp(percentage / 100, 0, -15)}px)`
}}>
{/* Top Half */}
<div style={sharedStyles} />
{/* Bottom Half */}
<div className="wrapper">
<animated.div style={{
...sharedStyles,
backgroundPosition: `0px -100%`,
transform: props.percentage.interpolate(p => {
return `rotateX(-${convertPercentageToRotation(p) + 180}deg)`
}),
transformOrigin: 'center top',
willChange: 'transform',
transformStyle: 'preserve-3d'
}}
>
<div style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: 'hsla(0, 100%, 100%, 0.9)',
backfaceVisibility: 'hidden',
transform: 'rotateY(180deg) translateZ(0.1px)',
}} />
<div className="shadow" style={{
opacity: (1 - norm(percentage, 0, 100))
}} />
</animated.div>
</div>
<br />
<Slider min={0} max={100} onChange={value => {
set({percentage: value});
setPercentage(value);
}} />
</div>
);
};
export default Foldable;
.wrapper {
transform-style: preserve-3d;
}
.shadow {
position: absolute;
z-index: 3;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #000;
backface-visibility: hidden;
border-radius: 0 0 10px 10px;
transform: translateZ(0.01px);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment