I'm trying to animate an image to move to a certain point then turn and come back to the startign point,I searched this site for answers but i still can't seem to understand how the RenderTransform works.
This is my current code for anyone interested in helping me:
public static void MoveTo(this Image target, double newX, double newY,int s)
{
Vector offset = VisualTreeHelper.GetOffset(target);
DoubleAnimation animay = new DoubleAnimation(0, newY - offset.Y, TimeSpan.FromSeconds(s));
DoubleAnimation animax = new DoubleAnimation(0, newX - offset.X, TimeSpan.FromSeconds(s));
TransformGroup transformGroup = new TransformGroup();
TranslateTransform translatetransform = new TranslateTransform();
ScaleTransform scaletransform = new ScaleTransform();
transformGroup.Children.Add(translatetransform);
transformGroup.Children.Add(scaletransform);
target.RenderTransform = transformGroup;
target.RenderTransform.BeginAnimation(TranslateTransform.YProperty, animay);
target.RenderTransform.BeginAnimation(TranslateTransform.XProperty, animax);
}
Edit:
Just to be clear I should add that I know how to animate the object to move and flip separately,but can't make them work in succession with a Transform Group.
Related
I am using MSDN example to setup the animation of Width of a Rectangle in C3 UWP.
Here is the code of the sample:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 0;
myRectangle.Height = 20;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myRectangle.Fill = myBrush;
// Create the transform
TranslateTransform stretchTransform = new TranslateTransform();
stretchTransform.X = 0;
stretchTransform.Y = 0;
myRectangle.RenderTransform = stretchTransform;
// Add the rectangle to the tree.
DefaultLayout.Children.Add(myRectangle);
myRectangle.Name = "myWidthAnimatedRectangle";
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard justintimeStoryboard = new Storyboard();
justintimeStoryboard.Duration = duration;
justintimeStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTarget(myDoubleAnimation, stretchTransform);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
// Set the X property of the Transform to be the target property
Storyboard.SetTargetProperty(myDoubleAnimation, "X");
myDoubleAnimation.To = 300.0;
// Make the Storyboard a resource.
DefaultLayout.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
However, on Build, what it does is move the object and not change its width.
I need to animate width change.
However, on Build, what it does is move the object and not change its width. I need to animate width change.
Your code was used to animate the Rectangle's position, not its width. You could specify a default value for its width and animate its ScaleTransform.
If you have to use DoubleAnimation to animate its width, you need to set EnableDependentAnimation to true. Please check the following code sample:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 10;
myRectangle.Height = 20;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
DefaultLayout.Children.Add(myRectangle);
myRectangle.Name = "myWidthAnimatedRectangle";
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard justintimeStoryboard = new Storyboard();
Storyboard.SetTargetProperty(myDoubleAnimation, "(Rectangle.Width)");
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
myDoubleAnimation.To = 300.0;
myDoubleAnimation.EnableDependentAnimation = true;
justintimeStoryboard.Children.Add(myDoubleAnimation);
// Make the Storyboard a resource.
DefaultLayout.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
I have a TextBox(toAnimate) and an Button(toClick).
When i click the button, the TextBox disappears.
But it should move on the X Position 20 units.
What did i do wrong?
//double left = Canvas.GetLeft(toAnimate); Returned wrong value.
TranslateTransform tanl = new TranslateTransform();
Vector pos = VisualTreeHelper.GetOffset(toAnimate);
double left = pos.X;
toAnimate.RenderTransform = tanl;
DoubleAnimation doua = new DoubleAnimation((left + 20), left, TimeSpan.FromSeconds(3));
tanl.BeginAnimation(TranslateTransform.XProperty, doua);
I have created a TransformGroup with multiple Transforms and assigned this to an Image's RenderTransform property:
TransformGroup group = new TransformGroup();
ScaleTransform st = new ScaleTransform();
group.Children.Add(st);
TranslateTransform tt = new TranslateTransform();
group.Children.Add(tt);
image.RenderTransform = group;
If I want to get an individual transform from this group in WPF, I can do this:
TranslateTransform tt = (TranslateTransform)((TransformGroup)image.RenderTransform).Children.First(tr => tr is TranslateTransform);
However, in Silverlight, this TransformGroup is apparently implicitly converted to a MatrixTransform, because running the above code gives the error:
Unable to cast object of type 'System.Windows.Media.MatrixTransform' to type 'System.Windows.Media.TransformGroup'.
Is there any way to avoid the conversion from TransformGroup to MatrixTransform? If not, how can I recover the individual Transforms from the MatrixTransform?
D'oh! I had accidentally tried to use the TransformGroup before assigning it, so image.RenderTransform was still set to the default of MatrixTransform.
In case anyone needed to use a MatrixTransform to perform a ScaleTransform followed by a TranslateTransform, given these transforms:
ScaleTransform st = new ScaleTransform();
TranslateTransform tt = new TranslateTransform();
The following two options should provide equivalent results:
Using TransformGroup:
TransformGroup group = new TransformGroup();
group.Children.Add(st);
group.Children.Add(tt);
image.RenderTransform = group;
Using MatrixTransform:
MatrixTransform mt = new MatrixTransform
{
Matrix = new Matrix
{
M11 = st.ScaleX,
M22 = st.ScaleY,
OffsetX = tt.X,
OffsetY = tt.Y
}
};
image.RenderTransform = mt;
I'm newbie to C# and I'm trying to do a simple application which have elements that move a lot on the screen. After some research I found a code that moved a button. The problem is the button returns to it's original state (although invisible). When I click the button it moves outside the screen (just as I wanted), but when I click it back (it should do the reverse animation) but instead, it just magically appears on the screen again.
I also tried to make it change position after the animation ended, but that didn't work either. Here's my code:
private void ButtonOnClick(object sender, RoutedEventArgs e)
{
if (nextSlideMoving)
return;
nextSlideMoving = true;
KinectTileButton target = (KinectTileButton)sender;
Vector offset = VisualTreeHelper.GetOffset(target);
if (nextSlideHidden)
moveAnimation(target, 0, offset.Y);
else
moveAnimation(target, -target.ActualWidth, offset.Y);
}
private void moveAnimation(KinectTileButton target, double newX, double newY)
{
Vector offset = VisualTreeHelper.GetOffset(target);
var top = offset.Y;
var left = offset.X;
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
DoubleAnimation anim1 = new DoubleAnimation(0, newY - top, TimeSpan.FromSeconds(0.5));
trans.BeginAnimation(TranslateTransform.YProperty, anim1);
DoubleAnimation anim2 = new DoubleAnimation(0, newX - left, TimeSpan.FromSeconds(0.5));
anim2.Completed += new EventHandler(finishedAnimation);
trans.BeginAnimation(TranslateTransform.XProperty, anim2);
}
public void finishedAnimation(Object sender, EventArgs e)
{
nextSlideMoving = false;
nextSlideHidden = !nextSlideHidden;
Console.WriteLine(nextSlideHidden);
if (nextSlideHidden)
nextSlide.Margin = new Thickness(-(SystemParameters.VirtualScreenWidth * 0.2), SystemParameters.VirtualScreenHeight * 0.2, SystemParameters.VirtualScreenWidth * 0.8, SystemParameters.VirtualScreenHeight * 0.2); // (LEFT, TOP, RIGHT, BOTTOM)
else
nextSlide.Margin = new Thickness(0, SystemParameters.VirtualScreenHeight * 0.2, SystemParameters.VirtualScreenWidth * 0.8, SystemParameters.VirtualScreenHeight * 0.2); // (LEFT, TOP, RIGHT, BOTTOM)
}
You seem to be asking for FillBehavior. Take a look at following link:
http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.fillbehavior(v=vs.110).aspx
Also take a look at AutoReverse property:
http://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.autoreverse(v=vs.110).aspx
If those properties doesn't help you any futher I would gladly take a look at your example just please upload it online.
I am able to animate the movement of a Border:
private void MoveTo(Border target, double newX, double newY)
{
Vector offset = VisualTreeHelper.GetOffset(target);
var top = offset.Y;
var left = offset.X;
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
DoubleAnimation anim1 = new DoubleAnimation(0, newY - top, TimeSpan.FromMilliseconds(500));
DoubleAnimation anim2 = new DoubleAnimation(0, newX - left, TimeSpan.FromMilliseconds(500));
trans.BeginAnimation(TranslateTransform.YProperty, anim1);
trans.BeginAnimation(TranslateTransform.XProperty, anim2);
}
But I would like to be able to animate an increase in Height and Width as well as position to give the impression of enlarging an image(which is contained in a Border in my case and example above)).
Is this spossible with code behind?
OK, I tried the scale transform but it does not appear to do anything - do I need a storyboard?
private void Zoom(Border target)
{
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
DoubleAnimation anim1 = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
DoubleAnimation anim2 = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
trans.BeginAnimation(ScaleTransform.ScaleXProperty, anim1);
trans.BeginAnimation(ScaleTransform.ScaleYProperty, anim2);
}
It is better to use scale transform for zooming, but if you insist on animating W/H you can do it, since these are normal DP you can animate them using standard DoubleAnimation/DoubleAnimationUsingKeyFrames
Something like
DoubleAnimation doubleAnimation = new DoubleAnimation(100, 200, new Duration(TimeSpan.FromMilliseconds(500)));
this.BeginAnimation(FrameworkElement.WidthProperty, doubleAnimation);
Use ScaleTransform, no need for Height & Width animations, the ScaleTransform will affect your Border's VisualTree so the inner image will be stretched as well.
private void Zoom(Border target)
{
ScaleTransform trans = new ScaleTransform();
target.RenderTransform = trans;
// if you use the same animation for X & Y you don't need anim1, anim2
DoubleAnimation anim = new DoubleAnimation(1, 2, TimeSpan.FromMilliseconds(1000));
trans.BeginAnimation(ScaleTransform.ScaleXProperty, anim);
trans.BeginAnimation(ScaleTransform.ScaleYProperty, anim);
}