Silverlight动画基础六:动画与三角函数-图片旋转

ImageRotate主要讲是使用正弦、余弦函数结合鼠标拖动来完成对象按拖动角度选择。

效果图如下,按黄色的角拖动可以使图片围绕中心旋转。

image

此代码主要包含了两个对象

1.RotateItem:用于实现和控制对象的旋转。

2.ImageRotate:容器。

首先来看一下RotateItem对象

 

RotateItem

主要对象,RotateItem对象实现了对自身鼠标旋转的控制,使用鼠标拖动事件结合Math.Atan2函数进行对象的角度。代码如下:

 

RotateItem.xaml代码

<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" Stretch="Fill"/>
<!--Thumb-->
<Ellipse x:Name="Handle" Width="15" Height="15"
Canvas.Left="313" Canvas.Top="233"
Fill="#FFEAFF00" Stroke="#FF000000"/>
</Canvas>

 
RotateItem.xaml.cs代码,主要代码都在这里处理。
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);
}

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;
}
}

void Handle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
//释放鼠标捕捉
          FrameworkElement Item = sender as FrameworkElement;
Item.ReleaseMouseCapture();
IsMouseCaptured = false;
Item.Cursor = null;
}

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 double RadiansToDegrees(double Radians)
{
return Radians * 180 / Math.PI;
}
}

关键代码中的注释已经说明了它的基本用法。

 

 

ImageRotate

ImageRotate对象为容器,用于承载RotateItem,提供了对RotateItem的初始化、加载等功能。

 

ImageRotate.xaml代码:

<Canvas x:Name="LayoutRoot" Width="800" Height="600">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF3F45AC"/>
<GradientStop Color="#FF05083A" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
</Canvas>

 

ImageRotate.xaml.cs代码:

public partial class ImageRotate : Page
{
private RotateItem Picture1;
private RotateItem Picture2;
public ImageRotate()
{
InitializeComponent();

//初始化两个RotateItem对象,RotateItem根据各自的位置来设置其中心点
        Picture1 = new RotateItem();
Picture1.Image.Source = new BitmapImage
(new Uri("/AnimationSample;component/images/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);


Picture2 = new RotateItem();
Picture2.Image.Source = new BitmapImage
(new Uri("/AnimationSample;component/images/PurpleFlower.jpg", UriKind.Relative));
Picture2.SetValue(Canvas.LeftProperty, 400.00);
Picture2.SetValue(Canvas.TopProperty, 300.00);
//设置中心点
        Picture2.CanvasCenter.X = (double)Picture2.GetValue(Canvas.LeftProperty) + Picture2.Width / 2;
Picture2.CanvasCenter.Y = (double)Picture2.GetValue(Canvas.TopProperty) + Picture2.Height / 2;
Picture2.RotateItemCanvas.Angle = -15;
LayoutRoot.Children.Add(Picture2);

}
}

 

所有代码已经完成了

运行效果演示地址:点击查看

 

总结:从代码中可以发现,主要使用了Math.Atan2函数,根据鼠标前后位置的变化值,

计算出围绕RotateItem中心点的旋转角度。

image

 

 

【注:本文技术论点源于《Foundation Silverlight 3 Animation》,个人理解可能存在差异,请参考原著】

posted @ 2011-04-12 22:47  vvince  阅读(637)  评论(0编辑  收藏  举报