The storyBoard_Completed event is invoked in a delay of about half a second after the visual animation had finished.
Would be glad for some more eyes to check out my Storyboard XAML:
<Storyboard x:Key="blaAnimation" Completed="storyBoard_Completed">
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla1" Storyboard.TargetProperty="Offset" Completed="bla_Completed">
<DiscreteDoubleKeyFrame KeyTime="0:0:0" x:Name="bla1StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2" Value="-20" x:Name="bla1Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla2" Storyboard.TargetProperty="Offset" BeginTime="0:0:0.1" Completed="bla2_Completed">
<DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.1" x:Name="bla2StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1.1">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.1" Value="-20" x:Name="bla2Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="bla3" Storyboard.TargetProperty="Offset" BeginTime="0:0:0.18" Completed="bla3_Completed">
<DiscreteDoubleKeyFrame Value="0" KeyTime="0:0:0.2" x:Name="bla3StartKeyFrame"/>
<EasingDoubleKeyFrame Value="-10.2" KeyTime="0:0:1.2">
<EasingDoubleKeyFrame.EasingFunction>
<PowerEase EasingMode="EaseIn"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="0:0:2.2" Value="-20" x:Name="bla3Animation">
<EasingDoubleKeyFrame.EasingFunction>
<ElasticEase EasingMode="EaseOut" Oscillations="5" Springiness="20"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
Thanks in advance,
--Ran.
When in doubt - Blend it
Following on from comment trail (above), the end result is "If you have access to it (or can afford it), always use Expression Blend for creating animation storyboards".
Blend is the best way to learn animation which can get very complex quite easily. Blend also optimises certainly animations automatically for you.
As you know there is no support at all in VS 2010 for authoring animation, except with XAML, and that is error prone. It is also very hard to visualise multiple animations in your head with only text to go by :)
Related
I am trying to play a bit with the badged control from Mahapps. Is it possible to change the size of the badge (not just the color/value/etc..)
Finally I am trying to do some sort of bigger pulse effect when the badge value changed, I tried the following for the color but it didn't work:
<Controls:Badged.Triggers>
<EventTrigger RoutedEvent="Controls:Badged.BadgeChanged">
<EventTrigger.EnterActions>
<BeginStoryboard Name="AnimateVisibilityChanged">
<Storyboard>
<ColorAnimation Duration="0:0:0.5"
From="#FFEE4709"
To="Green"
BeginTime="0:0:0"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
<ColorAnimation Duration="0:0:0.5"
From="Green"
To="Transparent"
AutoReverse="True"
BeginTime="0:0:2"
RepeatBehavior="0:0:2.5"
Storyboard.TargetProperty="(Controls:Badged.BadgeBackground).(SolidColorBrush.Color)">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.EnterActions>
<EventTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="AnimateVisibilityChanged" />
</EventTrigger.ExitActions>
</EventTrigger>
</Controls:Badged.Triggers>
The next step if this would work is to also increase the size more than it's already increasing
It looks like I will answer to my question:
the animation didn't work because I used EnterActions instead of simply Actions (EventTrigger.Actions)
To change the size of the badge when the value changes I had to use BadgeChangedStoryboard property and replace with my own:
<SineEase x:Key="BadgeEase"
EasingMode="EaseOut" />
<Storyboard x:Key="BadgeChangedStoryboard">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="0"
Value="2.3" />
<EasingDoubleKeyFrame EasingFunction="{StaticResource BadgeEase}"
KeyTime="0:0:0.3"
Value="1" />
</DoubleAnimationUsingKeyFrames>
</Storyboard>
To change the size change both the easing double key frame Value
Is this just me or what? RepeatBehavior doesn't seem work for animations in Expression Blend 4. I have the following animation:
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)"
Storyboard.TargetName="WaitDoc" RepeatBehavior="0:0:2">
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="180"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="360"/>
</DoubleAnimationUsingKeyFrames>
I expect this animation to run for 2 seconds, but instead it runs only once when I click Play button in Objects and Timeline pane. I have tried values like 5x too, getting the same behavior.
I don't want to run the entire project to test every minute change. The Play button SHOULD play it as defined. Am I missing something here?
EDIT: In addition, I just discovered that Blend also doesn't show any respect for BeginTime attribute.
Try this :
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children) [2].(RotateTransform.Angle)"
Storyboard.TargetName="WaitDoc" Duration="0:0:2" RepeatBehavior="Forever">
<EasingDoubleKeyFrame KeyTime="0:0:1.0" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.1" Value="180"/>
<EasingDoubleKeyFrame KeyTime="0:0:1.2" Value="360"/>
</DoubleAnimationUsingKeyFrames>
I Have Animation In My ResourceDictionary But I Want Call Animation In My C# Code.
This ResourceDictionary Add To My Resources App
Example:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<BeginStoryboard x:Key="PuzzleFall">
<Storyboard Storyboard.TargetName="RenderT" Storyboard.TargetProperty="X">
<DoubleAnimationUsingKeyFrames Duration="0:0:3" BeginTime="0:0:0">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,0.95 0" KeyTime="0:0:3"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:3.06" Duration="0:0:1.5">
<SplineDoubleKeyFrame Value="50" KeySpline="0 1,0 1" KeyTime="0:0:1.5"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:3.08" Duration="0:0:1">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,1 0" KeyTime="0:0:1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:4.1" Duration="0:0:1">
<SplineDoubleKeyFrame Value="15" KeySpline="0 1,0 1" KeyTime="0:0:1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="0:0:4.15" Duration="0:0:0.5">
<SplineDoubleKeyFrame Value="0" KeySpline="1 0,1 0" KeyTime="0:0:0.5"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</ResourceDictionary>
Then I Want Run This Animation In C# Code.
Thanks.
You probably should not put the Storyboard which is the main component inside a BeginStoryboard especially if you use code. EIther way. you can get the Storyboard using FindResource.
In your current setup something like this:
var beginsb = (BeginStoryboard)FindResource("PuzzleFall");
var sb = beginsb.Storyboard;
sb.Begin();
When button1 is clicked I want this sequence
RectangeA becomes visible
RectangeA opacity changed from 0 to 75% over lets say 3 seconds
ControlB becomes visible.
Steps 1 and 3 are easy with imperative code, but I'm assuming I need to learn how to use story boards to do step 2.
Here is the storyboard that describes your sequence:
<Storyboard x:Key="animate">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="button1" Storyboard.TargetProperty="(UIElement.Opacity)">
<LinearDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<LinearDoubleKeyFrame KeyTime="00:00:03" Value="0.75"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="button1" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visibility.Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="control" Storyboard.TargetProperty="(UIElement.Visibility)">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="Visibility.Visible"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
You can trigger it in xaml through EventTrigger or in code through TryFindResource().
Here is the link on Animation Overview MSDN Article and you can find there answers on your questions on many WPF animations topics.
I have a problem with my Silverlight animation that I can't seem to fix. The problem seems to be well established, but the techniques used to solve it don't seem to work in my case.
Here is the storyboard code that I am using to animate a grid called "underGrid". underGrid is a base grid which I am applying a scale and location offset to in response to mouse input from the user, so that they can scale and move the grid in real time. The ResetGrid storyboard below simply animates from the current scale and location values back to scale {1, 1} and location {0, 0}, resetting the view for the user. I wanted to be able to apply this animation whenever the user clicks a reset button but it freezes the Scale and Translation transforms once it has run once (as discussed here: http://msdn.microsoft.com/en-us/library/aa970493.aspx). Which means that when the user then uses the mouse to move the grid, it doesn't move. I've tried everything I can think of to stop the animation from having an affect on the dependency properties. I've tried hooking the Completed event and trying (amongst other things), stopping the animation, seeking the animation to 0, looping through the ResetGrid Children and using StoryBoard.SetTarget(). I've also tried setting the FillBehavior.. No matter what I do nothing seems to make a difference, the Scale and Translation are always tapped and cannot be set again in user-code.
Can anyone suggest anything I can try that I've not listed above (drastic or otherwise :) )? All I want is the animation to have completely stopped and detached itself on Complete.
Storyboard XAML:
<Storyboard x:Name="ResetGrid">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
will ResetGrid.stop() work?
I used it in my applications and the animation was cut off straight away.
animation.stop will stop and reset, while animation.pause will just stop on where timeline it hit
if not u can put another animation of duration 0,
call this animation to place back the property
I've run into this issue before too... check out this thread on Silverlight.Net which I think you might find helpful:
http://forums.silverlight.net/forums/t/68888.aspx