以 45 度为步长旋转元素,始终向前

Rotate element in steps of 45 degrees, always forward

假设我想在每次按下按钮时将 UI 元素顺时针旋转 45 度。

我定义了 8 种视觉状态,在它们之间设置了不同的 RotateTransform 值。因此,每当我按下按钮时,我都会移动到下一个视觉状态:

VisualStateManager.GoToElementState(MyElement, "Position2", True)

等等

问题是当从 VisualState 8 移动到 VisualState 1 时,元素向后旋转。似乎合乎逻辑,因为它从 315º 移动到 0º。

问题是,怎样才能实现按下按钮就一直往前走呢?

我用 C# 为你写了一个简单的例子; VB应该很相似。

在您的 Main Window 中放置一个 Rectangle 和一个 Button。然后,像 Xaml 示例中那样为 Rectangle 设置 RenderTransformOrigin

在您后面的代码中,声明您的 RotateTransform 并将其附加到 Rectangle,如下所示。每按一次ButtonRotateTransformAngle属性增加45。

@编辑: 我喜欢@Clemens 公式来增加角度(避免溢出)。我编辑了我的答案。

XAML:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    <Rectangle x:Name="myRect" RenderTransformOrigin=".5,.5" Grid.Row="0" Width="100" Height="100" Fill="LightBlue" >

    </Rectangle>
    <Button Grid.Row="1" Width="100" Height="50" Margin="10" Click="Button_Click">Rotate</Button>
</Grid>

Window 代码隐藏:

public partial class MainWindow : Window
{
    private TransformGroup _transformGroup;
    private RotateTransform _rotateTrsf;

    public MainWindow()
    {
        InitializeComponent();
        _transformGroup = new TransformGroup();
        _rotateTrsf = new RotateTransform();
        _transformGroup.Children.Add(_rotateTrsf);

        SetupAnimation();

        myRect.RenderTransform = _transformGroup;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        _rotateAnimation.To = Math.Floor(_rotateTrsf.Angle / 45 + 1) * 45;            
        _rotateTrsf.BeginAnimation(RotateTransform.AngleProperty, _rotateAnimation);
        _rotateAnimation.From = _rotateAnimation.To;            
    }

    private void SetupAnimation()
    {           
        _rotateAnimation = new DoubleAnimation();
        _rotateAnimation.From = 0.0;
        _rotateAnimation.To = 45;
        _rotateAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.3));
    }
}

动画的基本示例如下所示:

<Grid>
    <Rectangle Fill="Black" Width="100" Height="100" RenderTransformOrigin=".5,.5">
        <Rectangle.RenderTransform>
            <RotateTransform x:Name="rotation"/>
        </Rectangle.RenderTransform>
    </Rectangle>
    <Button Content="Rotate" VerticalAlignment="Bottom" Click="Button_Click"/>
</Grid>

使用此按钮单击处理程序:

private void Button_Click(object sender, RoutedEventArgs e)
{
    const double rotSpeed = 180; // °/s, i.e. 45° in 0.25 seconds

    var newAngle = Math.Floor(rotation.Angle / 45 + 1) * 45; // integer multiple of 45°
    var duration = TimeSpan.FromSeconds((newAngle - rotation.Angle) / rotSpeed);

    rotation.BeginAnimation(
        RotateTransform.AngleProperty, new DoubleAnimation(newAngle, duration));
}