Making jQuery Plugin(4)

피벗 슬라이드 플러그인 만들기(3)

사실, 플러그인을 만드는 방법의 핵심은 앞 페이지에서 모두 설명이 끝났습니다. 플러그인 메서드를 만드는 방법과 옵션 객체를 적용하는 방법을 알면 다른 플러그인도 쉽게 만들 수 있습니다.
여기서는 pivot 플러그인을 구현해 봅시다. 아래의 코드 처럼 작성하고 설명하겠습니다.



이벤트 연결

							jQuery.fn.pivot = function (options) {
								// 변수 선언
								/* 생략 */

								// 옵션 처리
								/* 생략 */

								// 스타일 지정
								/* 생략 */

								// 이벤트 연결
								var originalLeft = 0;
								var oldLeft = 0;
								var nowPosition = 0;
								var isDown = false;

								$target.bind('mousedown', function () {
									// source
								});

								$target.bind('mousemove', function () {
									// source
								});

								$target.bind('mouseup', function () {
									// source
								});
							}
						

우선, 변수 네 개를 선언했습니다.
변수 isDown은 사용자가 마우스를 누르는짖 확인하는 변수입니다. mousedown 이벤트가 발생하면 true로 바꾸고 mouseup 이벤트가 발생하면 false로 바꿉니다. 이렇게 함으로써 사용자가 마우스 버튼을 누르고 있을 때 변수 isDown은 true를 표시합니다.
변수 nowPosition은 현재 페이지를 나타내는 변수입니다. 초깃값은 0이며, 사용자가 페이지를 오른쪽으로 넘기면 1이 추가되고, 왼쪽으로 페이지를 넘기면 1이 감소되는 변수입니다. 이를 이용해 이미지 슬라이더처럼 animate() 메서드를 적용합니다.

중요한 것은 변수 originalLeft와 oldLeft입니다. 이벤트 발생 순서와 함께 이 두 변수를 어디에 활용하는지 알아봅시다.
우선 mousedown 이벤트가 발생하면 현재 위치를 두 변수에 저장합니다.
이어서 마우스 커서를 이동할 때마다 mousemove 이벤트가 발생합니다. 이때 변수 oldLeft를 이용해 이동한 마우스 커서와의 거리를 구해 페이지를 조금 이동시킵니다. 페이지를 이동한 후에는 현재 위치를 다시 변수 oldLeft에 넣습니다.
한번 더 mousemove 이벤트가 발생하면 변수 oldLeft를 사용해 마찬가지의 과정을 반복합니다. 이렇게 페이지를 조금씩 드래그해 이동할 때는 변수 oldLeft만 사용합니다.

mouseup 이벤트가 일어날 때는 변수 originalLeft만 사용합니다. 변수 originalLeft는 최종적으로 mouseup 이벤트가 발생할 때 mouseup 이벤트가 발생한 위치와 시작 지점의 거리를 구하는 데 사용합니다.
이때, 최종 이동 거리가 페이지 width 속성의 1/4이면 페이지를 이동합니다. 약간 복잡하지만 코드를 직접 작성하다 보면 충분히 이해할 수 있을 것입니다.

이제, 이를 토대로 구현해 봅시다. 아래의 코드 처럼 mousedown 이벤트가 발생할 때, 변수 oldLeft와 originalLeft를 지정합니다. 또한, mousedown 이벤트에서 isDown 속성을 true로 변경하고 mouseup 이벤트에서 isDown 속성을 false로 만들어 마우스를 누르고 있는 상태임을 구분하게 했습니다.



변수 선언과 이벤트 구현

							// 이벤트 연결
							var originalLeft = 0;
							var oldLeft = 0;
							var nowPosition = 0;
							var isDown = false;

							$target.bind('mousedown', function (event) {
								oldLeft = originalLeft = event.clientX;
								isDown = true;
								event.preventDefault();
							});

							$target.bind('mousemove', function (event) {
								if (isDown) {
									
								}
								event.preventDefault();
							});

							$target.bind('mouseup', function (event) {
								isDown = false;
								event.preventDefault();
							});
						

마우스를 클릭한 채로 움직이면 아래 소스 코드처럼 움직인 거리를 구하고 animate() 메서드를 사용해 드레그한 만큼 이동합니다. 일반적으로 css() 메서드를 사용해 이동 거리를 계산해서 직접 조절하지만, 그 방법이 생각보다 부드럽게 만들어지지 않으므로 animate() 메서드를 사용했습니다.



mousemove 이벤트

							$target.bind('mousemove', function (event) {
								if (isDown) {
									// 변수 선언
									var distance = oldLeft - event.clientX;
									oldLeft = event.clientX;

									// 움직임
									$target.animate({left: '-='+distance}, 0);
									$target.stop(true);
								}
								event.preventDefault();
							});
						

mousedown 이벤트와 mousemove 이벤트는 모두 처리가 끝났고, 이제 mouseup 이벤트를 살펴봅시다. 사용자가 width 옵션 속성의 1/4이상 왼쪽이나 오른쪽으로 드래그하면 변수 nowPosition을 변화시키고, animate() 메서드를 사용해 nowPosition 위치로 이동합니다.



mouseup 이벤트

							$target.bind('mouseup', function (event) {
								//  내부 함수 선언
								function movePosition (direction) {
									// 위치 설정
									var changePosition = nowPosition + direction;
									if (0 <= changePosition && changePosition < $items.length) {
										nowPosition = changePosition;
									}
								}

								// 요소의 1/4 이상 드래그를 했을 경우  피벗실행
								if (originalLeft - event.clientX >option.width / 4 ) {
									movePosition(+1);
								}else if (originalLeft - event.clientX< -option.width / 4) {
									movePosition(-1);
								}

								// 이동
								$target.animate({'left': -nowPosition*option.width}, 'fast');
								isDown = false;
								event.preventDefault();
							});
						

페이지가 좌우로 이동할 때만 animate() 메서드를 사용하면 되지, 왜 animate() 메서드를 저 위치에 놓았는지 의문이 생길 수 있습니다. 변수 nowPosition이 변화하지 않아도 원래 위치로 다시 이동해야 하므로 저 위치에 animate() 메서드를 사용한 것입니다.