이번에 하는 한이음프로젝트 'BlueRoof'에서 평소처럼 랜딩페이지를 평범하게 개발하고 있었다.
근데 이번 프로젝트는 청약 관련 서비스인만큼 신뢰도 있어 보이는 랜딩페이지를 만들고 싶었고 평범하게 가지말고 애니메이션을 좀 넣어보기로 했다.
평소에 멋진 랜딩페이지들을 보면서 배우고 싶었기도 했고 ...
무엇보다 랜딩페이지는 사용자들이 처음으로 보는 페이지니까 완성도 있게 만들어야한다고 생각했다! (왜 지금까지 했던 과거 프로젝트들에서는 이 생각을 못했을까..)
처음으로 생각난건 아래로 스크롤을 내릴때 샤라락하고 페이지 넘어가듯 아래로 내려가는 애니메이션이다.
알아보니 fullpage라고 불리는 애니메이션이었고 주로 fullPage.js를 사용하는 것 같았다.
하지만 fullPage.js는 유료로 라이선스를 구매해야하므로
나는 간단히 react-fullpage를 설치해 사용했다.
https://youtu.be/a_f4vsNlKek (이 영상을 참고하였다)
npm i @ap.cx/react-fullpage
<FullPage>
<FullpageNavigation/>
<FullPageSections>
<FullpageSection style={SectionStyle}>
<Landing1/>
</FullpageSection>
<FullpageSection style={SectionStyle}>
<Landing2/>
</FullpageSection>
<FullpageSection style={SectionStyle}>
<Landing3/>
</FullpageSection>
<FullpageSection style={SectionStyle}>
<Landing4/>
</FullpageSection>
</FullPageSections>
</FullPage>
다음으로는 Landing2 컴포넌트 내에서 각 요소들이 순차적으로 보여지게끔 하고 싶었다.
찾아보니 gsap 라는 라이브러리가 있었다!
(참고한 자료들)
https://greensock.com/docs/v3/Installation
npm i gsap
const Landing2 = () => {
const refs=useRef([]);// ref는 배열로 관리
const textRef=useRef();
useEffect(()=>{
gsap.registerPlugin(ScrollTrigger);
refs.current.forEach(function(textanimation,index){
gsap.to(textanimation,1,{
//메인페이지 렌더링 되자마자가 아니라 두번째 랜딩페이지로 오면 애니메이션 실행되도록
scrollTrigger:refs.current[0],
delay:(index + 1) * .6,
opacity:1
})
});
gsap.to(textRef.current,1,{
scrollTrigger:refs.current[0],
delay:1,
opacity:1
})
},[])
return (
<Landing2Container>
<Img src='../../imgs/landing2_sample.svg' ref={(el)=>refs.current[0]=el} ></Img>
<RowContainer style={{width:"100%",height:"100%", gap: "30px", marginTop: "30px"}}>
<Img src='../../imgs/landing2_sample.svg' ref={(el)=>refs.current[1]=el} ></Img>
<Img src='../../imgs/landing2_sample.svg' ref={(el)=>refs.current[2]=el} style={{marginBottom:"70px"}}></Img>
</RowContainer>
<TextContainer ref={textRef}>
<BlackText weight={"600"} size={"40px"} style={{textAlign:"center"}}>미리 개인정보를 입력해두고 편하게<br/>조건 검사 해보세요!</BlackText>
<GrayText size={"14px"} marginTop={"10px"}>상세한 개인정보 문항을 통해 더욱 자세하고 정확한 조건 검사가 가능해요</GrayText>
</TextContainer>
</Landing2Container>
)
}
export default Landing2
1. 이미지 3개가 순차적으로 나타나야함
✔️ forEach(function(각각의 요소,index){})를 통해 index를 사용하여 이미지 3개가 서로 0.6초의 차이를 두고 나타날 수 있도록 하였음
✔️gsap.to(요소, 지속시간, 옵션) 을 사용하여 애니메이션 지정
일단 기본값으로 이미지들의 opacity를 0으로 주고
(index+1)*0.6 초 후에 opacity가 1이 되도록 애니메이션 구현
2. ref 여러개를 배열로 관리
이미지 3개를 가리키는 ref를 따로 만들어 두면 코드가 길어지고 delay 지정도 (index+1)*0.6 가 아닌 각각 지정해줘야 해서 비효율적임
✔️ ref를 배열로 관리
const refs=useRef([]);로 배열을 생성하고
각 img들마다 ref={(el)=>refs.current[0]=el} 이런식으로 ref 지정.
이렇게 되면 refs.current.foreach(function( ... ) ...) 를 통해 효율적인 코드 가능
3. 스크롤이 해당 컴포넌트까지 내려왔을 때 애니메이션 시작되어야함.
랜딩페이지가 렌더링 되자마자 스크롤을 내려야만 보이는 Landing2 컴포넌트의 애니메이션이 시작되는 문제가 생겼다. 그래서 뒤늦게 스크롤을 내리면 이미 img 요소들이 다 나타나있는 상태.....
✔️scrollTrigger 활용
scrollTrigger : refs.current[0]을 통해 애니메이션의 시작 시간을 지정해주었다. 첫 img가 보여지는 순간! 그때 시작을 해라 !
Landing3 부분에서 적용하고 싶었던 애니메이션은
사진을 하나씩 보여주되 옆으로 넘길 수 있는 기능!
이 랜딩페이지에서는 여러 사진을 다 보여주고 싶은데 깔끔한 디자인을 위해 이러한 애니메이션을 찾아보았고
react-slick 으로 carousel을 만들기로 결정!
(참고자료)
https://sirong.tistory.com/38
https://velog.io/@pixelstudio/React-Slick%EC%9C%BC%EB%A1%9C-%EC%BA%90%EB%9F%AC%EC%85%80-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0
npm i react-slick
npm i slick-carousel
import "slick-carousel/slick/slick.css";
import "slick-carousel/slick/slick-theme.css";
<StyledSlider {...settings}>
<Img src='../../imgs/landing3_sample1.svg'></Img>
<Img src='../../imgs/landing3_sample2.svg'></Img>
<Img src='../../imgs/landing3_sample3.svg'></Img>
<Img src='../../imgs/landing3_sample4.svg'></Img>
<Img src='../../imgs/landing3_sample5.svg'></Img>
<Img src='../../imgs/landing3_sample6.svg'></Img>
<Img src='../../imgs/landing3_sample7.svg'></Img>
</StyledSlider>
dots: true, // 슬라이드 밑에 점 보이게
infinite: true, // 무한으로 반복
speed: 500, // 넘기는 속도
autoplay: false, // 자동으로 넘김
autoplaySpeed: 2000, //자동으로 넘어가는 속도
slidesToShow: 1, // 스크린에 보여지는 슬라이드 개수
slidesToScroll: 1, // n장씩 뒤로 넘어가게 함
centerMode: true, // 중앙정렬
centerPadding: "0px", // 0px 하면 슬라이드 끝쪽 이미지가 안잘림
nextArrow: <> // 슬라이드 좌우 넘기기 커스텀 버튼
prevArrow: <> //슬라이드 좌우 넘기기 커스텀 버튼