안녕하세요!
오늘은 [자바스크립트 사다리 타기] 프로젝트에 이어서 웹 페이지에 생동감을 불어넣는 것은 물론, 방문자의 시선을 단번에 사로잡을 수 있는 ‘캔버스 기반의 인터랙티브 JavaScript 마우스 트래커(Visual Particle System)’를 만들어 보았습니다.
그동안 다양한 자바스크립트 프로젝트를 진행하며 기초를 다져왔다면, 이번에는 Canvas API의 심화 기능을 활용해 한 단계 더 높은 수준의 인터랙션을 구현해 볼 차례입니다. 단순히 클릭에 반응하는 단계를 넘어, 사용자의 움직임 하나하나에 화려한 입자(Particle)들이 반응하는 비주얼 시스템을 구축해 보며 자바스크립트의 강력한 표현력을 경험해 보시기 바랍니다.
1. 왜 JavaScript 마우스 트래커인가?
웹 사이트의 첫인상을 결정짓는 요소는 매우 다양하지만, 사용자의 동작에 실시간으로 반응하는 인터랙션만큼 강렬한 인상을 남기는 것은 드뭅니다. 이번에 구현할 JavaScript 마우스 트래커는 사용자가 마우스를 움직일 때마다 다채로운 색상의 입자들이 생성되고, 물리 법칙에 따라 흩어지며 서서히 사라지는 효과를 제공합니다.
이는 단순히 시각적인 즐거움을 줄 뿐만 아니라, 캔버스의 애니메이션 최적화 기법인 requestAnimationFrame과 효율적인 객체 관리 로직인 파티클 시스템을 학습하기에 더할 나위 없이 좋은 주제입니다. 특히 고해상도 모바일 기기에서도 부드러운 프레임을 유지하는 법을 고민하며 개발했습니다.

