-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SP2] 메인페이지 상단 두번째 섹션 애니메이션 #288
Conversation
디자이너와 논의 후 추가 작업 사항입니다. (논의 슬랙 스레드)
2023-11-17.9.57.30.mov |
useEffect(() => { | ||
const unsubscribe = scrollValue.on('change', (value) => { | ||
setClipPathValue(`inset(0% ${value} 0% 0%)`); | ||
}); | ||
|
||
return () => { | ||
unsubscribe(); | ||
}; | ||
}, [scrollValue]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
처음에는 아래와 같이 코드를 작성하였는데 이상하게 isMobileSize
일때 clipPath Style
이 처음에는 정상적으로 'none'으로 적용되어있다가 스크롤을 하게 되면 clipPathValue
이 적용이 되더라고요...! opacity Style
은 화면 크기에 따라 정상적으로 스타일이 적용되던데... clipPath Style
만 안되었습니다...!
이를 해결하기 위해 clipPathValue
를 useMotionTemplate
이 아니라 useState
로 관리하니 정상적으로 작동이 되었습니다!
혹시 이부분에 대해 아신다면 알려주세요 😭 (2시간정도 삽질은 해봤는데 이유를 못찾았습니다....)
const scrollValue = useTransform(scrollYProgress, [1, 0.4], ['100%', '0%']);
const opacityValue = useTransform(scrollYProgress, [1, 0.4], ['0%', '100%']);
const scaleValue = useTransform(scrollYProgress, [1, 0.4], [0.9, 1]);
const clipPathValue = useMotionTemplate`inset(0% ${scrollValue} 0% 0%)`;
const content = '전국 최대 규모의 대학생 IT 연합 동아리, SOPT를 소개합니다.';
return (
<S.Background ref={contentRef}>
<S.Wrapper>
<S.Textcontainer style={{ scale: scaleValue }}>
<S.MotionTitle
style={{
clipPath: isMobileSize ? 'none' : clipPathValue, // 여기 코드가 문제
opacity: isMobileSize ? opacityValue : 1,
}}
data-text={content}
/>
<S.BackgroundTitle>{content}</S.BackgroundTitle>
</S.Textcontainer>
</S.Wrapper>
</S.Background>
);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이것은 아마 useIsMobile 훅의 문제인 것 같습니다 ... 모든 상황에서 꼭 제대로 동작하지는 않는 것 같아요
나중엔 모바일 ui랑 데탑 ui 코드를 아예 따로 써야 할 수도 있을 것 같아용
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사실 모바일일 때는 저것을 사용하지 않는데 계속 clipPathValue
를 들고 있는 것도 엄청 좋은 사례는 아닌 것 같습니다 ..!!!
저는 현재 코드 또한 모바일이랑 데탑이랑 나눠서 짠 후 조건부 렌더링하셔도 좋을 것 같아용
MotionTitle 부분만 따로 컴포넌트로 빼고, 백그라운드타이틀 부분은 그대로 칠드런으로 넘겨주면 현재 구조에서 크게 바뀌는 점 없을 것입니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
음 그렇군요! useIsMobile 함수가 있는데 제대로 되지 않는거라면,, 아예 이 코드를 사용하지 않는 방안을 채택해야할 것 같네요!
useIsMobile 함수 작동에 대해 체크 해보고 새로 코드를 짜면서 구조도 다시한번 고민해볼게요!
<S.Title>전국 최대 규모의 대학생 IT 연합 동아리, SOPT를 소개합니다.</S.Title> | ||
<S.Background ref={contentRef}> | ||
<S.Wrapper> | ||
<S.Textcontainer style={{ scale: scaleValue }}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TextContainer로 해주시면 좋을 것 같습니다~!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인 감사해요!!
const contentRef = useRef<HTMLElement>(null); | ||
const { scrollYProgress } = useScroll({ | ||
target: contentRef, | ||
offset: ['end center', 'start start'], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
comment;
'start start'같이 반복되는 경우 'start' 하나로 축약 가능하다고 합니다!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오오 그렇군요!
<S.MotionTitle | ||
style={{ | ||
opacity: opacityValue, | ||
}} | ||
data-text={content} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
짧아서 개행 없이 한 줄로 작성 가능할 거 같아요..! (지금은 eslint로 인해 style에 개행이 있어서 이렇게 된 것)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
저는 cmd+S 누르면 자동으로 개행이 되는데 이런 부분이 있으면 제 로컬에서 eslint를 주석처리 하고 저장해서 커밋하면 되나요?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재 아래에 제시해준 코드로 수정해서 개행없이 <S.MotionTitle style={style} data-text={content} />;
이렇게 작성됩니다!
그래도 추후에 이런 상황에 어떻게 해야할지 궁금해요!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style={{opacity: opacityValue,
}}
이렇게 스타일 객체에서 opacity 개행을 없애고 cmd+s를 하면 아마 한줄로 바뀌었을 거예요!!
const unsubscribe = scrollValue.on('change', (value) => { | ||
const percentValue = Number(value.split('%')[0]); | ||
isMobileSize | ||
? setOpacityValue((100 - percentValue) / 100) | ||
: setClipPathValue(`inset(0% ${percentValue}% 0% 0%)`); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
지금 상태를 두 개 사용하고 있는데 style 상태를 하나 만들어도 될 것 같아요
const unsubscribe = scrollValue.on('change', (value) => { | |
const percentValue = Number(value.split('%')[0]); | |
isMobileSize | |
? setOpacityValue((100 - percentValue) / 100) | |
: setClipPathValue(`inset(0% ${percentValue}% 0% 0%)`); | |
}); | |
const unsubscribe = scrollValue.on('change', (value) => { | |
const percentValue = Number(value.split('%')[0]); | |
const newStyle = isMobileSize | |
? { opacity: (100 - percentValue) / 100 } | |
: { clipPath: `inset(0% ${percentValue}% 0% 0%)` }; | |
setStyle(newStyle); | |
}); |
이렇게 하면 조건부 렌더링 없이 다음처럼 작성할 수 있을 것 같습니다..!!
<S.MotionTitle style={style} data-text={content} />
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
두개의 스타일을 분리하려고만 하다보니 하나의 스타일로 합치는걸 생각못했네요...! 좋은 의견 감사해요!!
content: string; | ||
} | ||
|
||
export default function MotionTitle({ contentRef, content }: MotionTitleProps) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
멋진 방법이네요 ..!!
저는 모바일/데탑에 대해 아예 다른 컴포넌트를 리턴하는 것을 생각하였는데,
요렇게 하는 거라면 useMotionTitle
훅을 만들어서 Introduce/index.tsx 에서 호출해서 사용해도 괜찮을 것 같다는 생각이 들었습니당
containerRef 받아서 style 을 리턴하는 형태가 생각됩니다!!
그러나 이대로도 좋습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MotionTitle을 컴포넌트 말고, 훅으로 호출해서 사용하는 것의 이점이 있나요?!
Summary
close #283
디자이너 레퍼런스
2023-11-08.18.44.49.mov
Screenshot
데스크탑, 모바일 애니메이션 효과입니다.
2023-11-17.2.03.38.mov
Comment
scale은 디자이너에게 물어보고 수정이 필요하면 조정하겠습니다!