I managed to build my storyboard behind code. I don't know how to add easing functions though. I am looking for something like:
DoubleAnimation FadelnTBAnimation = new DoubleAnimation();
FadelnTBAnimation.To = 0;
FadelnTBAnimation.BeginTime = TimeSpan.FromSeconds(0);
FadelnTBAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
FadelnTBAnimation.EasingFunction = EasingMode.EaseInOut; // this line gives an error
How could I apply easing functions with c#?
The reason why I find useful to build the storyboard with code Is because I am applying the same animation to several objects and sometimes it does not work when I bind the target property in XAML.
You need to create an instance of IEasingFunction (http://msdn.microsoft.com/en-us/library/system.windows.media.animation.ieasingfunction.aspx). There is a list of implementation classes at the bottom of that documentation entry, the most common of which is probably CubicEase or QuadraticEase.
There is a difference between the easing-function and the easing-mode.
Here is a short example for Win-8 (not WPF):
SineEase easingFunction = new SineEase();
easingFunction.EasingMode = EasingMode.EaseIn;
animation.EasingFunction = easingFunction;
A simple way to add the easing function in your case would be to just add it to the double animation.
FadelnTBAnimation.EasingFunction = new QuarticEase(); // for example
Related
I'm working with some Win2D effects and the Composition APIs in a UWP application and I'm having some issues with some of the available effects.
Here's a working method I use to blur some content behind a target element:
public static SpriteVisual GetAttachedBlur<T>(
[NotNull] this T element, float blur, int ms) where T : FrameworkElement
{
// Get the visual and the compositor
Visual visual = element.GetVisual();
Compositor compositor = visual.Compositor;
// Create the blur effect and the effect factory
GaussianBlurEffect blurEffect = new GaussianBlurEffect
{
Name = "Blur",
BlurAmount = blur,
BorderMode = EffectBorderMode.Hard,
Optimization = EffectOptimization.Balanced,
Source = new CompositionEffectSourceParameter("source")
};
CompositionEffectFactory effectFactory = compositor.CreateEffectFactory(blurEffect);
// Setup the rest of the effect
CompositionEffectBrush effectBrush = effectFactory.CreateBrush();
effectBrush.SetSourceParameter("source", compositor.CreateBackdropBrush());
// Assign the effect to a brush and display it
SpriteVisual sprite = compositor.CreateSpriteVisual();
sprite.Brush = effectBrush;
sprite.Size = new Vector2((float)element.ActualWidth, (float)element.ActualHeight);
ElementCompositionPreview.SetElementChildVisual(element, sprite);
return sprite;
}
Now, it works perfectly fine, but if I try to replace that GaussianBlurEffect effect with for example a DirectionalBlurEffect, I get an exception when I call the CreateEffectFactory method, saying that the input effect is not supported.
Now, I looked at the documentation and it seems that both those effects have the [NoComposition] attribution, so my first question is:
If both of the effects are unsupported ([NoComposition] attribute), why is it that the GaussianBlurEffect works fine and the DirectionalBlurEffect doesn't?
And the second question I have:
Is there another way to use/apply that DirectionalBlurEffect? There are quite a few Win2D effects that are marked as [NoComposition] that I would like to use, is there a workaround for that or do I just have to give up on them?
Thanks for your help!
Looks like the Win2D documentation wasn't updated, and right now only theGaussianBlurEffect is supported (see here)
I am creating a marquee animation for textblock. I have managed to do it with doubleanimation moving textblocks on canvas. But the problem is that text is flickering while moving each 0,5 seconds...
Here is the sample code I am using:
sb1 = new Storyboard();
DoubleAnimationUsingKeyFrames animationKeyFrames = new DoubleAnimationUsingKeyFrames();
var keyFrameStart = new EasingDoubleKeyFrame();
keyFrameStart.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
keyFrameStart.Value = TextWidth;
var keyFrameEnd = new EasingDoubleKeyFrame();
keyFrameEnd.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(10000));
keyFrameEnd.Value = -TextWidth;
animationKeyFrames.KeyFrames.Add(keyFrameStart);
animationKeyFrames.KeyFrames.Add(keyFrameEnd);
Storyboard.SetTargetProperty(animationKeyFrames, "(Canvas.Left)");
Storyboard.SetTarget(animationKeyFrames, textBlock1);
sb1.RepeatBehavior = RepeatBehavior.Forever;
sb1.Children.Add(animationKeyFrames);
sb1.Begin();
Does anyone knows any property, some double buffer or something like that to override this problem?
Actually, this issue was more related to device performance. I've checked your code, there's no problem in your code.
I tested your code on different configuration of the machines. The "flicker" phenomenon was different.
There's a workaround for you to alleviate this issue.
You could alleviate this issue by setting more large duration (e.g, keyFrameEnd.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(20000));).
I want to apply the following animation to my Window:
var ani = new DoubleAnimation(610, TimeSpan.FromSeconds(0.7));
BeginAnimation(Window.WidthProperty, ani);
The problem is that this animation works only the first time, the other times it has no effect.
Why? How can I fix this problem?
You have to specify the fromValue when you create the DoubleAnimation (as first argument).
var ani = new DoubleAnimation(ActualWidth, 610, TimeSpan.FromSeconds(0.7));
You can add the following code:
ani.RepeatBehavior = RepeatBehavior.Forever;
The animation will repeat itself once it is finished with RepeatBehavior set to Forever
I have a method that enables me to animate objects that have to do with a DoubleAnimation:
public void animDouble(DependencyObject target, DependencyProperty property, double to, TimeSpan duration, double? from = null, TimeSpan? beginTime = null, IEasingFunction e = null)
{
DoubleAnimation animation = new DoubleAnimation();
animation.To = to;
if (beginTime == null)
beginTime = TimeSpan.FromSeconds(0);
if (from != null)
animation.From = from;
animation.BeginTime = beginTime;
animation.Duration = duration;
if (e != null)
animation.EasingFunction = e;
//start animating
Storyboard.SetTarget(animation, target); // what object will be animated?
Storyboard.SetTargetProperty(animation, new PropertyPath(property)); // what property will be animated
Storyboard sb = new Storyboard();
sb.Children.Add(animation);
sb.Begin();
}
so if I have a boarder called br1 for example and I want to animate it's height I will call the method as:
animDouble(br1, FrameworkElement.HeightProperty, 150, TimeSpan.FromSeconds(5));
if I want to animate it's width I will do:
animDouble(br1, FrameworkElement.WidthProperty, 150, TimeSpan.FromSeconds(5));
I could also animate it's visibility with the same method.
for some reason I am not able to animate its x property in order to translate it along the x axis or y-axis. When I call the method as:
a.animDouble(br1, TranslateTransform.XProperty, 150, TimeSpan.FromSeconds(5));
the boarder does not animates. I don't get any errors aether.
Somehow i would have expected an error, well, anyway, the Border owns no such property, if you want to move your control you need to set the RenderTransform or LayoutTransform of the border to a TranslateTransform, then you can pass the transform itself into the method as target.
(The whole storyboard is awfully redundant as you only have one animation, you can just call BeginAnimation on the target itself)
It had to do with registering the name. I found a link in here
I don't know what the method registerName does but I guess I needed it. from the page I managed to get the basic animations. I where not able to animate two things at once SOMETIMES. if you are interested in seeing the method take a look tat this question. I think it is a prety nice class that will enable to create animations with code. copy the namespace to visual studio and copy the first example that I posted so that you can see how it works.
I'm working on a project that involves drawing curved paths between two objects. Currently, I've been writing some test code to play around with bezier curves and animation. The first test is simply to move the endpoint (Point3) from the origin object (a rectangle) to the destination object (another rectangle), in a straight line. here is the code which sets up the actual line:
connector = new Path();
connector.Stroke = Brushes.Red;
connector.StrokeThickness = 3;
PathGeometry connectorGeometry = new PathGeometry();
PathFigure connectorPoints = new PathFigure();
connectorCurve = new BezierSegment();
connectorPoints.StartPoint = new Point((double)_rect1.GetValue(Canvas.LeftProperty) + _rect1.Width / 2,
(double)_rect1.GetValue(Canvas.TopProperty) + _rect1.Height / 2);
connectorCurve.Point1 = connectorPoints.StartPoint;
connectorCurve.Point2 = connectorPoints.StartPoint;
connectorCurve.Point3 = connectorPoints.StartPoint;
connectorPoints.Segments.Add(connectorCurve);
connectorGeometry.Figures.Add(connectorPoints);
connector.Data = connectorGeometry;
MainCanvas.Children.Add(connector);
OK, so we now have a line collapsed to a point. Now, lets animate that line, going from _rect1 to _rect2 (the two objects at the endpoints):
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
board.Children.Add(pointAnim);
Works beautifully. However, when I try to do it with a storyboard, I get nothing. Here's the storyboarded code:
Storyboard board = new Storyboard();
PointAnimation pointAnim = new PointAnimation();
pointAnim.From = connectorCurve.Point3;
pointAnim.To = new Point((double)_rect2.GetValue(Canvas.LeftProperty) + _rect2.Width / 2,
(double)_rect2.GetValue(Canvas.TopProperty) + _rect2.Height / 2);
pointAnim.Duration = new Duration(TimeSpan.FromSeconds(5));
Storyboard.SetTarget(pointAnim, connectorCurve);
Storyboard.SetTargetProperty(pointAnim, new PropertyPath(BezierSegment.Point3Property));
board.Children.Add(pointAnim);
board.Begin();
Nothing moves. I'm suspecting there is a problem with what I'm feeding SetTarget or SetTargetProperty, but can't seem to figure it out. Does anyone have experience with animating line / bezier points in WPF?
I recreated your code, and this works:
Storyboard.SetTarget(pointAnim, connector);
Storyboard.SetTargetProperty(pointAnim, new PropertyPath("Data.Figures[0].Segments[0].Point3"));
That fixes it :) It seems that the target needs to be the control itself.
Going one step down, like this:
Storyboard.SetTarget(pointAnim, connectorGeometry);
Storyboard.SetTargetProperty(pointAnim, new PropertyPath("Figures[0].Segments[0].Point3"));
...gives the InvalidOperationException:
'[Unknown]' property value in the path 'Figures[0].Segments[0].Point3' points to immutable instance of 'System.Windows.Media.PathFigure'.
http://msdn.microsoft.com/en-us/library/system.windows.media.animation.storyboard(VS.95).aspx says:
Do not attempt to call Storyboard members (for example, Begin) within the constructor of the page. This will cause the animation to fail silently.
..in case you were doing that!
The sample on that page also sets the Duration property of the Storyboard object.
Finally a general tip, with these kinds of UI objects and weird XAML object graphs once you've got the basics working best to put it in a ResourceDictionary and use something like 'Resources["Name"] as Storyboard' to get it back later.
Hope that's helpful: looks like the missing Duration should do the trick.
edit: Looks like Duration is set to Automatic by default, I will see what else I can come up with, please bear with me.. :)