Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...
說到對象的旋轉(zhuǎn),或許就會(huì)聯(lián)想到對象角度的概念。對象的旋轉(zhuǎn)實(shí)現(xiàn)實(shí)際上就是利用對象的角度改變來實(shí)現(xiàn)的位置變換,在《Silverlight & Blend動(dòng)畫設(shè)計(jì)系列二:旋轉(zhuǎn)動(dòng)畫(RotateTransform)》一文中有對對象的不同角度變換的實(shí)現(xiàn)介紹,本篇要介紹的自由旋轉(zhuǎn)(Free-form rotation)將借助《Function Silverlight 3 Animation》一書中的示例項(xiàng)目介紹,詳細(xì)敬請閱讀本文。
?
要實(shí)現(xiàn)自由旋轉(zhuǎn)其實(shí)非常簡單,需要特別注意的有四點(diǎn),既旋轉(zhuǎn)對象、旋轉(zhuǎn)中心點(diǎn)、旋轉(zhuǎn)角度及旋轉(zhuǎn)焦點(diǎn)。可以簡單理解為當(dāng)點(diǎn)擊對象上的某一點(diǎn)可以對對象實(shí)現(xiàn)其以某一中心點(diǎn)為準(zhǔn)的不等角度旋轉(zhuǎn)。為了方便控制通常會(huì)將旋轉(zhuǎn)焦點(diǎn)設(shè)計(jì)為相對突出的UI呈現(xiàn),如下圖示:
?
? 上圖的UI外觀設(shè)計(jì)為一個(gè)獨(dú)立的UserControl,對應(yīng)的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可以知道,整個(gè)界面通過基于坐標(biāo)的Canvas進(jìn)行布局,默認(rèn)設(shè)置布局容器的旋轉(zhuǎn)角度為0度,在Canvas里面放置了一個(gè)圖片作為可旋轉(zhuǎn)的對象外觀呈現(xiàn),一個(gè)圓形作為旋轉(zhuǎn)焦點(diǎn)。最終實(shí)現(xiàn)旋轉(zhuǎn)功能的就是鼠標(biāo)在Ellipse對象上的事件應(yīng)用,通過事件處理函數(shù)來改變整個(gè)布局容器的旋轉(zhuǎn)角度(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對象的鼠標(biāo)事件
????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);
}
?
最關(guān)鍵的就是MouseMove事件了,在MouseMove事件處理函數(shù)中,通過計(jì)算鼠標(biāo)點(diǎn)下時(shí)的坐標(biāo)和當(dāng)前所在的坐標(biāo)進(jìn)行弧度轉(zhuǎn)化角度的計(jì)算,將得到的角度值設(shè)置為Canvas的旋轉(zhuǎn)角度就達(dá)到了實(shí)現(xiàn)對象的自由旋轉(zhuǎn)功能。
?
以下為弧度轉(zhuǎn)化為角度的計(jì)算公式以及MouseMove事件算法實(shí)現(xiàn):
///?<summary>///?弧度轉(zhuǎn)化為角度
///?</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;
????}
}
?
可旋轉(zhuǎn)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>
????///?弧度轉(zhuǎn)化為角度
????///?</summary>
????///?<param?name="Radians"></param>
????///?<returns></returns>
????private?double?RadiansToDegrees(double?Radians)
????{
????????return?Radians?*?180?/?Math.PI;
????}
}
?
使用也是非常簡單的,動(dòng)態(tài)創(chuàng)建上面所創(chuàng)建的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動(dòng)畫設(shè)計(jì)系列文章
《Function Silverlight 3 Animation》----本篇中使用的示例素材選自此書
?
????
版權(quán)說明
? 本文屬原創(chuàng)文章,歡迎轉(zhuǎn)載且注明文章出處,其版權(quán)歸作者和博客園共有。??
? 作??????者:Beniao
?文章出處:http://beniao.cnblogs.com/? 或? http://www.cnblogs.com/
?
轉(zhuǎn)載于:https://www.cnblogs.com/beniao/archive/2010/06/20/1735898.html
總結(jié)
以上是生活随笔為你收集整理的Silverlight Blend动画设计系列十二:三角函数(Trigonometry)动画之自由旋转(Free-form rotation)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言中float,double类型,在
- 下一篇: Trade Stages - The T