2011-07-14 44 views
1

我想实现像样式的转盘,我发现很难用鼠标移动事件移动磁盘。用鼠标移动事件旋转图像

这是我的XAML代码

<!-- Disk rotating code --> 
     <StackPanel x:Name="disk" Margin="0,-60,0,0"> 
      <StackPanel.Resources> 
       <Storyboard x:Name="myStoryboard"> 
        <DoubleAnimation Storyboard.TargetName="myTransform" 
            Storyboard.TargetProperty="Angle" 
            From="0" To="360" Duration="0:0:5" 
            RepeatBehavior="Forever"> 
        </DoubleAnimation> 
       </Storyboard> 
      </StackPanel.Resources> 
      <Rectangle x:Name="ttbg" Margin="5,200,30,0" Stroke="Black" StrokeThickness="0" RenderTransformOrigin="0.503,0.503" Height="420" Width="420" MouseLeftButtonDown="press_down" MouseLeftButtonUp="press_up" MouseMove="press_move" > 
      <Rectangle.Fill> 
        <ImageBrush ImageSource="Images/ttbg.png" Stretch="Uniform" /> 
      </Rectangle.Fill> 
       <Rectangle.RenderTransform> 
        <TransformGroup> 
         <RotateTransform x:Name="myTransform" /> 
        </TransformGroup> 
       </Rectangle.RenderTransform> 
      </Rectangle> 
     </StackPanel> 

这是我的C#代码从一个新手

回答

1

private void press_down(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 

    } 

    private void press_up(object sender, System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 
    } 

    private void press_move(object sender, System.Windows.Input.MouseEventArgs e) 
    { 
     // TODO: Add event handler implementation here. 

    } 

问题这是一个有点棘手,需要一些编码。但我会试一试。

首先,我更改了XAML,以便我将使用Canvas而不是您使用的StackPanel。在这种情况下,我更喜欢Canvas,因为它允许我使用绝对坐标定位转盘图像,以便我确切知道转盘中心的位置。在XAML现在看起来是这样的:

<UserControl x:Class="TurnTable.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="400" 
    > 

    <Canvas x:Name="LayoutRoot" Background="White"> 
     <!-- Disk rotating code --> 
     <Canvas.Resources> 
      <Storyboard x:Name="myStoryboard"> 
       <DoubleAnimation x:Name="angleAnimation" Storyboard.TargetName="myTransform" 
            Storyboard.TargetProperty="Angle" 
            From="0" To="0" Duration="0:0:1" 
            > 
        <DoubleAnimation.EasingFunction> 
         <CubicEase /> 
        </DoubleAnimation.EasingFunction> 
       </DoubleAnimation> 
      </Storyboard> 
     </Canvas.Resources> 
     <Rectangle x:Name="ttbg" Canvas.Left="100" Canvas.Top="100" Stroke="Black" StrokeThickness="0" RenderTransformOrigin="0.5,0.5" Height="420" Width="420" MouseLeftButtonDown="press_down" MouseLeftButtonUp="press_up" MouseMove="press_move" > 
      <Rectangle.Fill> 
       <ImageBrush ImageSource="Images/ttbg.png" Stretch="Uniform" /> 
      </Rectangle.Fill> 
      <Rectangle.RenderTransform> 
       <TransformGroup> 
        <RotateTransform x:Name="myTransform" /> 
       </TransformGroup> 
      </Rectangle.RenderTransform> 
     </Rectangle> 
    </Canvas> 
</UserControl> 

另外请注意,我把故事板1秒的时间,我给它一个EasingFunction给动画一个漂亮的外观和感觉。

在用户控件的代码隐藏中,我使用Math.Atan函数来计算鼠标移动时转动转盘的角度。我正在使用鼠标相对于转盘中心的坐标来确定要馈送到Math.Atan的值。该代码最终看起来如下:

namespace TurnTable 
{ 
    public partial class MainPage : UserControl 
    { 
     Point _centerOfTurnTable; 
     Point _startMousePosition; 
     Point _lastMousePosition; 
     bool _isMouseCaptured = false; 
     double _deltaAngle; 

     public MainPage() 
     { 
      InitializeComponent(); 
     } 

     private void press_down(object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      _centerOfTurnTable = new Point 
      (
       Canvas.GetLeft(ttbg) + ttbg.ActualWidth/2d, 
       Canvas.GetTop(ttbg) + ttbg.ActualHeight/2d 
      ); 

      myStoryboard.Pause(); 

      _startMousePosition = e.GetPosition(this); 
      _isMouseCaptured = true; 
      _lastMousePosition = _startMousePosition; 
     } 

     private void press_up(object sender, System.Windows.Input.MouseButtonEventArgs e) 
     { 
      if (_isMouseCaptured) 
      { 
       _isMouseCaptured = false; 

       angleAnimation.From = myTransform.Angle; 
       angleAnimation.To = myTransform.Angle + _deltaAngle * 100; 
       _deltaAngle = 0; 
       myStoryboard.Begin(); 
      } 
     } 

     private void press_move(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      Point currentMousePosition = e.GetPosition(this); 
      if (_isMouseCaptured && Math.Abs(currentMousePosition.X - _centerOfTurnTable.X) > 5) 
      { 
       _deltaAngle = GetAngleDelta(currentMousePosition); 

       myTransform.Angle += _deltaAngle; 
       _lastMousePosition = currentMousePosition; 
      } 
     } 

     private double GetAngleDelta(Point currentMousePosition) 
     { 
      double lastAngleDegrees = GetAngleDegrees(_lastMousePosition); 
      double newAngleDegrees = GetAngleDegrees(currentMousePosition); 

      if (Math.Sign(lastAngleDegrees) != Math.Sign(newAngleDegrees)) 
      { 
       lastAngleDegrees = newAngleDegrees; 
      } 
      double delta = newAngleDegrees - lastAngleDegrees; 
      return delta; 
     } 

     private double GetAngleDegrees(Point position) 
     { 
      return 180d/Math.PI * Math.Atan((position.Y - _centerOfTurnTable.Y)/(position.X - _centerOfTurnTable.X)); 
     } 
    } 
} 

的代码可以让你把转盘上并按下鼠标时的动画将开始允许转盘慢慢道来完全停止这给它一个很好的接触。

+0

感谢jakob的回复,试着让你的代码在angleAnimation.From = myTransform.Angle; angleAnimation.To = myTransform.Angle + _deltaAngle * 100; angleAnimation对于当前上下文不存在。 – Dharmang

+0

如果你看看我的XAML,你会看到angleAnimation是DoubleAnimation的名字。所以你必须在XAML中定义angleAnimation。 –