설정
tsdx
를 사용합니다.
마지막 커밋은 2022년 3월이지만 유명한 CLI툴 입니다.
리엑트 기반의 컴포넌트 라이브러리를 만들 때 boilerplate를 생성합니다.
rollup을 사용하여 cjs, esm, umd를 지원하는 단일 js 파일을 만들어 줍니다.
리엑트 17 버전대의 class형 컴포넌트와 hook 기반 라이브러리로 구현하였습니다.
ts-monorepo
에 link를 할떄, ReactNode
정의가 달라 오류가 났습니다.
ts-monorepo
는 pnpm으로 되어 있기 때문에 다음과 같이 link 명령을 사용합니다.
pnpm link /Users/swcho/projects/swcho/react-scroll-parallax
사용 예시는 다음과 같습니다.
https://react-scroll-parallax-examples.vercel.app/
기본적으로 특정 엘리먼트가 viewport에 진입할 때와 빠져나갈 떄를 기준으로 transform을 설정할 수 있습니다. 또한 스크롤 변화 시, 이벤트 콜백을 제공하기 때문에 다양하게 활용이 가능해 보입니다.
parallax-controller라는 모듈을 사용합니다. 분석을 위해선 추가로 설정을 해 줍니다.
전체적인 테스트 환경은 ts-monorepo 기반으로 구성했습니다.
동작 과정
<ParallaxProvider>
를 react 코드에 설정해 주면 ParallaxController
를 생성 합니다.
스크롤을 포함하는 엘리먼트를 넘겨주면, ParallaxController
객체가 스크롤 관련 처리를 수행합니다.
ParallaxController
는 scroll
이벤트와 함께, resize
, blur
, focus
, load
이벤트를 처리합니다.
이렇게 스크롤을 포함하는 엘리먼트에 대한 초기 설정을 <ParallaxProvider>
에서 하고 나면,
<Parallax>
컴포넌트를 사용하여 viewport 영역의 enter, exit, progress 등의 이벤트를 받아 처리할 수 있습니다.
또한 transform
, opacity
와 같은 css 속성 값의 start, end 값과 progress에 따라 적용하는 easing 함수 등을 설정할 수 있습니다.
Scroll 이벤트 처리
생성 과정 중에서 전달 받은 target HTMLElement
dom 객체의 scroll
이벤트를 등록합니다.
target 엘리먼트를 전달하지 않을 경우, window
객체의 scroll
이벤트를 등록합니다.
addEventListener
의 passive
옵션은 scroll 이벤트 처리 과정 중 preventDefault
를 할 것인지를 브라우저에게 알려주는 역할을 합니다.
parallax-controller
해당 옵션의 지원여부를 알아내는 코드는 다음과 같습니다.
export function testForPassiveScroll() {
let supportsPassiveOption = false;
try {
const opts = Object.defineProperty({}, 'passive', {
get() {
supportsPassiveOption = true;
return true;
},
});
// @ts-expect-error
window.addEventListener('test', null, opts);
// @ts-expect-error
window.removeEventListener('test', null, opts);
} catch (e) {}
return supportsPassiveOption;
}
opts
라는 proxy 객체를 사용하여 passive
라는 옵션을 브라우저가 읽으면 해당 기능을 지원하는 것으로 판단합니다.
이렇게 알아낸 값으로 scroll
이벤트 등록 옵션을 결정합니다.
물론 성능향상을 위해 passive
옵션을 true
로 설정합니다.
...
el.addEventListener(
'scroll',
this._handleScroll,
this._supportsPassive ? { passive: true } : false
);
영역 정보
기본적으로 영역에 대한 정보는 다음과 같은 dom 프로퍼티 값을 참조 합니다.
...
const width = window.innerWidth || html.clientWidth;
const height = window.innerHeight || html.clientHeight;
const scrollHeight = html.scrollHeight;
const scrollWidth = html.scrollWidth;
이벤트 동작
scroll
이벤트 뿐만아니라 resize
, blur
, focus
, load
이벤트에 따라 Update를 진행합니다.
scroll
이벤트 처리에 추가로 viewport 크기 변경에 의한 값 조정을 모두 재조정하는 setCachedAttributes
작업을 수행합니다.