2. 핵심 기술의 원리: 파티클 시스템 (Particle System)
이번 JavaScript 마우스 트래커 프로젝트의 기술적 핵심은 수많은 작은 입자들을 개별적인 객체로 관리하는 파티클 시스템입니다.
기본 원리는 간단합니다. 마우스의 현재 좌표를 감지하여 그 주변에 무작위 속도와 방향을 가진 입자 객체들을 생성합니다. 각 입자는 생성된 순간부터 매 프레임마다 자신의 위치를 업데이트하고, 크기를 줄이며, 투명도를 낮추어 갑니다. 그리고 수명이 다한(투명해지거나 너무 작아진) 입자들을 메모리에서 효율적으로 제거함으로써 부드러운 퍼포먼스를 유지하는 것이 관건입니다.
파티클의 생명 주기를 관리하는 클래스 로직
class Particle {
constructor() {
// 마우스 주변에 랜덤한 위치로 생성
this.x = mouse.x + (Math.random() - 0.5) * 20;
this.y = mouse.y + (Math.random() - 0.5) * 20;
this.size = Math.random() * 5 + 1; // 랜덤 크기
this.speedX = Math.random() * 3 - 1.5; // 랜덤 x축 속도
this.speedY = Math.random() * 3 - 1.5; // 랜덤 y축 속도
this.color = `hsl(${Math.random() * 360}, 70%, 50%)`; // 다채로운 HSL 색상
this.opacity = 1;
}
update() {
this.x += this.speedX;
this.y += this.speedY;
this.size *= 0.98; // 매 프레임마다 크기 감소
this.opacity -= 0.02; // 매 프레임마다 투명도 감소
// 수명이 다한 파티클을 제거하기 위한 플래그
if (this.size < 0.3 || this.opacity < 0.05) {
this.markedForDeletion = true;
}
}
}
3. 고해상도 모바일 환경을 위한 디테일한 조정
이번 프로젝트를 진행하며 가장 신경 쓴 부분 중 하나는 고해상도 모바일 환경에서의 사용자 경험이었습니다. PC와 달리 모바일은 터치 기반이기 때문에 마우스 이벤트와는 또 다른 디테일이 필요합니다.
첫째로, 캔버스의 크기를 단순히 픽셀 단위로 고정하지 않고 window.innerWidth와 innerHeight를 활용하여 반응형으로 설계했습니다. 둘째로, 고해상도 디스플레이(Retina 등)에서 선이 흐릿하게 보이는 현상을 방지하기 위해 장치의 pixelRatio를 고려한 캔버스 스케일링 기법을 적용할 수 있다는 점도 염두에 두어야 합니다.
4. 프로젝트 구현 중 마주한 고민과 해결책
가장 큰 고민은 “어떻게 하면 수많은 파티클이 생성되어도 브라우저가 느려지지 않을까?” 하는 점이었습니다.
처음에는 단순히 배열에 파티클을 계속 추가하기만 했더니, 시간이 흐를수록 메모리 점유율이 올라가며 프레임 드랍이 발생했습니다. 이를 해결하기 위해 filter 메서드를 활용하여 화면에서 보이지 않게 된 입자들을 실시간으로 배열에서 완전히 삭제하는 ‘가비지 컬렉션’ 로직을 직접 구현했습니다.
또한, setTimeout 대신 브라우저의 주사율에 맞춰 최적의 주기로 애니메이션을 실행하는 requestAnimationFrame을 사용하여 고성능 모바일 기기에서도 끊김 없는 60fps의 부드러움을 확보할 수 있었습니다.
5. 실무 응용 및 프로젝트의 가치
이 인터랙티브 JavaScript 마우스 트래커는 다양한 실무 환경에서 응용될 수 있습니다.
- 브랜드 랜딩 페이지: 사용자의 유입이 중요한 이벤트 페이지의 헤더 영역에 적용하여 브랜드의 혁신적이고 현대적인 이미지를 심어줄 수 있습니다.
- 디지털 포트폴리오: 정적인 포트폴리오 사이트에 이펙트를 추가함으로써 개발자의 창의성과 기술력을 시각적으로 즉각 증명할 수 있습니다.
- 로딩 인디케이터: 지루한 대기 시간 동안 사용자가 화면 위에서 놀 수 있는 장치를 마련하여 체감 대기 시간을 줄이는 용도로도 훌륭합니다.
단순한 코드 복사 붙여넣기를 넘어, 각 파티클이 가지는 속성값(속도, 중력, 색상 변화율 등)을 조금씩 수정해 보시기 바랍니다. 수치를 조금만 바꿔도 눈 내리는 효과나 불꽃놀이 효과처럼 완전히 다른 분위기를 연출할 수 있습니다.
6. JavaScript 마우스 트래커
오늘 구현한 기초적인 파티클 시스템은 그 자체로도 훌륭하지만, 여기에 몇 가지 수학적 로직을 한 겹 더 입히면 진정한 인터랙티브 아트의 영역으로 진입할 수 있습니다.
가장 먼저 도전해 볼 만한 기능은 ‘유사 중력 및 자석 효과(Magnetic Attraction)’입니다. 현재는 입자들이 마우스 위치에서 생성되어 사방으로 흩어지기만 하지만, 피타고라스의 정리를 활용해 마우스 좌표와 각 입자 사이의 거리()를 실시간으로 계산하는 로직을 추가해 보세요. 특정 거리 이내로 마우스가 다가가면 입자들이 자석에 이끌리듯 마우스 방향으로 가속도를 얻게 하거나, 반대로 밀려나게 하는 물리 법칙을 적용하면 훨씬 더 유기적이고 생동감 넘치는 움직임을 연출할 수 있습니다.
또한, 시각적인 화려함을 극대화하고 싶다면 ‘오디오 비주얼라이저(Audio Visualizer)’ 기법과의 결합을 추천합니다. Web Audio API를 통해 배경 음악의 주파수 데이터를 분석하고, 베이스 비트가 강하게 울릴 때마다 파티클의 색상을 강렬하게 변화시키거나 폭발하는 입자의 개수를 순간적으로 늘리는 식의 구현이 가능합니다.
마지막으로 입자들이 지나간 자리에 잔상(Ghosting Effect)을 남기는 기법도 매력적입니다. ctx.clearRect() 대신 아주 낮은 불투명도를 가진 사각형을 매 프레임마다 덮어씌우는 방식으로 캔버스를 초기화하면, 입자들이 유성처럼 긴 꼬리를 남기며 이동하는 몽환적인 효과를 낼 수 있습니다.
코딩은 단순히 정답을 찾아가는 과정이 아니라, 상상력을 현실로 구현해내는 즐거운 예술 활동입니다. 이번 프로젝트를 통해 여러분도 캔버스라는 빈 도화지 위에 자신만의 화려한 코드를 그려보셨기를 바랍니다. 작업하시다가 로직이 꼬이거나 더 화려한 효과를 내고 싶다면 언제든 의견 나누어 주세요!