Last active
April 5, 2017 14:26
-
-
Save RyanCCollins/1a09d299f26ae53880803c044d5b2a3e to your computer and use it in GitHub Desktop.
With Animation HOC; styled-components animation made easy
This file contains hidden or 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
| // See original source here: https://github.com/RyanCCollins/the-agency/tree/master/packages/ui/src/WithAnimation | |
| import * as React from 'react'; | |
| import { ThemedCssFunction } from 'styled-components'; | |
| import Animation from './animation'; | |
| import { AnimationType } from './types'; | |
| export interface Props { | |
| type?: AnimationType; | |
| isVisible: boolean; | |
| children?: JSX.Element; | |
| duration?: number; | |
| delay?: number; | |
| css?: ThemedCssFunction<{}>; | |
| } | |
| type HOC = (props: Props) => JSX.Element; | |
| const WithAnimation: HOC = ({ | |
| duration = 1000, | |
| type = 'fadeIn', | |
| children, | |
| delay = 0, | |
| ...props, | |
| }) => ( | |
| <Animation type={type} duration={duration} {...props}> | |
| {children} | |
| </Animation> | |
| ); | |
| export default WithAnimation; |
This file contains hidden or 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 styled, { css } from 'styled-components'; | |
| import { Props } from './types'; | |
| function styles(props: Props) { | |
| const opacity = props.isVisible ? 1.0 : 0.0; | |
| const transform = props.isVisible ? 0 : 20; | |
| switch (props.type) { | |
| case 'fadeIn': | |
| return css` | |
| opacity: ${opacity}; | |
| `; | |
| case 'fadeInUp': | |
| return css` | |
| opacity: ${opacity}; | |
| transform: translateY(${transform}%); | |
| will-change: transform, opacity; | |
| `; | |
| default: | |
| return ''; | |
| } | |
| } | |
| function transition(props: Props) { | |
| const duration = 600; | |
| return css` | |
| transition: transform ${duration / 2}ms ease, opacity ${duration}ms ease-out; | |
| `; | |
| } | |
| function delay({ delay }: Props) { | |
| return css` | |
| animation-delay: ${delay}ms; | |
| `; | |
| } | |
| export default styled.div` | |
| ${(props: Props) => styles(props)} | |
| ${(props: Props) => transition(props)} | |
| ${(props: Props) => delay(props)} | |
| ${(props: Props) => props.css} | |
| `; |
This file contains hidden or 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
| // Original Source From here: https://github.com/RyanCCollins/the-agency/blob/master/src/client/containers/Home/presentation.tsx | |
| import * as React from 'react'; | |
| import { findDOMNode } from 'react-dom'; | |
| import { Hero, Headline, Image, Box, WithAnimation, Button } from 'ui'; | |
| import { StateProps } from './types'; | |
| import Wrapper from './styles'; | |
| interface State { | |
| section1: boolean; | |
| section2: boolean; | |
| } | |
| export default class Presentation extends React.Component<StateProps, State> { | |
| constructor() { | |
| super(); | |
| this.handleScroll = this.handleScroll.bind(this); | |
| this.state = { | |
| section1: false, | |
| section2: false, | |
| }; | |
| } | |
| public componentDidMount() { | |
| if (typeof window !== 'undefined') { | |
| window.addEventListener('scroll', this.handleScroll); | |
| } | |
| } | |
| private section1Ref: Element; | |
| private section2Ref: Element; | |
| private handleScroll() { | |
| const windowHeight = window ? window.innerHeight : 1000; | |
| const section1Node = findDOMNode(this.section1Ref); | |
| const section2Node = findDOMNode(this.section2Ref); | |
| const section1 = section1Node.getBoundingClientRect().top < windowHeight / 2; | |
| const section2 = section2Node.getBoundingClientRect().top < windowHeight / 2; | |
| this.setState({ | |
| section1, | |
| section2, | |
| }); | |
| } | |
| public render() { | |
| return ( | |
| <Wrapper> | |
| <Hero backgroundColor="#03A9F4"> | |
| <Box alignItems="center" style={{ minHeight: 'calc(100vh - 100px)' }} justifyContent="center"> | |
| <Image | |
| alt="The Agency" | |
| src="https://github.com/RyanCCollins/cdn/blob/master/misc/rocket.png?raw=true" | |
| size={300} | |
| /> | |
| <Headline color="white"> | |
| The Agency | |
| </Headline> | |
| </Box> | |
| </Hero> | |
| <div ref={(ref) => { this.section1Ref = ref; }}> | |
| <Hero backgroundColor="#9c27b0"> | |
| <Box alignItems="center" style={{ minHeight: 'calc(100vh - 100px)' }} justifyContent="center"> | |
| <Box style={{ maxWidth: 576 }} justifyContent="center"> | |
| <WithAnimation type="fadeInUp" isVisible={this.state.section1}> | |
| <Headline color="white"> | |
| We are a dedicated digital agency | |
| </Headline> | |
| </WithAnimation> | |
| </Box> | |
| </Box> | |
| </Hero> | |
| </div> | |
| <div ref={(ref) => { this.section2Ref = ref; }}> | |
| <Hero backgroundColor="#ff9800"> | |
| <Box alignItems="center" style={{ minHeight: 'calc(100vh - 100px)' }} justifyContent="center"> | |
| <Box style={{ maxWidth: 576 }} justifyContent="center"> | |
| <WithAnimation type="fadeInUp" isVisible={this.state.section2}> | |
| <Headline color="white"> | |
| We build scalable solutions for the web and mobile platforms | |
| </Headline> | |
| <Button | |
| borderColor="#fff" | |
| backgroundColor="transparent" | |
| onClick={(e) => e} | |
| label="See Case Studies" | |
| /> | |
| </WithAnimation> | |
| </Box> | |
| </Box> | |
| </Hero> | |
| </div> | |
| </Wrapper> | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment