Skip to content

Instantly share code, notes, and snippets.

@fantasywind
Last active August 22, 2016 17:58
Show Gist options
  • Save fantasywind/582a8aafc75ae3687529054081bda230 to your computer and use it in GitHub Desktop.
Save fantasywind/582a8aafc75ae3687529054081bda230 to your computer and use it in GitHub Desktop.
<Blur /> React Component Wrapper [iOS_Frosted_Glass_Effect]
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);
@fantasywind
Copy link
Author

Usage

<Blur opacity={0.6} radix={3} wrapperStyle={styles.headerWrapperStyle}>
   <Header />
</Blur>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment