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();
}
Related
I'm trying to understand rules of WPF animation usying code from this site:
https://www.codeproject.com/Articles/23257/Beginner-s-WPF-Animation-Tutorial
Now I have a code to rotate element around x, y point:
RotateTransform rt = new RotateTransform();
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = 360;
da.Duration = new Duration(TimeSpan.FromSeconds(10));
da.RepeatBehavior = RepeatBehavior.Forever;
image.RenderTransformOrigin = new Point(x, y);
image.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
This is GIF image like "^", so I want to rotate it 90 deg BEFORE animation to rotate image like ">".
Tried RotateTransform rt = new RotateTransform(90); but no success.
Any suggestions?
Besides setting the Angle property of rt to 90, you should also change the From property of da to 90 to start animating from this value:
RotateTransform rt = new RotateTransform(90);
...
da.From = 90;
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)
});
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.
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.
I want to animate the rectangle x position from my code behind (as the x position is only determined at the run time).
I have got the following code:
KeySpline easeOut = new KeySpline(0, 1, 0.3, 1);
Storyboard sb = new Storyboard();
DoubleAnimationUsingKeyFrames da1 = new DoubleAnimationUsingKeyFrames();
SplineDoubleKeyFrame keyFrame1 = new SplineDoubleKeyFrame();
GeneralTransform generalTransform = rect4.TransformToVisual(this);
Point point = generalTransform.Transform(new Point());
keyFrame1.Value = point.X;
keyFrame1.KeySpline = easeOut;
da1.KeyFrames.Add(keyFrame1);
sb.Children.Add(da1);
Storyboard.SetTarget(da1, rect);
Storyboard.SetTargetProperty(da1, new PropertyPath("What is the path?"));
sb.Begin();
The thing I don't know is what to put for the PropertyPath?!
If you placed it on the Canvas use this
Storyboard.SetTargetProperty(da1, new PropertyPath("(Canvas.Left)"));
I would place the code in the Xaml in Window.Resorces, give it a name x:Name="da1" and ten just simply call it in code
sb.Begin();