LOCUS-X는 GSAP 라이브러리를 활용한 효과와 CSS 전처리기 SCSS 사용을 중점으로 작업했습니다.
SCSS 사용
1-1. 폴더 구조
1-2. 활용 방법
1-3. 반응형
GSAP 사용
2-1. 텍스트 모션
2-2. 마우스 이벤트
2-3. 횡스크롤
이 프로젝트 부터는 SCSS를 사용했습니다.
SCSS 아키텍처 7-1 패턴 폴더구조를 사용하여 스타일 시트를 기능별로 분리하여 재사용성을 높였습니다.
7-1 패턴 : 7개의 폴더(abstracts, vendors, base, components, layout, page, themes)와 1개의 파일을 가지는 패턴
크게 역할에 따라 abstracts, base, components, layout, page 폴더로 나누어 각 scss 파일들을 저장한뒤, style.scss 파일에서 모든 파일을 import 하는 방식입니다.
각 폴더의 역할
- abstracts: 전역 변수와 믹스인에 대한 폴더
- base: 사이트 전반에 걸쳐서 재사용되는 스타일을에 대한 폴더 (폰트, 리셋 등)
- layout: 사이트에서 공통적으로 사용되는 레이아웃 스타일에 대한 폴더
- components: 사이트에서 재사용 가능한 소형 컴포넌트 (버튼, 폼 등) 스타일에 대한 폴더
- page: 특정 페이지에 한정된 스타일에 대한 폴더
기존에 CSS만 사용했을 때와 다르게 상위 선택자 반복 사용을 피해 가독성을 높입니다.
.gnb {
position: fixed;
top: 0; left: 0;
.gnb-bg {
position: absolute;
top: 0; left: 0;
width: 100%; height: 0;
}
}
자주 사용되는 색상, 폰트 사이즈를 변수로 사용했습니다.
/* COLOR */
$color-white: #fff;
$color-black: #000;
$bg-color-dark-1: #181818;
/* FONT SIZE */
$font-size-heading1: clamp(5.4rem, 7vw, 12.6rem);
$font-size-heading2: clamp(4.6rem, 6vw, 10.2rem);
$font-size-heading3: clamp(4.0rem, 5vw, 8rem);
$font-size-heading4: clamp(3.2rem, 3vw, 5.2rem);
$font-size-body1: clamp(2.4rem, 4vw, 3.2rem);
$font-size-body2: clamp(1.8rem, 2vw, 2.4rem);
$font-size-body3: clamp(1.5rem, 1.6vw, 1.8rem);
$font-size-body4: 1.3rem;
공통으로 사용되는 마우스 오버 스타일, 반응형 분기점, 레이아웃 정렬 등을 믹스인으로 만들어 사용했습니다.
/* HOVER */
@mixin linkHover($height: 2px) {
&::after {
content: '';
position: absolute;
bottom: 0; right: 0;
height: $height; width: 0;
background-color: $color-white;
transition: 0.3s;
}
&:hover::after {
width: 100%;
left: 0;
}
}
/* RESPONSIVE */
@mixin tablet {
@media (max-width: 1023px) { @content; }
}
@mixin mobile {
@media (max-width: 767px) { @content; }
}
/* LAYOUT */
@mixin flexCenter() {
display: flex;
justify-content: center;
align-items: center;
}
.
.
.
반응형 분기점은은 1023px 이하 태블릿, 767px 이하 모바일로 작업했고
반응형 작업이 필요한 코드에 믹스인을 사용해주는 방식으로 적용했습니다.
.inner {
padding: 0 120px;
@include tablet { padding: 0 20px; }
}
폰트 사이즈는 rem
을 기본 단위로 사용하고
상위 태그에 62.5%를 적용하여 rem을 계산하기 편리하게 했다.
html { font-size: 62.5%; }
62.5%를 적용한 이유
기본 폰트 크기를 10px로 조정하여 (16px * 62.5%) 상대적으로 폰트사이즈를 직관적으로 확인할 수 있도록 하기위해서이다.
그냥 10px을 적용할 경우, 브라우저 기본 폰트를 변경할 수 없기 때문에 접근성 옵션을 해치기 때문에 사용하지 않는다.
각 폰트 사이즈마다 clamp()
를 사용하여 최소 및 최대 폰트를 지정했습니다.
$font-size-heading1: clamp(5.4rem, 7vw, 12.6rem);
GSAP 이란?
The GreenSock Animation Platform.
타임라인 기반의 애니메이션 자바스크립트 라이브러리.
세밀한 움직임과 동작의 연속성을 훨씬 간편하게 설정할 수 있다.
애니메이션이 들어갈 텍스트를 미리 아래에 위치시키고
텍스트를 감싼 부모 클래스에 overflow: hidden
속성을 줘서 텍스트를 보이지 않도록 처리한 뒤
스크롤을 내릴 때, 지정한 위치에 도달하면 y 값이 0이 되면서 텍스트가 아래에서 위로 올라옵니다.
.overflow { display: block; position: relative; overflow: hidden; }
.overflow .text { display: block; transform: translateY(100%);}
// (공통) 스크롤마다 텍스트 올라오는 모션
textList = document.querySelectorAll('.overflow .text');
textList.forEach(element => {
gsap.to(element, {
scrollTrigger: {
trigger: element.parentElement,
start: "0% 60%",
},
y: 0
})
});
마우스를 따라다니는 요소로, mousemove
이벤트가 일어나면
clientX
, clientY
로 마우스 커서의 좌표 값을 구해 마우스 스토커의 left, top 값에 적용합니다.
.cursor {
position: fixed; //absolute로 하면 스크롤 내릴 때 안따라오기 때문에 fixed
z-index: 50;
pointer-events: none;
mix-blend-mode: difference;
.pointer {
position: absolute;
top: 0; left: 0;
transform: translate(-50%, -50%); // 커서 정중앙에 위치시키기
width: 50px; height: 50px;
border-radius: 50%;
border: 2px solid #fff;
transition: 0.3s;
}
}
// 마우스 스토커
function mouseFollower(e) {
gsap.to('.cursor',0.3, {
css: {
left: e.clientX,
top: e.clientY
}
})
}
$(window).on('mousemove', mouseFollower);
.pointer-event 클래스를 가진 요소에 마우스 오버시,
그 요소가 .btn-scroll이라는 클래스를 가졌다면 zoom-sm 클래스를,
.link-more 클래스를 가졌다면 zoom 클래스를 마우스 커서에 추가해서 스타일을 변경하는 방식으로 특정 영역마다 포인터 스타일을 바꿔주었습니다.
$('.pointer-event').hover(function(){
if ( $(this).hasClass('btn-scroll') ) {
$mouseCursor.addClass('zoom-sm');
} else if ( $(this).hasClass('link-more') ) {
$mouseCursor.addClass('zoom');
}
마우스 커서를 따라오듯 움직여야하므로 offset
함수를 통해 마우스의 좌표값을 구하고 계산식을 통해 특정 범위 내에서 요소를 움직이도록 했습니다.
// 마우스커서 올리면 버튼 움직이는 모션
function moveBtn(e) {
x = (-($(this).width()/2) + e.offsetX) * 0.3
y = (-($(this).width()/2) + e.offsetY) * 0.3
gsap.to($(this), { x: x, y: y })
}
$('.header .btn-menu').on('mousemove', moveBtn);
client
,offset
차이client 메서드는 브라우저 화면을 기준으로 좌표값 반환 (스크롤 무시)
offset 메서드는 이벤트 대상이 되는 요소를 기준으로 좌표값 반환
gsap에서 pin: true
를 설정하면 특정 요소가 고정됩니다.
요소를 고정 시킬 스크롤 시작 지점과 끝나는 지점을 설정해주고 xPercent
를 스크롤이 끝나는 지점까지 설정해서 가로스크롤을 만듭니다.
gsap.to('.group-list', {
scrollTrigger: {
trigger: '.sc-project',
start: '0% 0%',
end: '+=500%',
pin: true,
scrub: 3,
},
xPercent: -500
})