PDA

Click to See Complete Forum and Search --> : [RESOLVED] Get object position during animation


Kezmondo
May 28th, 2009, 06:28 AM
Hi,

I have used Expression Blend to create a very simple animation where an image moves across the screen.

In code (c#), I have a DispatcherTimer which puts the image co-ordinates in a TextBlock with each tick using MyImage.GetValue(Canvas.LeftProperty).

My problem is that the co-ordinates being read never change, they are always the start position, even though I can see the image moving across the screen. If I don't use the storyboard, and instead move the image using MyImage.SetValue(Canvas.LeftProperty, newXpos) then the co-ordinates DO update correctly. It seems that the storyboard method does not update the Canvas.LeftProperty and Canvas.TopProperty values.

Am I missing something here? I want to be able to read the position of an object during an animation, for things like collision detection.

Thanks!


The XAML:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="AnimateTest.Page"
Width="640" Height="480">
<UserControl.Resources>
<Storyboard x:Name="MoveDuck">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Donald" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="608"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Donald" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:02" Value="448"/>
</DoubleAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" BeginTime="00:00:00">
<SplineColorKeyFrame KeyTime="00:00:02" Value="#FFF24D4D"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" BeginTime="00:00:00">
<SplineColorKeyFrame KeyTime="00:00:02" Value="#FF5F5D5D"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>

<Canvas x:Name="LayoutRoot">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF000000"/>
<GradientStop Color="#FFFFFFFF" Offset="1"/>
</LinearGradientBrush>
</Canvas.Background>
<Image Source="duck.JPG" Canvas.Top="50" Canvas.Left="50" RenderTransformOrigin="0.5,0.5" x:Name="Donald">
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Image.RenderTransform>
</Image>
<TextBlock Height="13" Width="65" Canvas.Left="20" Canvas.Top="378" Text="TextBlock" TextWrapping="Wrap" x:Name="txtPos"/>
</Canvas>
</UserControl>

chris128
May 28th, 2009, 04:33 PM
I would guess its because you are not actually animating that same property that you are checking. You are animating the TranslateTransfrom.X property but then checking the Canvas.Left property, which I dont think will change when your animation runs.

Of course I might be completely wrong :) let me have a quick play around and see if I can get something working, will post back soon.

chris128
May 28th, 2009, 04:49 PM
OK not quite sure if this is exactly what you wanted, but how about this in your tick event:

txtPos.Text = Donald.RenderTransform.Value.OffsetX.ToString & ", " & Donald.RenderTransform.Value.OffsetY.ToString


Note that you will have to remove the explicit setting of the Width property of your Textblock to be able to see the full string.
So instead of:
<TextBlock Height="13" Width="65" Canvas.Left="20" Canvas.Top="378" Text="TextBlock" TextWrapping="Wrap" x:Name="txtPos"/>
Just this:
<TextBlock Height="13" Canvas.Left="20" Canvas.Top="378" Text="TextBlock" TextWrapping="Wrap" x:Name="txtPos"/>

That what you wanted?

If thats not right then I think maybe you need to look at animating the Canvas.Left property etc instead of the Transform properties

Kezmondo
May 29th, 2009, 05:17 AM
Hi Chris128, cheers for the response!

You're right, I can change the TargetProperty in the XAML to Canvas.Left and Canvas.Top and it works - thanks!

The TargetProperty I had was what Blend created, so I'm interested to know if I can get your other suggested method working, but RenderTransform doesn't seem to have a Value property. Did you somehow have that code working?

chris128
May 29th, 2009, 05:30 AM
When you say RenderTransform doesnt have a value property, do you mean you cant find a value to display in your textblock for the coordinates?
That code I posted worked fine for me:
txtPos.Text = Donald.RenderTransform.Value.OffsetX.ToString & ", " & Donald.RenderTransform.Value.OffsetY.ToString

Another option might be to bind your textblock text to the relevant RenderTransform property of your image instead of using a timer to keep setting the text but im not that great with Binding yet im afraid so dont know how easy/possible this is

Kezmondo
May 29th, 2009, 05:46 AM
Sorry if I wasn't clear.
I meant that that line of code won't compile for me - I get the red squiggly line underneath "Value", with the error being:
'System.Windows.Media.Transform' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'System.Windows.Media.Transform' could be found (are you missing a using directive or an assembly reference?)

No big deal if I can't get it working, as the other method is fine, but I'm curious now as to why it isn't working for me! :confused:

chris128
May 29th, 2009, 05:55 AM
Really? and you just copied and pasted my exact code from above yeah?

What version of Visual Studio and .NET are you using? I'm on VS 2008 SP1 and .NET framework 3.5 SP1, might make a difference as I know they did change quite a few things in WPF in SP1

Kezmondo
May 29th, 2009, 06:17 AM
Yup, I have the same setup.

I've just noticed though that your code doesn't have parenthesis after ToString though - I added those in without really thinking about it as I'm using C#. Are you using VB.NET? Could that be the difference?

chris128
May 29th, 2009, 06:21 AM
Ah yeah I am using VB.NET so that is probably why its not exactly the same... but even so, it should be very similar

Kezmondo
May 29th, 2009, 06:39 AM
OK, great - well I'll have a dig around on that but you've definitely set me on the right track so thanks a lot for your time, much appreciated.

chris128
May 29th, 2009, 06:47 AM
no problem, glad I could help :)