Reputation: 1241
I have a pretty simple requirement (I thought), a window that shows an image at a certain start point & size and moves/zooms it to a certain end point and size. This is not the typical Image Viewer requirement for pan&zoom. More like a sprite animation.
I tried out a couple of ways, e.g. a ThicknessAnimation to alter the Margin to move the image, but the performance was just not good enough. I have to admit I don't have much experience with WPF, though.
Below is my last version which is ok performance-wise. The image element goes over the whole window and the size and position are set by ScaleTransform and TranslateTransform. It works well (and shows relatively smooth movement) if the end position is on the lower right of the start position, e.g. from 0,0 to 800,600. If it's the other way around, though, the image makes kind of a slingshot movement to the lower right corner of the window, leaves the window and then finally comes back to stop at its end position.
I would appreciate an explanation for this behavior as well as a solution. And if you know a different way that works and is similar or better performance-wise, I'd like to hear that too.
<Window x:Class="ViewBoxText.AnimatedImageWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="AnimatedImageWindow"
WindowStyle="None"
SizeToContent="WidthAndHeight"
AllowsTransparency="True"
ShowInTaskbar="False"
Left="0"
Top="0"
Height="{Binding TotalHeight}"
Width="{Binding TotalWidth}"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<Image x:Name="image" HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding TotalWidth}" Height="{Binding TotalHeight}" Stretch="Uniform">
<Image.RenderTransform>
<TransformGroup>
<TranslateTransform X="{Binding HorizontalStart}" Y="{Binding VerticalStart}" />
<ScaleTransform />
</TransformGroup>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<BeginStoryboard>
<Storyboard Completed="OnStoryBoardCompleted">
<DoubleAnimation Storyboard.TargetName="image"
Storyboard.TargetProperty="(Image.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)"
From="{Binding ScaleStart}" To="{Binding ScaleEnd}" DesiredFrameRate="30"
Duration="0:0:2" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetName="image"
Storyboard.TargetProperty="(Image.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleY)"
From="{Binding ScaleStart}" To="{Binding ScaleEnd}" DesiredFrameRate="30"
Duration="0:0:2" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetName="image"
Storyboard.TargetProperty="(Image.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)"
By="{Binding HorizontalOffset}"
Duration="0:0:2" BeginTime="0:0:0" />
<DoubleAnimation Storyboard.TargetName="image"
Storyboard.TargetProperty="(Image.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.Y)"
From="{Binding VerticalStart}" To="{Binding VerticalEnd}"
Duration="0:0:2" BeginTime="0:0:0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
</Grid>
Upvotes: 0
Views: 120
Reputation: 321
The problem is the scale is scaling about 0,0. I believe you want to scale about the point you are interested in, which may or may not be you Vertical/Horizontal end point.
Normally, you would translate so that the centre is on the origin, scale, then put the whole thing back.
e.g. to scale by X about point A,B
Fortunately the scale has a couple of centre properties that make this easier.
So try adjusting the CenterX
and CenterY
properties of the ScaleTransform
.
Upvotes: 1