Reputation: 6424
Let's say I want to animate rotate an UI element 45 degrees clockwise each time I press a button.
I have defined 8 visual states setting different RotateTransform
values between them. So, whenever I press the button I move to the next visual state:
VisualStateManager.GoToElementState(MyElement, "Position2", True)
etc.
The problem is that when moving from the VisualState 8 to VisualState 1, the element rotates backward. Seems logical, since it is moving from 315º to 0º.
The question is, how could achieve to goal of always moving forward when pressing the button?
Upvotes: 0
Views: 1312
Reputation: 946
I wrote a simple example for you in C#; VB should be very similar.
In your Main Window put a Rectangle
and a Button
. Then, set the RenderTransformOrigin
for the Rectangle
like in the Xaml sample.
In your code behind, declare your RotateTransform
and attach it to the Rectangle
as shown below. Everytime the Button
is pressed, the Angle
property of the RotateTransform
is increased of 45.
@EDIT: I like @Clemens formula to increase angle (it avoid overflows). I edited my answer.
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 Code-Behind:
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));
}
}
Upvotes: 1
Reputation: 128013
A basic example with animation could look like this:
<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>
with this Button Click handler:
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));
}
Upvotes: 3