tags:

views:

1056

answers:

2

Why does the following animation flicker and act goofy on MouseLeave? If it can be repro-ed, I'll post a screencast.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
  <Canvas>
    <Path Fill="Blue" Margin="15,15,15,15">
      <Path.Data>
        <!-- Describes an ellipse. -->
        <EllipseGeometry x:Name="MyAnimatedEllipseGeometry" Center="200,100" RadiusX="15" RadiusY="15" />
      </Path.Data>
      <Path.Triggers>
        <EventTrigger RoutedEvent="UIElement.MouseEnter">
          <BeginStoryboard>
            <Storyboard Duration="0:0:.5">
              <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" 
                         Storyboard.TargetProperty="RadiusX"
                         From="15" To="100" />
              <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" 
                         Storyboard.TargetProperty="RadiusY"
                         From="15" To="100" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
        <EventTrigger RoutedEvent="UIElement.MouseLeave">
          <BeginStoryboard>
            <Storyboard Duration="0:0:.5">
              <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" 
                         Storyboard.TargetProperty="RadiusX"
                         From="100" To="15" />
              <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" 
                         Storyboard.TargetProperty="RadiusY"
                         From="100" To="15" />
            </Storyboard>
          </BeginStoryboard>
        </EventTrigger>
      </Path.Triggers>
    </Path>
  </Canvas>
</Page>
A: 

There's always the usual culprits of hardware. But I would suspect that it may have something to do with the time being taken to perform the animation. Try increasing the length of time the animation runs, or adjusting the size of the values you are moving between.

half a second is not much time to transition from 100 to 15 and vice versa, so you may just be running into not having a smooth enough transition, resulting in a choppy animation. Remember that time is key and that your target should be at least 30 fps for a smooth animation.

MasterMax1313
+2  A: 

The reason is that you specify a From on your DoubleAnimations.

If the radius is anything less than 100 when MouseLeave happens, the From property will make it jump up to 100 and likely cause a MouseEnter. Then, you have two competing animations and the mouse events go crazy as the ellipse radius flickers underneath the cursor.

The solution is to just omit the From properties, this will cause the animation to start from wherever the current radius is:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1">
    <Canvas>
        <Path Margin="15,15,15,15" Fill="Blue">
            <Path.Data>
                <!-- Describes an ellipse. -->
                <EllipseGeometry x:Name="MyAnimatedEllipseGeometry" Center="200,100" RadiusX="15" RadiusY="15"/>
            </Path.Data>
            <Path.Triggers>
                <EventTrigger RoutedEvent="UIElement.MouseEnter">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" Duration="0:0:.5" Storyboard.TargetProperty="RadiusX" To="100"/>
                            <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" Duration="0:0:.5" Storyboard.TargetProperty="RadiusY" To="100"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
                <EventTrigger RoutedEvent="UIElement.MouseLeave">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" Duration="0:0:.5" Storyboard.TargetProperty="RadiusX" To="15"/>
                            <DoubleAnimation Storyboard.TargetName="MyAnimatedEllipseGeometry" Duration="0:0:.5" Storyboard.TargetProperty="RadiusY" To="15"/>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Path.Triggers>
        </Path>
    </Canvas>
</Page>

On an unrelated note, when you set Storyboard.Duration, it won't speed up your child animations, it will just end the Storyboard prematurely. You really want to set Duration on your child DoubleAnimations - I've modified the XAML above to do this.

Robert Macnee
Thanks Robert. That worked very well. Can I ask what the difference is, then, between setting the Storyboard Duration and the DoubleAnimation duration?
Ryan Cromwell
or more appropriately, when should Storyboard.Duration be set versus DoubleAnimation.Duration
Ryan Cromwell
I think it's mostly when the entire Storyboard has RepeatBehavior set, you can reset it at a particular time interval using Duration.
Robert Macnee