|
1 | | -import { motion } from 'framer-motion'; |
| 1 | +import { motion, useScroll, useTransform } from 'framer-motion'; |
2 | 2 | import { Box, VStack } from '@chakra-ui/react'; |
3 | 3 | import { ProjectsData } from '@data'; |
4 | 4 | import 'react-responsive-carousel/lib/styles/carousel.min.css'; |
5 | 5 | import ProjectItem from './ProjectItem'; |
6 | 6 | import { WavyBackground } from '@components'; |
7 | 7 | import HeroText from './HeroText'; |
| 8 | +import { useRef } from 'react'; |
8 | 9 |
|
9 | 10 | const Projects = () => { |
| 11 | + const ref = useRef(null); |
| 12 | + const base = [400, 600, 1000, 1400]; |
| 13 | + const project1Ref = useRef<HTMLDivElement>(null); |
| 14 | + const { scrollY } = useScroll({ target: ref }); |
| 15 | + const opacity1 = useTransform(scrollY, base, [0, 1, 1, 0]); |
| 16 | + const height1 = project1Ref.current?.clientHeight; |
| 17 | + const opacity2 = useTransform( |
| 18 | + scrollY, |
| 19 | + base.map((i) => i + (height1 ?? 550)), |
| 20 | + [0, 1, 1, 0], |
| 21 | + ); |
| 22 | + |
| 23 | + const heroOpacity = useTransform( |
| 24 | + scrollY, |
| 25 | + base.map((i) => i + 550), |
| 26 | + [1, 1, 1, 0], |
| 27 | + ); |
| 28 | + |
| 29 | + const project1 = ProjectsData[0]; |
| 30 | + const project2 = ProjectsData[1]; |
| 31 | + |
10 | 32 | return ( |
11 | | - <VStack minH={'100vh'} width={'100vw'} id="projects" rowGap={20}> |
12 | | - <HeroText /> |
13 | | - <Box position={'sticky'} top={'0'}> |
| 33 | + <VStack minH={'100vh'} width={'99vw'} id="projects" rowGap={20} ref={ref}> |
| 34 | + <HeroText opacity={heroOpacity} /> |
| 35 | + <Box position={'sticky'} top={'15vh'} transform={'translateY(-120px)'}> |
14 | 36 | <WavyBackground /> |
15 | 37 | </Box> |
16 | | - {ProjectsData.map((project) => ( |
17 | | - <motion.div |
18 | | - style={{ |
19 | | - position: 'sticky', |
20 | | - top: '25vh', |
21 | | - }} |
22 | | - key={project.title} |
23 | | - > |
24 | | - <ProjectItem {...project} /> |
25 | | - </motion.div> |
26 | | - ))} |
| 38 | + <motion.div |
| 39 | + style={{ |
| 40 | + opacity: opacity1, |
| 41 | + position: 'sticky', |
| 42 | + top: '25vh', |
| 43 | + }} |
| 44 | + > |
| 45 | + <ProjectItem {...project1} /> |
| 46 | + </motion.div> |
| 47 | + <motion.div |
| 48 | + style={{ |
| 49 | + opacity: opacity2, |
| 50 | + position: 'sticky', |
| 51 | + top: '25vh', |
| 52 | + }} |
| 53 | + > |
| 54 | + <ProjectItem {...project2} /> |
| 55 | + </motion.div> |
| 56 | + ); |
27 | 57 | </VStack> |
28 | 58 | ); |
29 | 59 | }; |
|
0 commit comments