marojun’s Android

안드로이드 관련 글을 공유합니다. 

path tracing

marojun
marojun’s Android
7 min readDec 31, 2013

--

path tracing을 좀 더 알기 쉽게 설명하기 위해 Road Trip USA라는 앱을 제작하게 되었다. 아래는 해당앱을 실행했을 때의 영상인데 이를 통해 해당 효과가 어떻게, 어디서 사용되는지 알아보도록하자.

Road Trip USA

영상을 보면 알겠지만 path tracing을 통해 미국 전역을 그린다던지 각 주들의 외곽선, 그리고 주의 이름을 표현 할 때 사용됨을 알 수 있다. 이처럼 해당 효과는 애플리케이션의 곳곳에서 사용되고있다.

드래그 인디케이터

이 뿐만이 아니라 로딩이 완료된 후에 나타나는 드래그 인디케이터를 그릴 때도 이것이 사용되었으며

프로그레스 인디케이터

처음부분에 갈매기형 모양(chevron)으로 움직이는 프로그레스 인디케이터는 path tracing과 매우 유사한 기술을 이용하여 구현되었다.

이제부터는 좀 더 구체적으로 설명하기에 쉽게 이해할 수 있도록 소스코드debug APK를 다운받을 것을 추천한다.

Path effects

path effects는 일반적으로 잘 사용하지 않은 Android API인 PathEffect를 통해 구현된다. PathEffect를 Paint에 셋팅함으로써 Canvas.drawPath() 명령에 적용될 수 있으며 이를 통한 path effects에는 네 가지 주요 타입이 있다.

일반적인 타입 Path. Path를 기준으로 4가지 효과를 줄 수 있다.

CornerPathEffect

CornerPathEffect는 path의 뾰족한 코너를 둥글게 만드는데 쓰인다 (예를 들어, 서로 연결된 path 중첩부분을 곡선으로 만든다고 생각하면 된다.)

DashPathEffect

DashPathEffect는 일련의 dash들을 사용하여 path를 그리는 것을 말한다.

DiscretePathEffect

DiscretePathEffect는 path를 임의로 배치된 일련의 segments(조각)으로 나눈다.

PathDashPathEffect

PathDashPathEffect는 path를 스탬프(마크)로 사용하여 경로를 그린다. (예를 들어 스탬프를 별모양으로 지정한다면 선 대신에 별모양이 그려질 것이다.)

CornerPathEffect + DashPathEffect

위 4가지 효과들은 ComposePathEffect 또는 SumPathEffect를 이용하여 결합하여 사용할 수 있다. 예를 들어, 서로 연결된 일련의 선들을 CornerPathEffect와 DashPathEffect를 병합하는데 ComposeEffect 를 이용하여 대쉬 곡선으로 변할 수 있도록 도와주는 것이다.

참고로 앞에서 보여준 데모는 path effects중 DashPathEffect 와 PathDashPathEffect 두 가지만 사용하였다:

Phase out

프로그레스 인디케이터는 PathDashPathEffect 와 오목한 화살표를 스탬프로 사용하여 구현되었다. 사실 PathEffect API가 모든 작업을 수행해주기 때문에, 가장 어려운 부분은 경로를 만드는 것이라고 할 수 있다.

프로그레스 애니메이션을 만들기 위해 사용할 파라메터는 phase 파라메터이다. 이 값은 첫번째 스탬프가 나오기전에 offset을 정의하는 데 사용될 수 있다. 이 값을 애니메이션으로 만듬으로써 우리는 효율적으로 화살표가 경로를 따라 움직이게 할 수 있다. 아래 그림은 다른 페이즈를 통해 그려진 동일한 경로를 보여준다.

Path tracing

tracing 애니메이션은 PathDashPathEffect 대신 DashPathEffect 의 phase 파라미터를 이용하여 구현되었다. DashPathEffect 구성은 대쉬의 길이 및 대쉬 간의 간격을 명시할 수 있도록 해준다. 여기서의 핵심은 대쉬와 간격을 경로 크기만큼 길게 만드는 것이다.

선의 길이를 계산하는 것은 매우 쉽지만, 임의의 경로 길이를 측정하는것은 이차 및 삼차 곡선의 길이를 측정해야하기 때문에 조금 더 복잡하다. 다행히도 안드로이드는 이것을 수행 할 수 있는 쉬운 API를 제공한다.

위의 예시를 실행하면, PathEffect 가 적용되지 않았을 때 동일한 경로가 보일 것이다. 이것은 DashPathEffect 가 항상 대쉬를 가장 먼저 그리기 때문이다. tracing 효과를 만들기 위해서는 경로의 길이와 동일한 phase부터 시작해야 한다.

이제 phase 값을 0.0f과 length값 사이에서 애니메이션화 함으로써 완벽한 효과가 구현될 수 있다. 해당 애니메이션의 구현은 StateView.java에서 확인할 수 있다.

Tracing an arrow

화살표 형태로 그려는 드래드 인디케이터는 구현하기 조금 더 어렵다. 우리는 하나가 아닌 두 가지의 경로 효과를 사용해야 한다: DashPathEffect 로 화살표 길을 그리고, PathDashPathEffect 를 이용하여 나머지 부분을 그려야 한다. PathDashPathEffect의 접근은 화살표의 끝부분을 경로를 끝으로 보내게 하기 위해 세팅된다.

이에 대한 자제한 내용은 IntroView.java 파일에서 확인할 수 있다.

Using SVG paths

이 앱에서는 경로를 저장하기 위해 SVG 파일을 사용했다. 이는 간편한 반면, 여기서 사용하는 라이브러리 문제 인지는 모르겠지만 로딩시간이 굉장히 느리다는 것을 알 수 있다. 나중에 이 효과를 실제 어플리케이션에서 적용한다면 성능을 위해서라도 커스텀 바이너리 포맷으로 바꿀 필요가 있다. 만약 이 효과가 경로만을 필요로 하고, 스타일링 정보가 필요없다면 이 포맷은 파싱하기 매우 빠르고 간편할 것이다.

여기서 선택한 androidsvg 라이브러리는 사용하기는 쉽지만, SVG 다큐먼트에 포함 된 경로에 대한 권한은 주지 않는다. 이 이슈를 해결하기 위해 drawPath() 콜을 인터셉트하는 커스텀 Canvas를 생성했다.

경로들은 미리 변형되어 저장되기 때문에, 이것에 대한 길이를 최종 스크린상의 사이즈로 잴 수 있다. 이 코드를 좀 더 발전시킨 버전은 SvgHelper.java 에서 볼 수 있다. 이 데모에서 사용 된 구현 방법은 경로가 컨테이너를 적절히 채울 수 있도록 스케일링 하는 것을 포함한다.

Other visual effects

데모를 유심히 봤다면 몇가지 추가 시각적 효과를 찾을 수 있었을 것이다.

흑백 색상 변환은 이미지 행을 왼쪽으로 스크롤링 할 때 사용된다 (첫번째 이미지는 흑백으로 시작하여 컬러를 먹게 변함)

핀 스크롤링은 리스트를 스크롤 업, 다운할 때 “stack card” 효과를 만들 때 사용된다.

시차 스크롤링은 다양한 지도들을 기타 아이템들과 다른 속도로 스크롤하는 데 사용된다.

구글 뮤직에서도 보여진 애니메이션 액션 바 불투명도도 포함된다.

이 모든 효과들은 MainActivity.java 에서 찾아볼 수 있다.

--

--

marojun’s Android
marojun’s Android

Published in marojun’s Android

안드로이드 관련 글을 공유합니다. 

marojun
marojun

Written by marojun

전슬마로. KTH, SK Planet, NCSOFT 에서 iOS와 Android를 개발하고 있다. — 안드로이드 개발 그룹 https://www.facebook.com/groups/junsle/

No responses yet