#29CM
#적응형
#5일
#scss
#jquery
#javascript
#gsap
#리뉴얼
clip-path
를 활용한 스크롤 애니메이션.data-
프로퍼티 활용.✏️ preview
1) 헤드라인 텍스트 스크럽 모션 (공통)
gsap.utils.toArray('.recipe .headline').forEach(element => {
gsap.to(element,{
scrollTrigger:{
trigger:element.parentElement,
start:"0% 100%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
end:"100% 0%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
// markers:true,
scrub: 1,
},
xPercent:-100,
})
});
🖋 code review
- forEach 문을 활용한 반복 레이아웃 처리. 반복되는 레이아웃의 각 부모를 (
trigger:element.parentElement,
) 스크롤 트리거 기준으로 잡는다.
2) group-grid 텍스트 모션 (공통)
gsap.utils.toArray('.column-right .wrap > *').forEach(element => {
gsap.to(element,{
scrollTrigger:{
trigger:element.parentElement.parentElement.parentElement,
start:"0% 50%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
end:"100% 80%",
// markers:true,
},
stagger:.3,
yPercent:0,
opacity:1,
delay: .5
})
});
😇 아쉬운 점
- 트리거를 잡을 때, 부모 요소에 해당하는 요소들에 공통 class 를 주고 js에 선언하면 코드를 보다 효율적으로 줄일 수 있었을 것.
BEFORE
parentEl = $(this).parents('.scroll-parent');
trigger:element.parentElement.parentElement.parentElement,
AFTER
parentEl = $(this).parents('.scroll-parent');
trigger: parentEl,
✔️ clip-path 란??
- clip-path 속성을 정의하게 되면, 요소의 일부분을 잘라낼 수 있다.
.arch{
margin-top: 20vh;
.picture{
overflow: hidden;
transition: 1s;
clip-path: circle(20% at 50% 100%);
}
}
gsap.to(element,{
scrollTrigger:{
trigger:element.parentElement,
start:"0% 50%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
end:"100% 80%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
// markers:true,
// scrub:0.4,
},
'clip-path': 'circle(71.4% at 49% 51%)'
})
🖋 code review
clip-path: circle(20% at 50% 100%);
에서 해당 스크롤 트리거에 도달했을 시,'clip-path': 'circle(71.4% at 49% 51%)'
로 변환하여라.
👉 css clip-path maker 사이트 : https://bennettfeely.com/clippy/
gsap.to('.footer .txt-flow-area .link-home',20,{xPercent:-100,repeat:-1,ease:'none',})
🖋 code review
gsap.to('선택자',20,{xPercent:-100,repeat:-1,ease:'none',})
: 20초 동안 x축 방향 -100만큼 이동된 상태, -1방향으로 반복재생 하여라.
data-
프로퍼티 활용.✔️
data-
프로퍼티
- 해당 요소에 사용자가 임의로 지정한 속성값을 활용할 수 있다. 이를 커스텀 데이터 속성(custom data attributes) 이라고 부르며,
data-
를 앞에 붙여서 속성명을 지정하고 값을 부여한다.data-
프로퍼티의 DOM 접근 방식
-엘리먼트노드.dataset.새데이터셋속성이름 = "속성값";
👇 이렇게 사용해요! 👇
html에 직접 속성값을 지정한다.
Js
const introTextList = document.querySelectorAll('.sc-intro .box-wrap .overflow-hidden');
introTextList.forEach(element => {
dataX = element.dataset.x;
// 엘리먼트에 dataset의 x값을 가지고 와라.
gsap.to(element,{
scrollTrigger:{
trigger:".sc-intro .box-wrap",
start:"0% 0%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
end:"100% 10%", //[트리거기준 꼭대기] [윈도우좌표 꼭대기]
// markers:true,
scrub:0.4,
},
xPercent:dataX
})
});
🖋 code review
dataX = element.dataset.x;
: 엘리먼트에서 dataset의 x값을 가지고 와라. (프로퍼티 접근 : 엘리먼트노드.dataset.새데이터셋속성이름 = "속성값";)xPercent:dataX
: html에 지정해둔 data-x 값만큼xPercent
(지정된 x좌표값)만큼 움직여라.
.group-grid{
display: grid;
grid-template-columns: 1.5fr 1.3fr;
.column-left{
margin-top: 6vw;
padding: 0 0 0 8.2vw;
.note{
text-transform: uppercase;
padding: 8vw 24.6vw 0 0;
font-size: 0.97vw;
&::before{
content: '*';
display: block;
font-family: 'NeueWorld', sans-serif;
line-height: 0.4;
font-size: 4vw;
}
}
}
.column-right{
margin-top: 23vw;
padding: 0 5vw;
.title{
padding-bottom: 1.4vw;
}
.wrap{
.desc:not(:first-child){
margin-top: 2vw;
}
}
}
.desc{
line-height: 1.7;
font-size: 1vw;
padding-top: 2vw;
span{
display: block;
}
}
.desc-tit{
margin-bottom: 1.2vw;
font-size: 1.5vw;
font-style: italic;
display: block;
}
}
✅ Tips
메인, 서브에 걸쳐 재사용 할 수 있는 소형 레이아웃의 경우 scss폴더를 별도로 만들어 관리하면 유지보수에 도움이 될 듯 하다.
✔️ 구현하고자 했던 효과.
스크롤을 아래로 내렸을 시 헤더가 사라지고, 스크롤을 위로 올렸을 시 헤더가 나타나게끔.
✔️ 구현하고자 했던 이유.
유저 플로우를 고려했을 때, 스크롤을 내리는 동안에는 보편적으로 컨텐츠를 확인하기 위한 목적일 때가 많고, 다시 위로 올라갈 때는 다른 페이지로 넘어가기 위한 목적이 많으므로 위와 같이 설정키로 결정.
let lastScroll = 0;
$(window).scroll(function () {
curr = $(this).scrollTop();
if (curr > lastScroll) {
$('header').addClass('hide');
} else {
$('header').removeClass('hide');
}
lastScroll = curr;
})
🖋 code review
curr = $(this).scrollTop();
: 현재 스크롤 위치.let lastScroll = 0;
: 스크롤 시작점 값 선언.if (curr > lastScroll) { $('header').addClass('hide); } else { $('header').removeClass('hide'); }
: 현재 스크롤 위치가 타겟 섹션에 도달하기까지의 스크롤 값과 같거나 크다면header
태그에 classhide
을 붙이고, 그게 아니라면 지운다.lastScroll = curr;
: 값이 0인lastScroll
이 현재 스크롤 위치값(curr
)과 동일하게 설정됐으므로, 스크롤이 조금이라도 내려가면header
태그에 classhide
가 붙고 아닐 시 classhide
가 없어진다.
# 특징 : 반복되는 레이아웃이 굉장히 많은 프로젝트.
위와 같은 이유로 scss에서의 마크업, 그리고 js 코드를 짤 때 좀 더 효율적인 방법을 찾으려고 노력했다. 대부분 forEach문을 활용하여 반복되는 코드를 줄였는데, 완성하고 난 뒤 떠오른 부분은 아쉬운대로 본 문서에 따로 정리해두었다.