티스토리 뷰

WindowsPhone

WP7 개발 기초 - 모양 형상과 변형

생각많은 소심남 2012. 1. 31. 23:54
TextBlock과 Image에 대한 정보를 봤으니 이번에는 도형을 만드는 법과 그 도형을 변형하는 방법에 대해 알아보겠습니다.

우선 기본 프로젝트에 포함된 Reference중에는 System.Windows.Shapes라는 네임스페이스가 이런 도형을 생성할 수 있게끔 도와줍니다. 그 클래스중에는 Ellipse와 Rectangle 등이 있지요.

우선 ContentPanel안에 다음과 같이 삽입해봅니다.

 
그럼 아래와 같이 큰 타원형이 생깁니다.

 
그럼 Ellipse안에 HorizontalAlignment와 VerticalAlignment를 설정하는 걸 집어넣어봅시다.

 


사라지는군요. 그런데 지금 디자인뷰에서도 아주 조그맣게 보이다시피 이 타원이 수축된겁니다. 왜냐하면 이 Ellipse라는 것 자체가 최소크기라는게 없기 때문입니다. 그래서 가운데 정렬을 하면서 확 줄어버리는 것이지요. 이렇게 타원을 정렬시키고자 할때는 그 타원의 Width와 Height을 조절하는 것이 필요합니다.

stroke랑 fill은 감이 오실겁니다. fill은 그 타원을 채우는 색, stroke는 겉의 테두리를 채우는 겉이겠지요. StrokeThickness를 통해서는 그 테두리의 두께를 결정짓는데 쓰입니다. 물론 여기에 사용된 특성모두 brush타입이기때문에 일전에 다뤘던 GradientBrush속성을 적용할 수 있습니다. 우선 width과 Height을 같게 통일시키고 안의 fill에 대한 부분도 RadialGradientBrush로 처리하면
 


위와같은 사진이 나옵니다. 이를 이용하면


입체감있는 도형도 나올 수 있겠습니다. 여기서 쓰인 RadialGradientBrush는 원형으로 그레디언트를 주는 효과입니다. 전에 배웠던 LinearGradientBrush가 선을 이루면서 그레디언트 효과를 주던 것과는 차이가 있는 것이죠.

이재 도형의 형성과 색깔입히는 것을 해봤으니 이 도형을 기반으로 변형을 줄수 있습니다.
영어에서도 변형이라 쓰이는 Transform 클래스가 바로 변형시에 쓰이는 겁니다.
Transform 클래스에는 여러개가 있는데 
- ScaleTransform : 크기 변화
- TranslateTransform : 위치 이동
- RotateTransform : 회전
- SkewTransform : 기울임
- MatrixTransform : 동시적용
- TransformGroup : 다양한 변형
-  CompositeTrnasform : 순서에 따른 변형

등을 줄 수 있습니다. 예를 들어서 각 Transform을 TransformGroup으로 묶어서 정리하면 코드를 다시보는 입장에서는 더 빠르게 이해할 수도 있고 적용도 쉬워집니다.

 
이런식으로 표현한건 그냥 기본적으로 보이는 설정입니다. 이제 여기서 변화를 주게 된다면 값이 변하겠지요.
이걸로 통해서 얻을 수 있는 장점은 만약 여러개의 개체를 한꺼번에 변형을 시킨다고 했을때 이 TransformGroup을 사용한다면 일일이 숫자를 바꿔줄 필요없이  이 내에서만 바꿔주면 알아서 적용된다는 겁니다. 
예를 든다면

 
이런식으로 기울임을 주는 건 금방 할 겁니다. 

여기서 한가지 효과를 주지 않은게 TranslateTransform인데 이건 보통 음각효과를 낼 때 쓰입니다. 흔히 엠보싱효과라고도 합니다. 이때는 약간의 트릭이 필요합니다. 

 
우선 두개의 같은 TextBlock을 생성한후 각각의 배경을  테마색으로 준겁니다. 보통 한글자로만 표현할 것 같은데 지금과 같은 경우는 두개를 겹치고 TranslateTransform을 사용한게 된겁니다. 결과는


 
와 같은 결과를 보여줍니다.

명심해야할 점은 아무 설정을 하지 않은 상태에서의 모든 변형은 그 개체를 둘러싸고 있는 네모의 왼쪽 상단 모서리를 기준으로 일어난다는 겁니다. 물론 이를 보정하는 방법으로는 CenterX와 CenterY값을 이용한 수정이 될 수도 있겠지만 
아예 기준을 바꿔버리면 변형하는데 있어서 예측가능하겠지요.


위와 같이 RenderTransformOrigin을 저렇게 잡으면 중심을 기점으로 변형됩니다. 
이전처럼 왼쪽 상단모서리를 기준으로 된건 바로 이 옵션이 (0 0)으로 결정되어있기 때문입니다. 물론 (1 1)로 되어 있으면 기준은 오른쪽 하단 모서리가 될 겁니다.
 
이전 포스팅에서 다뤘던 스타일에도 이런 Transform을 지정할 수 있습니다. 어떤 이름의 Style을 지정한후

<Setter Property="RanderTransform">
 <Setter.Value>
............
</Setter.Value>

를 통해서 집어넣을 수 있다는 거지요. 다만 이렇게 하면 코드를 사용해서 조작할 수 있지만 이런 스타일을 적용하는 개체에는 이런 리소스가 공유된다는 것을 명심해야 합니다.가령 RenderTransform을 여러개 사용해서 표현하고 싶은데 이에 적용하는 개체가 많다면 또 고려해볼만한 여지가 된다는 겁니다. 이때 사용하는 것이 바로 중간에 설명했던 CompositeTransform이라는 겁니다. 잠깐 언급했지만 정해진 순서에 따라 변형을 유발하는 것이라고 하네요.

이를 적절하게 활용한 것이 바로 원문의 예제로 나와있는 hybrid Clock이라는 겁니다.


 지금은 변형을 줄 TextBlock의 이름만 설정한 것이기 때문에 디자인 뷰에서는 아무것도 안보입니다.
이제 숨어있는 cs코드에서 CompositeTransform을 불러와야 합니다.
그리고 여기서 그 코드에서는 OnContentPanelSizeChanged란 핸들러를 통해서도 사이즈를 조절할 수도 있어야 합니다.

 참고로 코드에서 쓰일 DispatcherTimer를 위해서는 using 지시자로 system.Windows.Threading을 포함시켜야합니다.
 



우선 시계로 쓸것이기 때문에 Threading에 포함되어있는 DispatcherTimer를 사용해야합니다. 물론 주기는 1초단위로 움직이고 시간이 지날수록 그 값이 증가해야 되겠지요.


기존 xaml 상에서 Sizechaged 핸들러를 사용하면서 그 ContentPanel의 중심과 referencetext라 명명된 TextBlock의 크기를 정합니다. 그래서 UpdateClock 메서드를 불러오는데 여기서 이 referencetext를 기준으로 크기를 정하게 됩니다. 따라서 이 값은 변하지 말아야 합니다.
updateClock에서는 현재시간을 받아서 그 값을 각각의 초 분 시에 돌려주고 움직이는 각도를 정해주고 있습니다.


이제 위에서 받은 값을 표현해주고 renderTransform을 사용해서 회전이 되게끔 해야 합니다. 여기서 앞에서 말했던 CompositeTransform이 등장하게 됩니다. 위에 나와있는 값들은 사전에 계산된 값입니다. 그냥 이대로 하고 실행에 보도록 하겠습니다.
 

 
보다시피 시계가 움직이면서 그안에 포함된 수치가 해당 값을 나타내고 Rotation이 되면서 돌아가고 있습니다.
이처럼 CompositeTransform을 사용하면 코드상에서 그 값을 수정하면서 조금더 응용할 수 있는 여지를 보여줍니다.
물론 이를 위해서는 사전에 Scale이나 angle에 대한 계산이 이뤄져야하겠지요.

이번 포스팅에서는 도형의 생성 및 그 변형에 대해서 알아봤습니다!

댓글