c# uwp animation make text flicker - c#

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));).

Related

Correct Property Path for Width-Animation in Windows Store Apps (Windows 8.1 and above)

I don't understand why my Canvas.Left and Canvas.Top Animations are running, but my Width and Height Animations are not.
Here is one example of perfectly working code:
DoubleAnimation doubleAnimationCanvasLeft = new DoubleAnimation();
doubleAnimationCanvasLeft.From = Canvas.GetLeft(aDiceToBeChecked.myGrid);
doubleAnimationCanvasLeft.To = Canvas.GetLeft(aDiceToBeChecked.myGrid) - 102;
doubleAnimationCanvasLeft.Duration = TimeSpan.FromMilliseconds(myTimespan);
doubleAnimationCanvasLeft.FillBehavior = FillBehavior.HoldEnd;
Storyboard storyboardCanvasLeft = new Storyboard();
storyboardCanvasLeft.Children.Add(doubleAnimationCanvasLeft);
Storyboard.SetTarget(storyboardCanvasLeft, aDiceToBeChecked.myGrid);
Storyboard.SetTargetProperty(storyboardCanvasLeft, "(Canvas.Left)");
storyboardCanvasLeft.Begin();
And the same for width does not work:
DoubleAnimation doubleAnimationGridWidth = new DoubleAnimation();
doubleAnimationGridWidth.From = 200.0;
doubleAnimationGridWidth.To = 304.0;
doubleAnimationGridWidth.Duration = TimeSpan.FromMilliseconds(myTimespan);
doubleAnimationGridWidth.FillBehavior = FillBehavior.HoldEnd;
Storyboard storyboardGridWidth = new Storyboard();
storyboardGridWidth.Children.Add(doubleAnimationGridWidth);
Storyboard.SetTarget(storyboardGridWidth, aDiceToBeChecked.myGrid);
Storyboard.SetTargetProperty(storyboardGridWidth, "(Width)");
storyboardGridWidth.Begin();
It does not work with Width, (Width), (UIElement.Width), (Grid.Width) and I am really not sure how to get the correct Property Path of if the Property Path is even the problem!? Could you help me?
I am using Net Version 4.5.1 and Visual Studio Express 2013 and developing for Windows 8.1 and Windows 10.
I found the missing piece:
doubleAnimationGridWidth.EnableDependentAnimation = true;
If someone else is reading this: This means this animation is using more ressources of the UI Thread. There is more information on the Microsoft-Website.
Still, if someone could tell me how to build and or debug these property paths...

Repeat DoubleAnimation

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

How to maximize window in XNA

This SHOULD be a very simple question but after lots of searching there seems to be no working example anywhere.
I just want my XNA window to start off maximized.
I know how to set the width and height of the window, but that's not quite the same.
I also need to do this without going full screen. I just want a normal maximized window.
Set the IsFullScreen property of the graphics device manager to true.
http://msdn.microsoft.com/en-us/library/bb195024(v=xnagamestudio.10).aspx
//from the above msdn sample
graphics = new GraphicsDeviceManager( this );
content = new ContentManager( Services );
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.PreferMultiSampling = false;
graphics.IsFullScreen = true;
http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphicsdevicemanager.isfullscreen(v=xnagamestudio.10).aspx
#Cyral has the closest answer so far, but it's still not quite what you want. To maximize a Windows Form, you use the WindowState property:
var form = (Form)Form.FromHandle(Window.Handle);
form.WindowState = FormWindowState.Maximized;
You can add a reference to System.Windows.Forms and System.Drawing (However, You will need to type the namespaces out, Because of ambiguities)
Use the following code after base.Initialize
Form form = (Form)Form.FromHandle(Window.Handle);
form.Location = Point(0, 0);
form.Size = Screen.PrimaryScreen.WorkingArea.Size;
Others have covered the step of maximizing automatically, but to enable the actual maximize button so the user can do it when desired, do this in the Game constructor:
Window.AllowUserResizing = true;
Depending on how you want the game to behave when resizing begins and ends, perhaps pause the game, you may need to handle some of these events.
Form form = (Form)Form.FromHandle(Window.Handle);
form.ResizeBegin += new EventHandler(form_ResizeBegin);
form.ResizeEnd += new EventHandler(form_ResizeEnd);
form.LocationChanged += new EventHandler(form_LocationChanged);
_graphics = new GraphicsDeviceManager(this);
DisplayMode displayMode = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode;
this._graphics.PreferredBackBufferFormat = displayMode.Format;
this._graphics.PreferredBackBufferWidth = (int)(displayMode.Width);
this._graphics.PreferredBackBufferHeight = (int)(displayMode.Height);
Sort of works for me but not quite, you'll understand once you try. I mean, it's not perfect and I'm sure there's a better way but for prototyping this should work - or maybe with some tweaking you could get what you need.

Apply easing function to animation behind code

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

WPF Animation - Animating Bezier curve points

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.. :)

Categories

Resources