Skip to content

Commit

Permalink
Merge pull request #36 from softeerbootcamp4th/feature/34-useScrolTra…
Browse files Browse the repository at this point in the history
…nsition

[Feat] useScrollTransition 커스텀 훅 추가
  • Loading branch information
darkdulgi authored Jul 25, 2024
2 parents 39a40d2 + bd076a4 commit 537b1f8
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/common/throttleRaf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* request animation frame에 따라 스로틀링을 적용하는 고차 함수입니다.
* 스로틀링을 적용시킬 함수를 인자로 넣으면, 스로틀이 적용된 함수를 반환합니다.
* 스로틀링이 적용된 함수는 원본 함수와 동일한 매개변수를 받습니다.
*
* 주로 스크롤 애니메이션이나 마우스 드래그 애니메이션 시, 스로틀링을 걸어 함수의 실행 빈도를 줄여 성능을 향상시키는 용도로 사용합니다.
*/
function throttleRaf(func) {
let throttleArgs = [];
let isDelayed = false;
return function (...args) {
throttleArgs = args;
if (isDelayed) return;
isDelayed = true;
requestAnimationFrame(() => {
func(...throttleArgs);
isDelayed = false;
});
};
}

export default throttleRaf;
30 changes: 30 additions & 0 deletions src/common/useScrollTransition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useState, useEffect } from "react";
import throttleRaf from "./throttleRaf.js";
import { clamp } from "./utils.js";

/**
* 스크롤 트랜지션을 더 쉽게 사용할 수 있게 하는 커스텀 훅입니다.
*
* @param {number} scrollStart - 스크롤이 시작되는 위치입니다.
* @param {number} scrollEnd - 스크롤이 종료되는 위치입니다.
* @param {number} valueStart - 값의 시작 지점입니다.
* @param {number} valueEnd - 값의 종료 지점입니다.
*
* @return {number} 실제로 변환된 값입니다.
*/
function useScrollTransition({ scrollStart, scrollEnd, valueStart, valueEnd }) {
const [scroll, setScroll] = useState(0);

useEffect(() => {
const scrollRenew = throttleRaf(() => setScroll(window.scrollY));
document.addEventListener("scroll", scrollRenew);
() => {
document.removeEventListener("scroll", scrollRenew);
};
}, []);

const ratio = clamp((scroll - scrollStart) / (scrollEnd - scrollStart), 0, 1);
return ratio * (valueEnd - valueStart) + valueStart;
}

export default useScrollTransition;
9 changes: 9 additions & 0 deletions src/common/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export function clamp(target, min, max) {
if (target < min) return min;
if (target > max) return max;
return target;
}

export function linearMap(ratio, min, max) {
return ratio * (max - min) + min;
}
4 changes: 3 additions & 1 deletion src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@

@font-face {
font-family: "hdsans";
src: url("/font/HyundaiSansTextOffice-Medium.woff") format("woff"), url("/font/HyundaiSansTextOffice-Medium.ttf") format("truetype")
src:
url("/font/HyundaiSansTextOffice-Medium.woff") format("woff"),
url("/font/HyundaiSansTextOffice-Medium.ttf") format("truetype");
}

@layer base {
Expand Down
27 changes: 27 additions & 0 deletions src/introSection/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import useScrollTransition from "@/common/useScrollTransition.js";

function IntroSection() {
const titleOpacity = useScrollTransition({
scrollStart: 0,
scrollEnd: 500,
valueStart: 1,
valueEnd: 0,
});

const titleStyle = {
opacity: titleOpacity,
};

return (
<div className="h-[2160px]">
<h1
className="text-8xl w-full flex items-center justify-center absolute top-[500px]"
style={titleStyle}
>
The new IONIQ 5
</h1>
</div>
);
}

export default IntroSection;

0 comments on commit 537b1f8

Please sign in to comment.