WPF. Animation of window transparency - c#

I need a smooth animation of window transparency. I added this code to the "LOADED" event of the window.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100.0;
myDoubleAnimation.To = 0.1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
myStoryboard.Begin(this);
There is a sharp jump of transparency. Animation is missing. Where there has been a mistake?

Opacity is a relative value in the range 0 .. 1. Use
myDoubleAnimation.From = 1.0;
or don't set it at all.
Instead of using a Storyboard, you may also just write
BeginAnimation(OpacityProperty, new DoubleAnimation
{
To = 0.1,
Duration = TimeSpan.FromSeconds(1)
});

Related

Specifying PropertyPath for a MapIcon Latitude value in UWP Bing Maps

I am trying to animate the location of a MapIcon in the UWP version of Bing Maps. I am having problems specifying the PropertyPath for the Latitude component (a double value) of the GeoPoint used as the center value for the icon:
MapIcon mapIcon1 = new MapIcon();
mapIcon1.Location = myMap.Center;
mapIcon1.NormalizedAnchorPoint = new Point(0.5, 1.0);
mapIcon1.Title = "My Friend";
mapIcon1.Image = mapIconStreamReference;
mapIcon1.ZIndex = 0;
myMap.MapElements.Add(mapIcon1);
double centerLatitude = myMap.Center.Position.Latitude;
double centerLongitude = myMap.Center.Position.Longitude;
Storyboard storyboard = new Storyboard();
DoubleAnimation animation = new DoubleAnimation();
animation.From = centerLatitude;
animation.To = centerLatitude + 100f;
animation.Duration = new Duration(new TimeSpan(0, 0, 0, 5));
animation.EnableDependentAnimation = true;
storyboard.Children.Add(animation);
//Storyboard.SetTargetProperty(animation, "(MapIcon.Location)(Geopoint.Position)(BasicGeoposition.Latitude)");
//Storyboard.SetTargetProperty(animation, "(MapIcon.Location)(MapControl.Center)(Geopoint.Position)(BasicGeoposition.Latitude)");
//Storyboard.SetTargetProperty(animation, "(MapIcon.Location)(BasicGeoposition.Latitude)");
//Storyboard.SetTargetProperty(animation, "(MapIcon.Location.Latitude)");
Storyboard.SetTarget(storyboard, mapIcon1);
storyboard.Begin();
None of the commented out statements work; they all result in the "Cannot resolve TargetProperty on specified object" error. I was particularly hopeful for the first attempt "(MapIcon.Location)(Geopoint.Position)(BasicGeoposition.Latitude)", but no luck.
(I am able to animate the Color attribute of a MapIcon successfully.)
Storyboard.SetTargetProperty targets the dependency property where the animation applies. So, what you want to apply animation to 'Latitude'is impossible.
You would have to make it by yourself. For example, using the DispatcherTimer.

Calling a storyboard Asynchronously

I have a rectangle in my window. if i move the mouse towards the right corner of the window, i use MouseMove to detect the mouse position and fire an animation called AnimateRight() which translate the rectangle to the right horizontally.
However, during this animation, if the mouse moves to the center of the window, i want the reectangle to stop translating and just stay where it stopped.
How do i do this?
private void AnimateRight()
{
DoubleAnimation da = new DoubleAnimation();
da.Duration = TimeSpan.FromSeconds(2);
da.From = 0;
da.To = 200;
TransformGroup transGroup = new TransformGroup();
transGroup.Children.Add(new TranslateTransform());
gr.RenderTransform = transGroup;
Storyboard.SetTarget(da, gr);
Storyboard.SetTargetProperty(da, new PropertyPath("RenderTransform.Children[0].X"));
sb.AccelerationRatio = 0.8;
sb.Children.Add(da);
sb.Begin();
}

immediate translate animation in WPF in code behind

