WPF / SL animation time scaling

I looked for this thing because I thought it was very important and mysterious, but I did not find anything about this. I am thinking about time scaling in WPF and Silverlight animations.

Suppose we have a DoubleAnimation that lasts 4 seconds and animates a property from 0 to 100. This is an auto-reverse, or complementary animation that changes its effects, it doesn’t matter. Let's say that the event that triggers this animation is a simple MouseOver.

Here's the problem: I hover over an element. The property gains from 0 to 100 in 4 s. I move my cursor for 1 s, the property gets from 100 to 75, and then I go back. Now the property takes a form from 75 to 100 in 4 s. It’s obvious to the user that the animation works 4 times slower. Is there any way to scale animation time? If I wanted this animation to work from 75 to 100 in 1 s, how would I do it? I myself think, perhaps, about a converter that will take four parameters (absolute start and end, actual start and time for the entire interval), and then spit out the right time. Is there a more elegant way?

I noticed that this is not a problem at all when the animation is fast. A person does not really observe the difference in speed when the animation runs in 0.2 s or 0.1 s, and perhaps all animations should be as fast as possible so as not to worsen the experience. But please consider this question theoretically (therefore, do not use a sample code). I'm just wondering if there is a suitable way to scale the animation time.

If there is an answer to my question somewhere on the Internet, please just direct me there.

Paweł

PS Do not mind my English, I'm not a native speaker;)

+4
source share
3 answers

I did some more research. It seems that the only good way to scale the animation time is to use MultiConverter, which accepts boundary values ​​(e.g. 0 and 100 from my previous example), the current value of the animated property, and the runtime for full animation (e.g. 4s in my example). Then it must calculate what percentage of the animation should be performed (therefore, if the current value is 75 and the full range is 0-100, then 25% of the animation remains), and the return value should be the above-mentioned advantage of the original time period (25% of 4 s is 1 s). This may not be the most elegant way to achieve a goal, but it seems like it should work.

0
source

I know this is not the answer to your exact question, but one way to approach this is to capture MouseEnter and MouseLeave , check the current state of the animation, and pause or resume it:

 <UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="AnimationTest.MainPage" Width="640" Height="480"> <UserControl.Resources> <Storyboard x:Name="Rotate" AutoReverse="True"> <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="textBlock"> <EasingDoubleKeyFrame KeyTime="0" Value="0"/> <EasingDoubleKeyFrame KeyTime="0:0:4" Value="100"/> </DoubleAnimationUsingKeyFrames> </Storyboard> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock x:Name="textBlock" Margin="197,216,200,215" TextWrapping="Wrap" Text="My Funky Text" FontSize="32" RenderTransformOrigin="0.5,0.5" MouseEnter="textBlock_MouseEnter" MouseLeave="textBlock_MouseLeave"> <TextBlock.RenderTransform> <CompositeTransform/> </TextBlock.RenderTransform> </TextBlock> </Grid> </UserControl> 

the code:

 private void textBlock_MouseEnter(object sender, MouseEventArgs e) { var state = Rotate.GetCurrentState(); if (state == ClockState.Stopped || state == ClockState.Filling) { Rotate.Begin(); } else Rotate.Resume(); } private void textBlock_MouseLeave(object sender, MouseEventArgs e) { Rotate.Pause(); } 
0
source

I had the same problem so that the animation behaves linearly in the mod that you describe. I could not find a solution using WPF triggers in XAML without having to write code.

Then I started using VisualStateManager instead of triggers (which is supported in WPF 4 and Silverlight). All animations behaved perfectly, as you expected from them!

I would recommend Expression Blend 4 for using VisualStateManager, since it takes just a few seconds to set up an object with different states using the user interface.

0
source

Source: https://habr.com/ru/post/1416071/


All Articles