Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...
說到對象的旋轉,或許就會聯想到對象角度的概念。對象的旋轉實現實際上就是利用對象的角度改變來實現的位置變換,在《Silverlight & Blend動畫設計系列二:旋轉動畫(RotateTransform)》一文中有對對象的不同角度變換的實現介紹,本篇要介紹的自由旋轉(Free-form rotation)將借助《Function Silverlight 3 Animation》一書中的示例項目介紹,詳細敬請閱讀本文。
?
要實現自由旋轉其實非常簡單,需要特別注意的有四點,既旋轉對象、旋轉中心點、旋轉角度及旋轉焦點。可以簡單理解為當點擊對象上的某一點可以對對象實現其以某一中心點為準的不等角度旋轉。為了方便控制通常會將旋轉焦點設計為相對突出的UI呈現,如下圖示:
?
? 上圖的UI外觀設計為一個獨立的UserControl,對應的xaml定義如下:
<UserControl?x:Class="ImageRotate.RotateItem"????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"?
????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"?
????Width="320"?Height="240">
????<Canvas?x:Name="ItemCanvas"?Width="320"?Height="240"?Canvas.Left="77"?Canvas.Top="57"?Background="#FFFFFFFF"?
????RenderTransformOrigin="0.5,0.5">
????????<Canvas.RenderTransform>
????????????<TransformGroup>
????????????????<RotateTransform?x:Name="RotateItemCanvas"?Angle="0"/>
????????????</TransformGroup>
????????</Canvas.RenderTransform>????????
????????<Image?x:Name="Image"?Width="300"?Height="220"?Canvas.Left="10"?Canvas.Top="10"?Source=""?Stretch="Fill"/>
????????<Ellipse?x:Name="Handle"?Width="15"?Height="15"?Fill="#FFEAFF00"?Stroke="#FF000000"?Canvas.Left="313"?Canvas.Top="233"/>
????</Canvas>
</UserControl>
?
分析上面的xaml可以知道,整個界面通過基于坐標的Canvas進行布局,默認設置布局容器的旋轉角度為0度,在Canvas里面放置了一個圖片作為可旋轉的對象外觀呈現,一個圓形作為旋轉焦點。最終實現旋轉功能的就是鼠標在Ellipse對象上的事件應用,通過事件處理函數來改變整個布局容器的旋轉角度(Angle)。?
private?bool?IsMouseCaptured;private?Point?MousePosition;
private?Point?LastPosition;
public?Point?CanvasCenter;
private?double?LastAngle;
private?double?CurrentAngle;
private?double?AngleDelta;
public?RotateItem()
{
????InitializeComponent();
????//注冊Ellipse對象的鼠標事件
????Handle.MouseLeftButtonDown?+=?new?MouseButtonEventHandler(Handle_MouseLeftButtonDown);
????Handle.MouseLeftButtonUp?+=?new?MouseButtonEventHandler(Handle_MouseLeftButtonUp);
????Handle.MouseMove?+=?new?MouseEventHandler(Handle_MouseMove);
}
private?void?Handle_MouseLeftButtonUp(object?sender,?MouseButtonEventArgs?e)
{
????FrameworkElement?Item?=?sender?as?FrameworkElement;
????Item.ReleaseMouseCapture();
????IsMouseCaptured?=?false;
????Item.Cursor?=?null;
}
private?void?Handle_MouseLeftButtonDown(object?sender,?MouseButtonEventArgs?e)
{
????FrameworkElement?Item?=?sender?as?FrameworkElement;
????Item.CaptureMouse();
????Item.Cursor?=?Cursors.Hand;
????IsMouseCaptured?=?true;
????LastPosition?=?e.GetPosition(null);
}
?
最關鍵的就是MouseMove事件了,在MouseMove事件處理函數中,通過計算鼠標點下時的坐標和當前所在的坐標進行弧度轉化角度的計算,將得到的角度值設置為Canvas的旋轉角度就達到了實現對象的自由旋轉功能。
?
以下為弧度轉化為角度的計算公式以及MouseMove事件算法實現:
///?<summary>///?弧度轉化為角度
///?</summary>
///?<param?name="Radians"></param>
///?<returns></returns>
private?double?RadiansToDegrees(double?Radians)
{
????return?Radians?*?180?/?Math.PI;
}
?
private void?Handle_MouseMove(object?sender,?MouseEventArgs?e){
????MousePosition?=?e.GetPosition(null);
????if?(IsMouseCaptured)
????{
????????LastAngle?=?Math.Atan2(LastPosition.Y?-?CanvasCenter.Y,?LastPosition.X?-?CanvasCenter.X);
????????CurrentAngle?=?Math.Atan2(MousePosition.Y?-?CanvasCenter.Y,?MousePosition.X?-?CanvasCenter.X);
????????AngleDelta?=?CurrentAngle?-?LastAngle;
????????RotateItemCanvas.Angle?+=?RadiansToDegrees(AngleDelta);
????????LastPosition?=?MousePosition;
????}
}
?
可旋轉UserControl完整代碼 public?partial?class?RotateItem?:?UserControl{
????private?bool?IsMouseCaptured;
????private?Point?MousePosition;
????private?Point?LastPosition;
????public?Point?CanvasCenter;
????private?double?LastAngle;
????private?double?CurrentAngle;
????private?double?AngleDelta;
????public?RotateItem()
????{
????????InitializeComponent();
????????Handle.MouseLeftButtonDown?+=?new?MouseButtonEventHandler(Handle_MouseLeftButtonDown);
????????Handle.MouseLeftButtonUp?+=?new?MouseButtonEventHandler(Handle_MouseLeftButtonUp);
????????Handle.MouseMove?+=?new?MouseEventHandler(Handle_MouseMove);
????}
????private?void?Handle_MouseLeftButtonUp(object?sender,?MouseButtonEventArgs?e)
????{
????????FrameworkElement?Item?=?sender?as?FrameworkElement;
????????Item.ReleaseMouseCapture();
????????IsMouseCaptured?=?false;
????????Item.Cursor?=?null;
????}
????private?void?Handle_MouseLeftButtonDown(object?sender,?MouseButtonEventArgs?e)
????{
????????FrameworkElement?Item?=?sender?as?FrameworkElement;
????????Item.CaptureMouse();
????????Item.Cursor?=?Cursors.Hand;
????????IsMouseCaptured?=?true;
????????LastPosition?=?e.GetPosition(null);
????}
????private?void?Handle_MouseMove(object?sender,?MouseEventArgs?e)
????{
????????MousePosition?=?e.GetPosition(null);
????????if?(IsMouseCaptured)
????????{
????????????LastAngle?=?Math.Atan2(LastPosition.Y?-?CanvasCenter.Y,?LastPosition.X?-?CanvasCenter.X);
????????????CurrentAngle?=?Math.Atan2(MousePosition.Y?-?CanvasCenter.Y,?MousePosition.X?-?CanvasCenter.X);
????????????AngleDelta?=?CurrentAngle?-?LastAngle;
????????????RotateItemCanvas.Angle?+=?RadiansToDegrees(AngleDelta);
????????????LastPosition?=?MousePosition;
????????}
????}
????????
????///?<summary>
????///?弧度轉化為角度
????///?</summary>
????///?<param?name="Radians"></param>
????///?<returns></returns>
????private?double?RadiansToDegrees(double?Radians)
????{
????????return?Radians?*?180?/?Math.PI;
????}
}
?
使用也是非常簡單的,動態創建上面所創建的UserControl然后將其添加到主容器控件中就可以了,如下演示代碼:
?
public?partial?class?MainPage?:?UserControl{
????public?MainPage()
????{
????????InitializeComponent();
????????var?Picture1?=?new?RotateItem();
????????Picture1.Image.Source?=?new?BitmapImage(new?Uri("Marigold.jpg",?UriKind.Relative));
????????Picture1.SetValue(Canvas.LeftProperty,?100.00);
????????Picture1.SetValue(Canvas.TopProperty,?100.00);
????????Picture1.CanvasCenter.X?=?(double)Picture1.GetValue(Canvas.LeftProperty)?+?Picture1.Width?/?2;
????????Picture1.CanvasCenter.Y?=?(double)Picture1.GetValue(Canvas.TopProperty)?+?Picture1.Height?/?2;
????????Picture1.RotateItemCanvas.Angle?=?-15;
????????LayoutRoot.Children.Add(Picture1);
????}
}
?
?
?
推薦資源:
Silverlight & Blend動畫設計系列文章
《Function Silverlight 3 Animation》----本篇中使用的示例素材選自此書
?
????
版權說明
? 本文屬原創文章,歡迎轉載且注明文章出處,其版權歸作者和博客園共有。??
? 作??????者:Beniao
?文章出處:http://beniao.cnblogs.com/? 或? http://www.cnblogs.com/
?
轉載于:https://www.cnblogs.com/beniao/archive/2010/06/20/1735898.html
總結
以上是生活随笔為你收集整理的Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言中float,double类型,在
- 下一篇: Trade Stages - The T