I want to make an animation that involves translating a circle _fixedCircle on x-axis from starting point (5,0) to end point (200,0) and then from (200,0) to (5,0) In a forever loop but not following a path, but "jumping", in other words, immediate translation from point to point.
To animate this circle doing a linear interpolation there is this:
Storyboard sb = new Storyboard();
DoubleAnimation anim = new DoubleAnimation();
sb.Children.Add(anim);
Storyboard.SetTarget(anim, _fixedCircle);
Storyboard.SetTargetProperty(anim, new PropertyPath("(Canvas.Left)"));
anim.From = 5;
anim.To = 200;
anim.RepeatBehavior = RepeatBehavior.Forever;
anim.AutoReverse = true;
MYCANVAS.Resources.Add("CIRCLE_ID", sb);
Duration duration = new Duration(TimeSpan.FromSeconds(2));
anim.Duration = duration;
anim.Begin();
But how to create "jumping" effect?
Try using a DoubleAnimationUsingKeyFrames, adding a DiscreteDoubleKeyFrame for each jump you want, e.g. (calculation of jump values has a lot of room for improvement ;)):
DoubleAnimationUsingKeyFrames anim = new DoubleAnimationUsingKeyFrames();
int maxNrOfJumps = 10;
for (int jump = 0; jump < maxNrOfJumps; jump++) {
double value = ((200 - 5) / maxNrOfJumps) * jump;
anim.KeyFrames.Add(new DiscreteDoubleKeyFrame(value, KeyTime.FromPercent(jump / (double)maxNrOfJumps)));
}
Discrete key frames like DiscreteDoubleKeyFrame create sudden "jumps" between values (no Interpolation). In other words, the animated property does not change until the key frame's key time is reached at which point the animated property goes suddenly to the target value.
https://msdn.microsoft.com/en-us/library/system.windows.media.animation.discretedoublekeyframe%28v=vs.110%29.aspx
Edit:
Running it can be done without a Storyboard, this is how I tested it:
_fixedCircle.BeginAnimation(Canvas.LeftProperty, anim);
Edit2:
You'd still need to set these properties to keep the animation running:
anim.RepeatBehavior = RepeatBehavior.Forever;
anim.AutoReverse = true;
Also, don't forget to set the Duration...
immediate translation from point to point
Are you looking for a kind of instant teleportation from the first point to the last one ?
If so :
Storyboard sb = new Storyboard();
DoubleAnimation anim = new DoubleAnimation();
sb.Children.Add(anim);
Storyboard.SetTarget(anim, _fixedCircle);
Storyboard.SetTargetProperty(anim, new PropertyPath("(Canvas.Left)"));
anim.From = 5;
anim.To = 200;
// anim.RepeatBehavior = RepeatBehavior.Forever; // nope
anim.AutoReverse = false; // well
MYCANVAS.Resources.Add("CIRCLE_ID", sb);
Duration duration = new Duration(TimeSpan.FromSeconds(0)); // here we go
anim.Duration = duration;
anim.Begin();
Why not use skipToFill property?
just add it to your storyboard.

Simultaneous Animation For Same Element in WPF

I have an image in a canvas. What I want to do is code an animation which both rotates the image 90 degrees and move the image from the top left corner of canvas to the bottom right corner at the same time to create an action looks like projectile motion. However, I could only manage to do one part of the animation so far.
DoubleAnimation rotateAnimation = new DoubleAnimation(0, 90, new Duration(TimeSpan.FromSeconds(1)));
RotateTransform rt = new RotateTransform();
image.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
TranslateTransform tt = new TranslateTransform();
image.RenderTransform = tt;
DoubleAnimation moveXAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(1));
DoubleAnimation moveYAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(1));
tt.BeginAnimation(TranslateTransform.XProperty, moveXAnimation);
tt.BeginAnimation(TranslateTransform.YProperty, moveYAnimation);
These two blocks works very well separately, but do not work together(consequently). The latter one works only. Anyone can tell me why?
UPDATE (Complete answer of Clemens):
RotateTransform rt = new RotateTransform();
DoubleAnimation rotateAnimation = new DoubleAnimation(0, 90, new Duration(TimeSpan.FromSeconds(5)));
TranslateTransform tt = new TranslateTransform();
DoubleAnimation moveXAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(5));
DoubleAnimation moveYAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(5));
TransformGroup transform = new TransformGroup();
transform.Children.Add(rt);
transform.Children.Add(tt);
image.RenderTransformOrigin = new Point(0.5, 0.5);
image.RenderTransform = transform;
rt.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
tt.BeginAnimation(TranslateTransform.XProperty, moveXAnimation);
tt.BeginAnimation(TranslateTransform.YProperty, moveYAnimation);
Put both transforms in a TransformGroup, and assign that to the image's RenderTransform:
var rt = new RotateTransform();
var tt = new TranslateTransform();
var transform = new TransformGroup();
transform.Children.Add(rt);
transform.Children.Add(tt);
image.RenderTransform = transform;
// run animations
You may also want to take a look at how to use a Path Animation for a more realistic look. The projectile might follow a parabolic curve.

How to scale image from center? Windows 8.1 C#

How to scale dynamic image control from the center programmatically in c# for Windows 8.1. This code scales image from left upper corner:
Image img=new Image(){Width=150,Height=150};
img.RenderTransform = new CompositeTransform();
Storyboard story = new Storyboard();
DoubleAnimation xAnim = new DoubleAnimation();
DoubleAnimation yAnim = new DoubleAnimation();
xAnim.From = 0;
yAnim.From = 0;
xAnim.To = 1;
yAnim.To = 0.5;
xAnim.Duration = TimeSpan.FromMilliseconds(1000);
yAnim.Duration = TimeSpan.FromMilliseconds(1500);
story.Children.Add(xAnim);
story.Children.Add(yAnim);
Storyboard.SetTarget(xAnim, img);
Storyboard.SetTarget(yAnim, img);
Storyboard.SetTargetProperty(xAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)");
Storyboard.SetTargetProperty(yAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)");
story.Begin();
You want
img.RenderTransformOrigin = new Point(0.5, 0.5);
That will mean that all of your transforms will be relative to the center of your image. See the RenderTransformOrigin documentation for more details.

Categories