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.
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)
});
So I have 2 Image's I want the first Image to move towards the other Image I have both X,Y coordinates, how should this be done if I want it moving pixel by pixel towards the target Image?
Bare in mind, I'm using Windows-Universal I've tried DoubleAnimation but my knowledge in that stuff is really bad, I don't know where to start. The Image would sometimes have to move diagonally (across) rather than moving right then up.
How should I do this?
This is what I have so far:
private void MoveToTarget_Start()
{
moveToTimer = new DispatcherTimer();
moveToTimer.Tick += MoveToTarget_Tick;
moveToTimer.Interval = new TimeSpan(0, 0, 0, 0, 1);
moveToTimer.Start();
}
void MoveToTarget_Tick(object sender, object e)
{
}
First, you need to know how many pixels you need to move. For that, we can try to retrieve the absolute position of each element and compare them (there may be a more straightforward way, I just don't know how):
private Point GetAbsolutePosition(UIElement element)
{
var ttv = element.TransformToVisual(Window.Current.Content);
return ttv.TransformPoint(new Point(0, 0));
}
(taken from this answer)
From there, we retrieve the point of each element and compute the difference:
var position1 = GetAbsolutePosition(Image1);
var position2 = GetAbsolutePosition(Image2);
var offsetX = position2.X - position1.X;
var offsetY = position2.Y - position1.Y;
Now, we now of how many pixels we'll have to move on each axis. We add the TranslateTransform for the element (it may be better to do that beforehand directly from the XAML):
var translateTransform = new TranslateTransform();
image1.RenderTransform = translateTransform;
Finally, we create the animations, and target the TranslateTransform. Then we group them in a Storyboard, and start it:
var animationX = new DoubleAnimation()
{
From = 0,
To = offsetX,
Duration = TimeSpan.FromSeconds(2)
};
var animationY = new DoubleAnimation()
{
From = 0,
To = offsetY,
Duration = TimeSpan.FromSeconds(2)
};
Storyboard.SetTarget(animationX, translateTransform);
Storyboard.SetTargetProperty(animationX, "X");
Storyboard.SetTarget(animationY, translateTransform);
Storyboard.SetTargetProperty(animationY, "Y");
var storyboard = new Storyboard();
storyboard.Children.Add(animationX);
storyboard.Children.Add(animationY);
storyboard.Begin();
To be honest the best idea is to use DoubleAnimation and Storyboard classes.
I would set background as Canvas then You can animate it throught Canvas.SetLeft and Canvas.SetTop properties.
First You should create DoubleAnimationC class
DoubleAnimation da = new DoubleAnimation()
{
SpeedRatio = 3.0,
AutoReverse = false,
From = 0
To = 100
BeginTime = TimeSpan.FromSeconds(x),
};
Storyboard.SetTarget((Timeline)doubleAnimation, YOUR IMAGE);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(Canvas.Top)"));
Of course change those properties as You like and now we must create StoryBoard class which will contains our animation
Storyboard sb = new Storyboard();
sb.Children.Add(da);
sb.Start();
Hope it helps!
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.
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();