ux-scroll

애플의 제품페이지를 보면 스크롤에 따라 반응하는 에니메이션을 만날 수 있습니다.

기술에 대한 정보는 이미 많은 블로그에서 다루고 있는데요, 대부분 방대한 assets을 이용하는 반쪽짜리 정보였습니다.(스크롤에 반응하는건 맞으나, 화면전체를 이미지나 동영상으로 처리)

하지만 현재 애플의 스크롤 에니메이션은 방대한 assets으로 만든것과 엘리먼트를 직접 움직여 만들어낸 화면으로 구성되 있고 후자에 대한 라이브러리가 있다면 좋겠다는 생각에서 ux-scroll을 만들었습니다.(스크롤에 따라 이벤트를 실행시켜줄 수 있는)

필요기능

  1. 원하는 엘리먼트의 특정 위치에서 callback 함수를 실행시킨다.
  2. 이벤트 발생 시점을 조정할 수 있다.(ui변경없이 이벤트의 발생시점 변경하도록)
  3. 엘리먼트의 변경사항을 업데이트하여 1의 기능을 문제없이 발생시킨다.(윈도우 리사이징 또는 엘리먼트 위치 변경 이벤트 발생 시)
  4. 느리지 않게 1의 기능을 실행시킨다.(퍼포먼스)
  5. 간단한 에니메이션 처리를 위해 1의 기능을 축소해서 사용할 수 있다.(class를 이용한 transition 처리하는 클래스)

개선사항(major 버전에 추가될 기능)

미정

프로토타입을 생성해보고 실제 제품을 만드는 편인데, 이번 라이브러리도 마찬가지로 처리했습니다.
쉽게 만들어보고 발생한 문제점을 개선했는데 개선 사항에 대해 설명하겠습니다.

이벤트 발생(2=>3)

prototype

이벤트 발생 시점을 정방향 스크롤, 역방향 스크롤에 따라 뷰포트의 상단, 하단 위치, 그리고 엘리먼트당 top, bottom위치를 체크하는 방향당 2개의 이벤트입니다.

  • 정방향: 엘리먼트 top이 뷰포트 하단에서 뷰포트 상단까지의 이벤트

  • 정방향: 엘리먼트 bottom이 뷰포트 하단에서 뷰포트 상단까지의 이벤트

  • 역방향: 엘리먼트 bottom이 뷰포트 상단에서 뷰포트 하단까지의 이벤트

  • 역방향: 엘리먼트 top이 뷰포트 상단에서 뷰포트 하단까지의 이벤트

minor

엘리먼트당 3개의 이벤트를 생성하며, 각각 starting, doing, ending의 flag로 onoff가 가능하도록 처리했습니다. prototype과는 다르게 3개의 매소드를 동일하게 실행하되, 방향을 인자값으로 넘기도록 했습니다.

  • 엘리먼트 top의 뷰포트 위치 0~1000
  • 엘리먼트 top엘리먼트 bottom 사이의 0~1000
  • 엘리먼트 bottom의 뷰포트 위치 0~1000

element.getBoundingClientRect()에서 element.offsetTop으로 변경

prototypee

엘리먼트의 높이를 체크하는 방식중에 getBoundingClientRect이 매소드로 엘리먼트의 높이를 체크하는게 여러모로 장점이 있습니다.


https://developer.mozilla.org/ko/docs/Web/API/Element/getBoundingClientRect

장점:
1. scrollY값을 알 필요가 없다
스크롤 에니메이션에 중요한 부분은 viewport에서 어느곳에 위치하냐 인데,
offsetTop은 scrollY 값이 매번 필요하지만(절대값이다보니 스크롤의 위치, 화면의 크기로 계산해야함)
getBoundingClientRect은 상대값이고 매소드 호출 시 width등등, 필요한 모든 정보를 불러오기때문에 간편하게 처리할 수 있습니다.
2. 윈도우 리사이징시 변경되는 엘리먼트들에 대해 추가 대응이 필요없다는 점 또한 장점

단점:
1. 무겁다

minor

그래서 프로토타입에서 getBoundingClientRect이걸 사용해 제작했으며
이후 offsetTop으로 라이브러리를 변경했습니다.

글로벌 이벤트 처리

AOS 사용중 종종 오류가 발생한 적이 있습니다.
scroll 이벤트를 다루다보니, 이벤트가 오버렙되는 등의 사이드 이펙이 발생할 가능성을 발견했고 그래서 ux-scroll에서는 해당 이벤트를 유저가 처리하는걸로 제작했습니다.

minor

import { UxScrollCallback } from 'ux-scroll';
const uxScrollCallback = new UxScrollCallback(options)
window.onscroll = () => {
  uxScrollCallback.onScroll();
}
window.onresize = () => {
  uxScrollCallback.onResize();
}

requestAnimationFrame() 적용

minor

thottle만 적용하면 퍼포먼스에 문제가 없을거라 생각했는데 만들어본 데모에서 과도하게 느린부분이 발견되었습니다.
그래서 requestAnimationFrame 적용했습니다.
퍼포먼스 관련해서는 실제 적용한 콜백 함수에서도 영향을 받았는데 이건 다시 다룰 예정입니다.

style

major(예정)

숫자카운팅등의 스타일

profile
front-end

0개의 댓글