Skip to content

Instantly share code, notes, and snippets.

@omarkhatibco
Last active November 27, 2023 22:05
Show Gist options
  • Save omarkhatibco/e3c48108cd79d2889914de0830ec4ab8 to your computer and use it in GitHub Desktop.
Save omarkhatibco/e3c48108cd79d2889914de0830ec4ab8 to your computer and use it in GitHub Desktop.
Counter with react-countup only when the counter in viewport
import Counter from './counter';
const App = () => (
<div className='flex flex-wrap justify-between md:justify-center'>
<Counter target={150} title='Customer' duration={1} />
<Counter target={20000} title='Rooms' duration={2} />
<Counter target={40000} title='Places' duration={3} />
<Counter target={1200000} title='Users' duration={4} />
</div>
);
export default App;
import { useInView } from 'react-intersection-observer';
import CountUp from 'react-countup';
const Counter = ({ target, title, duration }) => {
const [ref, inView] = useInView({
threshold: 0.3,
triggerOnce: true,
});
return (
<div className='w-full md:w-1/4 p-2 md:p-4 text-center flex flex-col items-center' ref={ref}>
<CountUp
start={0}
end={inView ? target : 0}
duration={duration}
separator='.'
useEasing={true}>
{({ countUpRef }) => (
<span className='text-2xl md:text-4xl font-black leading-none' ref={countUpRef} />
)}
</CountUp>
<p
className={`font-bold text-lg animation delay ${
inView === true ? 'opacity-100 transform-show' : 'opacity-0 transform-hide'
}`}>
{title}
</p>
<style jsx>{`
.delay {
transition-delay: ${duration}s;
}
.transform-hide {
transform: translate3d(0, 1rem, 0);
}
.transform-show {
transform: translate3d(0, 0, 0);
}
`}</style>
</div>
);
};
export default Counter;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment