Skip to content

Instantly share code, notes, and snippets.

@swashata
Created September 19, 2020 08:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swashata/0729604d3d7dc363a046bc05f6183458 to your computer and use it in GitHub Desktop.
Save swashata/0729604d3d7dc363a046bc05f6183458 to your computer and use it in GitHub Desktop.
AnimateIn
import React from 'react';
import styled, { useTheme } from 'styled-components';
import { useSpring, animated } from 'react-spring';
import VisibilityObserver, {
useVisibilityObserver,
} from 'react-visibility-observer';
export const CONTROLCLASS = 'wpeform-component-animatein';
const Container = styled.div`
perspective: 600px;
`;
const AnimateInContainer = styled(animated.div)`
will-change: opacity, transform;
`;
export type AnimateInProps = {
/**
* Children of AnimateIn component.
*/
children: React.ReactNode;
};
function AnimateChild(props: AnimateInProps) {
const { isVisible } = useVisibilityObserver();
const theme = useTheme();
const styleProps = useSpring({
opacity: isVisible ? 1 : 0,
transform: isVisible
? 'translate3d(0px, 0, 0px)'
: 'translate3d(60px, 0, -100px)',
config: theme.springConfigGeneral,
});
return (
<Container className={CONTROLCLASS}>
<AnimateInContainer style={styleProps}>
{props.children}
</AnimateInContainer>
</Container>
);
}
/**
* An AnimateIn component to declaratively animate a component in when it
* comes within the viewport. It uses IntersectionObserver under the hood.
*
* It animates the children components only once when offset from the bottom
* is 50px.
*/
export default function AnimateIn(props: AnimateInProps) {
return (
<VisibilityObserver
triggerOnce
rootMargin="0px 0px -50px 0px"
threshold={0}
>
<AnimateChild {...props} />
</VisibilityObserver>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment