說到對象的旋轉,或許就會聯想到對象角度的概念。對象的旋轉實現實際上就是利用對象的角度改變來實現的位置變換,在《Silverlight & Blend動畫設計系列二:旋轉動畫(RotateTransform)》一文中有對對象的不同角度變換的實現介紹,本篇要介紹的自由旋轉(Free-form rotation)將藉助《Function Silverlight 3 Animation》一書中的示例項目介紹,詳細敬請閱讀本文。
要實現自由旋轉其實非常簡單,需要特別注意的有四點,既旋轉對象、旋轉中心點、旋轉角度及旋轉焦點。可以簡單理解爲當點擊對象上的某一點可以對對象實現其以某一中心點爲準的不等角度旋轉。爲了方便控制通常會將旋轉焦點設計爲相對突出的UI呈現,如下圖示:
上圖的UI外觀設計爲一個獨立的UserControl,對應的xaml定義如下:
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 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>
/// <param name="Radians"></param>
/// <returns></returns>
private double RadiansToDegrees(double Radians)
{
return Radians * 180 / Math.PI;
}
{
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 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);
}
}
推薦資源:
《Function Silverlight 3 Animation》----本篇中使用的示例素材選自此書