'WPF RenderTransform'에 해당되는 글 1건

  1. 2010.01.24 [WPF] Drag, Scale, Rotate 1
Window/WPF2010. 1. 24. 00:57

 

 

멀티터치는 기본적으로 위와 같은 세 가지의 제스쳐를 사용하여 컨트롤 하게 됩니다.

이를 간단하게 마우스로 동작할 수 있도록 구현해 보았습니다.

멀티터치와 같이 여러 점에 반응하는 것이 아닌 마우스의 두 버튼 만으로 동작하는 점이 다르지만

객체에 전해지는 두 좌표만을 사용하는 원리에는 비슷하지 않나 싶습니다.

 

이전 Drag 예제에선 부모 컨트롤이 Canvas에 제약이 되었기 때문에

이번 예제에서는 RenderTransform 값을 변경함으로써 부모 컨트롤의 제약을 없앴습니다.

 

가지 동작 모두 처음 값과 현재 값의 차이를 구한다는 점에서 공통점이 있습니다.

드래그는 현재 좌표값에서 처음 좌표 값의 차이만큼 현재 객체의 좌표값에 더해 줌으로써 이동시킵니다.

크기 조절은 현재 비율과 처음 비율을 나누어줌으로 변경시킬 비율을 구합니다.

회전은 처음각에서 현재각의 차이를 통해 회전 각을 구합니다.

 

이론은 간단하지만 수식으로 옮기기엔 수학적인 부분이 부족하여 많은 소스들을 참고하였습니다.

수학을 잘 하시는 분이라면 쉽게 하셨을 테지만 말이죠. ^^;;

 

소스의 내용은 길지 않기 때문에 이해가 빠르실겁니다.

크기 조절과 회전 시 현재 클릭 점 위치를 기준으로 변경하여야 하기 때문에 마지막 부분에 드래그를 해주었습니다.

 

< Drag > 

   121 private void Drag(Point point)

  122 {

  123     if (!IsDragging)

  124     {

  125         // 윈도우상의 처음 좌표값의 역변환

  126         FirstCoordinate = Element.TransformToVisual(Window).Inverse.Transform(FirstPoint);

  127         IsDragging = true;

  128     }

  129 

  130     // 객체를 기준으로 역변환 값을 윈도우상의 좌표값으로 변환합니다.

  131     Point Translate = Element.TranslatePoint(FirstCoordinate, Window);

  132 

  133     // 현재 좌표값과의 차이

  134     Point Difference = new Point(point.X - Translate.X, point.Y - Translate.Y);

  135 

  136     // 좌표를 변경합니다.

  137     TranslateTrans.X += Difference.X;

  138     TranslateTrans.Y += Difference.Y;

  139 

  140     Element.RenderTransform = TransGroup;

  141 }

 

< Scale &  Rotate  >

    61 private void TransformationeEvent(object sender, MouseEventArgs e)

   62 {

   63     if (e.LeftButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Pressed)

   64     {

   65         Point CurrentPoint = e.GetPosition(Window);

   66         Point DistanceVector = new Point((CurrentPoint.X - FirstPoint.X), (FirstPoint.Y - CurrentPoint.Y));

   67 

   68         double CurrentLength = Math.Sqrt(DistanceVector.X * DistanceVector.X

   69                                                   + DistanceVector.Y * DistanceVector.Y);

   70         double CurrentAngle = Math.Atan2(DistanceVector.Y, DistanceVector.X) * 180 / Math.PI;

   71 

   72         // 포인터 위치 표시

   73         if (ShowPosition)

   74         {

   75             ChangePosition(SecondPosition, CurrentPoint);

   76         }

   77 

   78         // 크기 변경

   79         if (CanBeScaled)

   80         {

   81             if (!IsScaling)

   82             {

   83                 // 처음 비율

   84                 FirstLength = CurrentLength / ScaleTrans.ScaleX;

   85                 IsScaling = true;

   86             }

   87 

   88             if (FirstLength > 0)

   89             {

   90                 // 현재 비율

   91                 double Scale = CurrentLength / FirstLength;

   92                 ScaleTrans.ScaleX = Scale;

   93                 ScaleTrans.ScaleY = Scale;

   94             }

   95         }

   96 

   97         // 회전

   98         if (CanBeRotated)

   99         {

  100             if (!IsRotating)

  101             {

  102                 // 처음 각도

  103                 FirstAngle = CurrentAngle + RotateTrans.Angle;

  104                 IsRotating = true;

  105             }

  106 

  107             // 현재 각도

  108             double AngleDiff = (FirstAngle - CurrentAngle + 360) % 360;

  109             RotateTrans.Angle = AngleDiff;

  110         }

  111 

  112         Drag(FirstPoint);

  113     }

  114 }

 

사용은 다음과 같이 하시면 됩니다.

Transform의 첫 인자는 변경 시킬 객체, 두 번째 인자는 해당 윈도우입니다.

CanBeDragged : 드래그 여부

CanBeScaled : 크기 조절 여부

CanBeRotated : 회전 여부

ShowPosition : 클릭 점을 표시 할지 여부

 

    38 transform = new Transform(grid, this);

   39 transform.CanBeDragged = true;

   40 transform.CanBeScaled = true;

   41 transform.CanBeRotated = true;

   42 transform.ShowPosition = true;

 

전체 소스코드는 첨부파일을 받으시길 바랍니다.

※ 프로토타입 형식으로 좀 더 유연하게 코드를 수정할 필요가 있습니다.

 

조작방법

드래그 : 왼쪽 or 오른쪽 버튼 클릭 후 이동

크기 조절 / 회전 : 왼쪽과 오른쪽 버튼을 누른 후

                         왼쪽 or 오른쪽 버튼 클릭 후 이동

                         왼쪽과 오른쪽 버튼을 한번 더 누르면 해제

 

마우스가 객체나 윈도우 창을 벗어나면 모두 해제 됩니다.

 

< 시연 영상 >
화면이 끊기네요 ㅡㅡ;;


'Window > WPF' 카테고리의 다른 글

[ WPF ] Window 사이즈 변경 시 컨트롤 크기 변경하기  (3) 2010.02.08
[WPF] Object Capture  (0) 2010.01.29
[WPF] 시계 만들기  (0) 2010.01.26
[WPF] Image Pixel  (0) 2010.01.24
[ WPF ] Drag  (0) 2009.09.27
Posted by 열ㅇl