먼저, welcome page 이후에 마주하는 main page는 크게 4개의 파트로 구성할 예정이다.
대충 jsx로 이런 느낌이다.
export default function Home() {
return (
<>
<IntroComponent></IntroComponent>
<AboutComponent></AboutComponent>
<ProjectComponent></ProjectComponent>
<ContactComponent></ContactComponent>
</>
);
}
오늘은 그 첫번째인 intro 파트를 어떻게 자연스럽게 welcome page와 연결시키는지이다.
# Welcome to Intro
Intro 파트는 앞서 가구현한 welcome page를 지나면 처음으로 마주하는 페이지이다.
그렇기 때문에 welcome page와 intro page가 연속성있게 연결되어 라우팅 과정이 자연스럽게 느껴지기를 원했다.
이를 위해서 내가 택한 방법은
1. welcome page에서 클릭하면 가속되는 것을 이용해 사용자가 클릭을 오래 하고 있게끔 유도한다.
2. 특정 시간 이상 마우스 다운 된 경우 화면을 black out 시키고 main page로 라우팅한다.
3. 라우팅 된 페이지의 첫 시작인 intro 파트는 검정색 배경이 기본이 되는 상태로 유저가 라우팅을 인식하지 못하게 한다.
# 구현
요구사항 1
일단은 단순하게 텍스트로 채워넣자.
추후 텍스트 입력되는 애니메이션을 추가하고 레트로한 폰트를 찾아서 적용할 예정이다.
요구사항 2
라우팅은 page.tsx에서 마우스 이벤트 핸들러로 처리하자.
mouse down 시 setTimeout 걸어놓고 특정 시간 후 라우팅 되게끔 하면 된다.
단, 중간에 사용자가 마우스 버튼을 놓을 수도 있으므로 mouse up 시 setTimeout을 없애주었다.
// page.tsx
...
const handleMouseDown = (e: React.MouseEvent) => {
if (e.button !== 0) return; // treat only left button
timeoutID = window.setTimeout(() => {
router.push('/home');
}, 3500);
e.preventDefault();
};
const handleMouseUp = (e: React.MouseEvent) => {
if (e.button !== 0) return; // treat only left button
window.clearTimeout(timeoutID);
e.preventDefault();
};
...
Black out은 canvas 애니메이션을 구현한 js 파일에 로직을 추가하여 구현하였다.
mouseDown 시점의 시간을 기록해두고 특정 시간(BLACKOUT_TIME)이 지나면 progress 값을 1까지 증가시키도록 하였다.
혜성의 위치를 원점으로 하는 검은 원을 그려주고 progress가 0에서 1로 점차 증가함에 따라 반지름의 크기를 점차 증가시키는 방식으로 구현하였다.
// canvas_welcom.js
...
let startTime = undefined;
let blackoutProgress = 0;
...
document.addEventListener(
'mousedown',
(e) => {
if (e.button !== 0) return; // treat only left button
targetSpeed = BOOST_SPEED;
startTime = new Date();
},
false
);
document.addEventListener(
'mouseup',
() => {
targetSpeed = DEFAULT_SPEED;
startTime = undefined;
},
false
);
...
function drawBlackout(cx, cy) {
if (!startTime) {
blackoutProgress = Math.max(0, blackoutProgress - 0.02);
} else {
blackoutProgress = Math.min(
1,
(new Date() - startTime - BLACKOUT_TIME) / 500
);
}
if (blackoutProgress <= 0) return;
context.save();
let rx, ry;
let pf, px, py;
let radius =
Math.sqrt(canvasWidth * canvasWidth + canvasHeight * canvasHeight) *
blackoutProgress;
rx = canvasWidth / 2 - cx;
ry = canvasHeight / 2 - cy;
pf = FL / COMET_Z;
px = cx + rx * pf;
py = cy + ry * pf;
context.fillStyle = 'rgb(0, 0, 0)';
context.beginPath();
context.moveTo(px, py);
context.arc(px, py, radius, 0, 2 * pi);
context.closePath();
context.fill();
context.restore();
}
...
요구사항 3
검정색이면 된다.
body의 background-color를 black으로만 설정해주어도 충분하다.
일단은 임시 텍스트를 넣어놓고 요구사항 1처럼 나중에 처리하자.
# 결과
추후에 텍스트 관련 애니메이션 추가할 때
Welcome page에서 글자 사라지는 애니메이션 추가 + Intro page 에서 글자 타이핑되면서 나타나는 애니메이션만 추가하면 될 듯 하다.
'Projects > Portfolio' 카테고리의 다른 글
Next.js 포트폴리오 페이지 제작기 - 5. Projects part (0) | 2023.08.05 |
---|---|
Next.js 포트폴리오 페이지 제작기 - 4. About part (0) | 2023.08.04 |
Next.js 포트폴리오 페이지 제작기 - 3. Intro part (0) | 2023.07.28 |
Next.js 포트폴리오 페이지 제작기 - 1. Welcome page 가구현 (0) | 2023.07.25 |
Next.js 포트폴리오 페이지 제작기 - 0. 프로젝트 구상 (0) | 2023.07.25 |