Last active
August 22, 2016 17:58
-
-
Save fantasywind/582a8aafc75ae3687529054081bda230 to your computer and use it in GitHub Desktop.
<Blur /> React Component Wrapper [iOS_Frosted_Glass_Effect]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { | |
PropTypes as T, | |
Component, | |
} from 'react'; | |
import radium from 'radium'; | |
import backgroundImage from '../static/images/background.jpg'; | |
const ANIMATION_DURATION = 1000; | |
const opacityAnimation = radium.keyframes({ | |
'0%': { | |
opacity: 0, | |
filter: 'blur(0)', | |
}, | |
'100%': { | |
opacity: 1, | |
filter: 'blur(3px)', | |
}, | |
}); | |
const styles = { | |
wrapper: { | |
position: 'relative', | |
padding: 0, | |
margin: 0, | |
}, | |
blurredWrapper: { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
overflow: 'hidden', | |
pointerEvents: 'none', | |
}, | |
blurBackground: { | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
backgroundColor: 'rgba(0, 0, 0, 0.6)', | |
display: 'block', | |
width: '100%', | |
height: '100%', | |
}, | |
blurred: { | |
filter: 'blur(2px)', | |
opacity: 0.6, | |
position: 'absolute', | |
left: 0, | |
top: 0, | |
zIndex: 50, | |
height: 'calc(100vh + 0px)', | |
width: 'calc(100vw + 0px)', | |
display: 'block', | |
backgroundImage: `url(${backgroundImage})`, | |
backgroundSize: 'cover', | |
backgroundPosition: 'center center', | |
transition: `opacity ${ANIMATION_DURATION}ms ease`, | |
}, | |
stackHide: { | |
display: 'none', | |
}, | |
stack: { | |
filter: 'blur(2px)', | |
opacity: 0.6, | |
position: 'absolute', | |
left: 0, | |
top: 0, | |
zIndex: 55, | |
height: 'calc(100vh + 0px)', | |
width: 'calc(100vw + 0px)', | |
display: 'block', | |
backgroundImage: `url(${backgroundImage})`, | |
backgroundSize: 'cover', | |
backgroundPosition: 'center center', | |
animationDuration: `${ANIMATION_DURATION}ms`, | |
animationTimingFunction: 'ease', | |
animationFillMode: 'forwards', | |
animationName: opacityAnimation, | |
}, | |
backgroundIndex: { | |
}, | |
}; | |
class Blur extends Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
bound: { | |
left: props.radix, | |
top: props.radix, | |
}, | |
}; | |
this.resizeListener = () => this.updateBlurPosition(); | |
} | |
componentDidMount() { | |
this.updateBlurPosition(); | |
window.addEventListener('resize', this.resizeListener); | |
} | |
componentWillUnmount() { | |
window.removeEventListener('resize', this.resizeListener); | |
} | |
updateBlurPosition() { | |
const target = this.refs.wrapper.firstChild; | |
this.setState({ | |
bound: target.getBoundingClientRect(), | |
}); | |
} | |
render() { | |
const { | |
style, | |
children, | |
isIndex, | |
wrapperStyle, | |
radix, | |
opacity, | |
indexSlideImage, | |
indexSlideStack, | |
} = this.props; | |
const { | |
left, | |
top, | |
} = this.state.bound; | |
let wrapperStyleMerged = [styles.blurredWrapper]; | |
if (Array.isArray(wrapperStyle)) { | |
wrapperStyleMerged = wrapperStyleMerged.concat(wrapperStyle); | |
} else { | |
wrapperStyleMerged.push(wrapperStyle); | |
} | |
return ( | |
<div ref="wrapper" style={[styles.wrapper, style]}> | |
{children} | |
<div style={wrapperStyleMerged}> | |
<div style={styles.blurBackground} /> | |
<div | |
style={[ | |
styles.blurred, | |
isIndex && styles.backgroundIndex, { | |
left: -left, | |
top: -top, | |
filter: `blur(${radix}px)`, | |
opacity: indexSlideStack.length ? 0 : opacity, | |
backgroundImage: indexSlideImage, | |
}, | |
]} /> | |
{indexSlideStack.map((stack, index) => ( | |
<div | |
key={index} | |
style={[styles.stack, { | |
left: -left, | |
top: -top, | |
filter: `blur(${radix}px)`, | |
opacity, | |
backgroundImage: `url(${stack})`, | |
}, index !== (indexSlideStack.length - 1) && styles.stackHide]} /> | |
))} | |
</div> | |
</div> | |
); | |
} | |
} | |
Blur.defaultProps = { | |
isIndex: false, | |
radix: 2, | |
opacity: 0.6, | |
indexSlideStack: [], | |
}; | |
Blur.propTypes = { | |
radix: T.number, | |
isIndex: T.bool, | |
children: T.node, | |
style: T.object, | |
wrapperStyle: T.oneOfType([ | |
T.array, | |
T.object, | |
]), | |
opacity: T.number, | |
indexSlideImage: T.string, | |
indexSlideStack: T.array, | |
}; | |
export default radium(Blur); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage