Skip to content

Instantly share code, notes, and snippets.

@hew
Last active Dec 5, 2019
Embed
What would you like to do?
Animated Text (React Spring)

animated text (react spring)

/** @jsx jsx */
import React, {useState} from 'react';
import {jsx} from 'theme-ui';
import {useTrail, animated} from 'react-spring';
import {Box, Text} from '@theme-ui/components';
const textStyle = {
position: 'relative',
width: '100%',
height: '80px',
lineHeight: '80px',
color: 'black',
fontSize: '5em',
fontWeight: 800,
textTransform: 'uppercase',
willChange: 'transform, opacity',
overflow: 'hidden'
};
const config = {mass: 5, tension: 2000, friction: 200};
const items = [<Text sx={{color: 'pink'}}>Matthew</Text>, <Text sx={{color: 'pink'}}>Jones</Text>];
const items2 = [<Text sx={{color: 'gray'}}>React</Text>, <Text sx={{color: 'gray'}}>Developer</Text>];
const Items = ({items}) => {
const [toggle, set] = useState(true);
const trail = useTrail(items.length, {
config,
opacity: toggle ? 1 : 0,
x: toggle ? 0 : 20,
height: toggle ? 80 : 0,
from: {opacity: 0, x: 20, height: 0}
});
return trail.map(({x, height, ...rest}, index) => {
return (
<animated.div
key={index}
style={{
...rest,
...textStyle,
transform: x.interpolate((x) => `translate3d(0,${x}px,0)`)
}}>
<animated.div style={{height, overflow: 'hidden'}}>{items[index]}</animated.div>
</animated.div>
);
});
};
export default () => {
return (
<>
<Items items={items} />
<Items items={items2} />
</>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment