들어가며

패럴랙스 스크롤링 웹 사이트의 세계로 들어갈 준비는 되었나요? 패럴랙스 스크롤을 사용한 사이트는 많습니다. 안타깝게도 일부 사이트에 있는 패럴랙스 스크롤링은 사용자들의 주의를 분산시키거나 보여주고자 했던 콘텐츠가 아닌 다른 곳으로 사용자들의 눈을 돌리지만, 제대로만 사용한다면 훨씬 더 빼어난 웹을 만들 수 있습니다. 패럴랙스는 잘만 사용된다면 사용자들이 더 실감 나는 매력적인 방식으로 콘텐츠를 탐색할 수 있도록 도와줍니다.

최근 우리팀은 콘텐츠 일부에 패럴랙스 스크롤 애니메이션을 사용하기 시작했습니다. 우리는 ADT의 역사라는 페이지에서 약간의 아이디어를 얻고, 유명 드라마인 워킹 데드에 대한 인터랙티브 좀비 인포그래픽을 만들어보기로 했습니다. 오늘은 이 프로젝트의 무대 뒤로 여러분을 데려가 굉장히 유용했던 Skrollr.js라는 자바스크립트 플러그인의 사용법을 보여주려고 합니다.

메인 좀비 이미지

간단히 말해서 Skrollr는 HTML과 CSS를 사용해 정교한 스크롤 기반 애니메이션(패럴랙스 혹은 그 밖의 것)을 만드는 플러그인입니다. Skrollr의 수많은 장점은 공식 문서에서 찾아볼 수 있습니다. 이 글에서 우리는 자바스크립트와 스프라이트 몇 개를 사용해 사용자가 스크롤을 앞뒤로 움직임에 따라 반응하는 보행 애니메이션을 간단하게 만들어보겠습니다. 이 글을 끝까지 따라가면, 패럴랙스 환경에서 걷는 캐릭터가 인간에서 좀비로 변하는 것도 볼 수 있습니다.

먼저 몇 가지 소스 파일을 다운로드 받으세요. 워킹 데드 프로젝트에서 사용했던 이미지 몇 장과 자바스크립트 파일, HTML 뼈대가 있을 것입니다. 이제 이 파일들을 가지고 삽질을 시작해보겠습니다.

1단계 - 패럴랙스 백그라운드

HTML5 data- 속성을 추가한 <div> 몇 개를 추가해서 패럴랙스 백그라운드 레이어 두 장을 만들어 보겠습니다. 또한, 스타일시트에 CSS도 약간 추가하고 우리가 작성한 main.js 파일에서 Skrollr의 .init() 함수도 호출할 것입니다. 다음 코드에서 보듯 패럴랙스 레이어는 id="skrollr-body"가 설정된 엘리먼트의 자식 노드여야 합니다. 지금 보기에는 클래스와 ID가 너무 많다 싶을 수 있지만, 나중에 엘리먼트를 조금 더 추가하게 되면 이유가 있었음을 알게 될 것입니다.

HTML:

<div id="skrollr-body">
	<div id="Scene">
		<div id="bg1" class="parallax-layer"
			data-0="left:0px;"
			data-5000="left:-1000px;">
		</div>
		<div id="bg2" class="parallax-layer"
			data-0="left:0px;"
			data-5000="left:-2500px;">
		</div>
	</div>
</div>

우리가 보게될 마술같은 일은 모두 data- 속성 덕분입니다. Skrollr를 호출하면, Skrollr는 #skrollr-body 안에 있는 모든 엘리먼트를 탐색하며 엘리먼트에 설정된 data- 속성을 사용해 적절한 애니메이션을 구현합니다. data- 뒤에 붙은 숫자는 사용자가 스크롤 한 픽셀의 수이며, 속성의 값은 해당 스크롤 위치에 왔을 때 현재의 요소에 설정할 스타일입니다. #bg1를 예로 들면, 사용자가 페이지 상단(data-0)으로부터 페이지 아래로 5,000 픽셀(data-5000)만큼 스크롤하면 #bg1이 왼쪽으로 1000 픽셀만큼 움직이는 애니메이션이 나타날 것입니다. 설정한 값을 보면 Skollr는 대략 사용자 스크롤 5픽셀마다 왼쪽으로 1픽셀씩 #bg1을 옮길 것입니다. 이 애니메이션은 앞으로도 뒤로도 일어나므로 사용자는 어느쪽으로든 스크롤 할 수 있으며 Skrollr이 적절한 애니메이션을 보여줄 것입니다.

#bg2data-* 속성에 설정된 값을 살펴보면 사용자 스크롤 2픽셀마다 #bg2가 1픽셀씩, 다시 말해 #bg1보다 훨씬 빨리 움직이는 것을 알 수 있습니다. 이 덕분에 3D 공간 같은 느낌이 날 것입니다. 그러나 이 코드를 실행하기 전에 이미지를 추가한 후 액자처럼 감싸는 CSS를 추가해야 합니다. 그 후에는 Skrollr의 초기화 함수도 호출해야 하고요.

CSS:

화면은 700px 높이의 프레임에 수직 중간 정렬되게 합니다.

#Scene{
	position: fixed;
	width: 100%;
	height: 700px;
	margin-top: -350px;
	top: 50%;
	}
.parallax-layer{
	position: absolute;
	height: 700px;
	background-repeat: no-repeat;
	}
#bg1{
	background: url(../images/bg-1.jpg);
	width: 3528px;
	}
#bg2{
	background: url(../images/bg-2.png) left bottom;
	/* 이미지가 꽤 크지만... 사용할만한 가치가 있습니다 */
	width: 4368px;
	}


JavaScript:

skrollr.init();

잠시 후에는 여기에 다른 작업을 더 추가할 것이므로 여기까지 작업한 내용을 별도 파일로 저장했습니다. 하지만, 여러분은 굳이 그렇게 하지 않아도 됩니다.

이것 보세요! 패럴랙스가 만들어졌네요!

2단계 - 전경 엘리먼트

다음으로는 전경에 몇 가지 요소를 추가해보겠습니다. 구름, 해, 학교를 추가한 후 캐릭터도 추가할 것입니다. 이 중 학교는 캐릭터가 인간에서 좀비로 변신할 때 잠시 캐릭터를 숨기는 용도로 사용합니다.

먼저 두 번째 구름 레이어를 추가해봅시다. 이 구름 레이어는 #bg2와 같은 속도로 화면을 가로질러 이동할 것이므로, #bg2 안에 구름 레이어를 추가하여 (절대 위치에 기반한) 동일한 애니메이션이 적용되도록 합니다. 이처럼 내부에 있는 div는 부모의 CSS 위치 속성을 그대로 사용하는 경우가 많습니다.

HTML:

<div id="bg2" class="parallax-layer"
	data-0="left:0px;"
	data-5000="left:-2500px;">
	<div id="cloud"></div>
</div>

CSS:

#cloud{
	position:absolute;
	background:url(../images/clouds.png);
	width:2059px;
	height:347px;
	}

이제 학교와 아직 좀비가 되기 전인 캐릭터를 추가해보겠습니다. 학교는 #bg2보다 살짝 더 빠르게 움직이게 할 것입니다. 또한, 학교를 그릴 때 뒤쪽과 앞쪽 레이어를 나누고 그 사이에 좀비 캐릭터를 두어서 마치 캐릭터가 문을 통과해서 지나가는 것처럼 보이게 할 것입니다.

HTML:

<div class="parallax-layer">
	<div id="schoolunder" class="school"
		data-0="left:2000px;"
		data-5000="left:-1500px;">
	</div>
	<div id="zombie"></div>
	<div id="schoolover" class="school"
		data-0="left:2000px;"
		data-5000="left:-1500px;">
	</div>
</div>

CSS:

캐릭터는 화면 왼쪽에서 300px만큼 떨어진 곳에 그대로 있되 배경이 화면 좌우로 움직이도록 하여 마치 예전에 보던 횡 스크롤 게임 느낌이 나도록 했습니다.

#zombie{
	position:absolute;
	background-image:url(../images/zombify.png);
	width:250px;
	height:190px;
	top:340px;
	left:300px;
	}
.school{
	position:absolute;
	width:600px;
	height:523px;
	top:100px;
	}
#schoolunder{
	background:url(../images/school_under.png);
	}
#schoolover{
	background:url(../images/school_over.png);
	}

이제 이 캐릭터는 마치 스케이트를 타듯 미끄러지며 화면을 이동하는 것처럼 보일 텐데, 여기에 보행 애니메이션과 짤막한 좀비 변신 애니메이션을 추가해보겠습니다. 그전에 해 이미지부터 추가하고 넘어가죠. 우리는 5개의 data 속성을 사용하여 해가 뜨고 지는 애니메이션을 표현했습니다. 이 엘리먼트는 #bg1#bg2 사이에 둘 것이므로 하늘 배경보다는 앞에 보이지만 전경 엘리먼트 뒤쪽을 이동하게 될 것입니다.

HTML:

<div id="bg1" class="parallax-layer"
	data-0="left:0px;"
	data-5000="left:-1000px;">
</div>
<div id="sun"
	data-0="top:200px;"
	data-2000="top:25px;"
	data-3000="top:0px;"
	data-4000="top:25px;"
	data-5000="top:50px;">
</div>
<div id="bg2" class="parallax-layer"
	data-0="left:0px;"
	data-5000="left:-2500px;">
</div>

CSS:

#sun {
	position:absolute;
	background:url(../images/sun.png);
	width:194px;
	height:194px;
	left:180px;
	}

우리가 지금까지 한 내용을 확인해보세요. 꽤 괜찮지만, 아직 다듬어야 할 부분이 남아 있습니다.

3단계 - 계속 걷게 하기 (& 좀비로 변신하기)

이제 캐릭터에 생명력을 불어넣을 때입니다. 캐릭터의 보행 및 변신 애니메이션에 필요한 이미지 프레임은 다운로드 받은 .png 스프라이트 파일 안에 있습니다. 처음에는 인간이었다가 나중에 좀비로 변할 것입니다. 이 프레임들을 배경 이미지로 보여주고 사용자의 스크롤에 따라 주기적으로 반복시키는 자바스크립트를 작성해보겠습니다. 스크롤을 어느 쪽으로 하든 동작하게 만들어서 정말 게임 같은 느낌을 내보겠습니다.


좀비화를 표현하는 스프라이트

data-* 속성을 사용하여 Skrollr가 배경 이미지를 애니메이션으로 만들게 할 수도 있지만, 이 방법은 속성을 꽤 많이 작성해야 하므로 직접 함수를 작성하기로 합니다. 직접 작성한 덕분에 약간의 유연함도 얻을 수 있으며 코드의 유지보수도 확실히 더 편해졌습니다. 우리는 skrollr.init()를 호출할 때 우리가 작성한 함수를 인수로 전달할 것입니다. 조금 더 자세히 말하자면 beforerender 리스너 함수로 할당하여 Skrollr가 애니메이션의 각 프레임을 그리기 직전에 자동으로 호출되게 할 것입니다(beforerender를 비롯한 Skrollr의 다른 옵션은 문서를 참고하세요). beforerender에는 curTop이라는 프로퍼티를 가진 객체가 인수로 전달됩니다. curTop은 현재 스크롤이 상단으로부터 얼마나 떨어졌는가를 알려주는, 다시 말해 페이지 상단으로부터 사용자가 스크롤 한 픽셀의 양을 알려주는 숫자입니다. 우리는 이 값을 사용하여 배경 이미지로 사용한 스프라이트를 앞으로 움직일 것인지 뒤로 움직일 것인지 또는 인간을 좀비로 바꿔야 할 때인지 정하겠습니다.

보행 애니메이션부터 작업한 후 인간에서 좀비로 변신하는 과정을 추가하겠습니다.

JavaScript:

var zombie = $('#zombie'),
	pLocs = [0, -250, -500, -750, -1000, -1250, -1500]
	curFrm = 0,
	lastStep=0;

skrollr.init({
	beforerender: function(o){
		// 마지막에 백그라운드 이미지를 움직인 후에
		// 사용자가 50픽셀 아래로 스크롤하면
		// 앞으로 이동해야 하므로 스프라이트에 있는
		// 다음 프레임으로 옮긴다.
		if(o.curTop > lastStep + 50) {
			if (curFrm>=6){ curFrm=-1; }
			zombie.css('background-position', pLocs[curFrm++] + 'px 0px');
			lastStep = o.curTop;
		// 사용자가 50픽셀 위로 스크롤하면
		// 뒤로 이동해야 하므로 이전 프레임으로 옮긴다.
		} else if(o.curTop < lastStep - 50) {
			if (curFrm<=0){ curFrm=7; }
			zombie.css('background-position', pLocs[curFrm--] + 'px 0px');
			lastStep = o.curTop;
		}
	}
});
  • zombie — 캐릭터를 표현하는 div에 대한 참조
  • pLocs — 스프라이트의 각 프레임이 왼쪽 끝으로부터 떨어진 픽셀 위치를 담은 배열
  • curFrm — pLoc에 있는 보행 애니메이션 프레임 중 현재 사용 중인 프레임의 인덱스
  • lastStep — 가장 최근에 배경 이미지를 움직였던 스크롤 위치. 프레임을 앞/뒤 어느 쪽으로 이동할 것인지 계산할 때 사용

멋지네요! 어려운 부분이 끝났습니다. 우리의 좀비는 걷기 시작할 테고요. 이제 남은 단계는 좀비로 변신!밖에 없습니다.

어쩌면 워킹 데드 드라마와 약간 다를지도 모르는데, 이 프로젝트에서는 캐릭터의 좀비 변신이 학교(zombie school)로 표현되었습니다. 덕분에 이 과정은 상대적으로 편했습니다. 인간이 걷는 장면의 프레임과 좀비가 걷는 장면의 프레임은 같은 이미지에 있었고 인간이 걷는 장면 바로 뒤에 좀비가 걷는 장면이 있었으므로 사용자가 캐릭터가 학교를 지나가는 장면이 나오는 곳을 스크롤 할 때 #zombie 레이어 배경 이미지의 위치만 적당히 바꿔주면 됐습니다. 인간이 걷는 장면은 7프레임인데 반해 좀비가 걷는 장면은 4프레임 밖에 안 들어서 애니메이션이 조금 더 유연하게 동작하도록 코드를 살짝 손봐야 했습니다. 수정된 부분은 아래에 굵은 글씨로 표시해두었습니다.

JavaScript:

var zombie = $('#zombie'),
	pLocs = [0, -250, -500, -750, -1000, -1250, -1500],
	curFrm = 0,
	lastStep=0,
	// We need just a couple extra variables
	animationCycle, backPosY;

skrollr.init({
	beforerender: function(o){
		// 사용자가 2800픽셀 이하로 스크롤하면
		// 캐릭터를 그대로 인간인 상태로 두고
		// 그 이상 스크롤하면 좀비로 바꾼다.
		if(o.curTop < 2800) {
			animationCycle=7;
			backPosY= '0px';
		} else {
			animationCycle=4;
			backPosY= '-190px';
		}
		if(o.curTop > lastStep + 50) {
			if (curFrm>=animationCycle-1){ curFrm=-1; }
			zombie.css('background-position', pLocs[++curFrm] + 'px ' + backPosY);
			lastStep=o.curTop;
		} else if(o.curTop < lastStep - 50) {
			if (curFrm<=0){ curFrm=animationCycle; }
			zombie.css('background-position', pLocs[--curFrm] + 'px ' + backPosY);
			lastStep = o.curTop;
		}
	}
});

그럼 이제 끝났습니다. 지금 막 우리는 게임 스타일의 패럴럭스 스크롤링을 만들었습니다. 축하합니다! 만약 더 다듬어진 버전을 보고 싶다면 우리팀이 작성한 워킹 데드 데모를 확인해보세요.

마무리

여기서 한 것은 Skrollr로 할 수 있는 기능의 겉핥기에 지나지 않습니다. 따라서 가능하다면 다른 많은 기능에 대해서도 꼭 읽어볼 것을 추천합니다. 애니메이션에 이징(easing)을 적용하거나 data 속성과 상수를 조합해서 사용하거나(유지보수에 좋습니다) Skrollr 스타일 시트에 프레임을 추가하는 대신 마크업에 전체 키프레임을 넣는 등 흥미로운 기능이 많습니다.

끝으로 잠깐 몇 마디 덧붙이려고 합니다. 가끔 웹 디자이너인 우리들은 매체의 노예처럼 느껴질 때가 있습니다. 웹에는 제약이 많고 크로스 브라우저와 크로스 디바이스 이슈에서 오는 어려움도 많습니다. 최소한 저는 여러 매체에서 디자인과 개발을 하는 한 사람으로서 간혹 매체의 노예처럼 느껴질 때가 있습니다. 하지만 이러한 브라우저 기반 매체에는 매우 독특한 면이 있는 것도 사실입니다. 예를 들어, 스크롤링 덕분에 사용자와 이런 식으로 인터랙션 할 수 있는 기회가 생겼습니다. 개인적으로 디자이너들은 이런 고유한 특성을 알아두어야 하며, 항상 이러한 특성을 훌륭한 경험으로 창조해 낼 방법을 찾아야 한다고 생각합니다.


이 글은 Elli Bishop이 오페라 개발자 사이트에 게시한 Creating Game-Style Parallax Scrolling: Zombie Edition을 번역한 글입니다.

Posted by 행복한고니 트랙백 0 : 댓글 1