I am working to create a Move Animation in windows. I want to move and object from one location to the other. Basically what I am trying to do is to FLIP the selected rectangle and then randomly swap the positions of two Rectangle objects the movement should be shown as an animation.
I have tried and achieved FLIP animation. But now if there are 4 rectangles in a grid, random two rectangles should exchange their positions followed by a move animation. I tried to use the below code. But it is not working.
It just creates a Rectangle in the center of the screen and nothing else.
1) Created a new project
2) Added the below code to the MainPage.xaml.cs file.
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += Create_And_Run_Animation;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
private void Create_And_Run_Animation(object sender, EventArgs e)
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 200;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
ContentPanel.Children.Add(myRectangle);
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTargetProperty(myDoubleAnimation2, new PropertyPath("(Canvas.Top)"));
myDoubleAnimation1.To = 200;
myDoubleAnimation2.To = 200;
// Make the Storyboard a resource.
ContentPanel.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
}
}
I haven't added anything in the xaml file. that is just as it is. Is there anything that i need to add to the xaml file for the animation to run properly. ?
Please Help
Better late than never ;-).
Just got the problem myself, you need to add
myDoubleAnimation1.EnableDependentAnimation = true;
myDoubleAnimation2.EnableDependentAnimation = true;
to your code to force WinRT to do execute animation - otherwise it deems your animation to be not worthy due to possible performance issues ... sigh.
Source: https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.animation.doubleanimation.enabledependentanimation.aspx
Related
hi i want to write a animation where car drivin on a road and waits untill train will pass and then goes again,but i cant find anything on the internet about it , i also want to cars drive in a "row" but now they driving through each other through.
Is it even possible ?
namespace Symulator_ruchu
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Random r = new Random();
IEnumerable<PathFigure> colle;
DispatcherTimer dispatcherTimer = new DispatcherTimer();
DispatcherTimer train = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
dispatcherTimer.Tick += new EventHandler(dispTimer_tick);
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
train.Tick += new EventHandler(train_tick);
train.Interval = new TimeSpan(0, 0, 10);
train.Start();
}
private void train_tick(object sender, EventArgs e)
{
Path car = new Path
{
Name = "AnimatedMatrixTrain",
Fill = Train.Fill,
Data = new RectangleGeometry
{
Rect = new Rect(0, 0, 55, 270)
},
LayoutTransform = new RotateTransform
{
Angle = 90
},
RenderTransform = new MatrixTransform
{
Matrix = new Matrix
{
OffsetX = 100,
OffsetY = 100
}
}
};
MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
{
Duration = TimeSpan.FromSeconds(r.Next(5, 10)),
DoesRotateWithTangent = true,
AutoReverse = false,
PathGeometry = new PathGeometry
{
Figures = PathFigureCollection.Parse("M 745,900 L 745,0")
}
};
Storyboard.SetTarget(maup, car);
Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(maup);
//Canvas.SetTop(car, r.Next(1, 500));
//Canvas.SetLeft(car, r.Next(1, 500));
storyboard.Begin(car);
Canv.Children.Add(car);
}
private void dispTimer_tick(object sender, EventArgs e)
{
Path car = new Path
{
Name = "AnimatedMatrixCar",
Fill = Car.Fill,
Data = new RectangleGeometry
{
Rect = new Rect(0,0,60,30)
},
LayoutTransform = new RotateTransform
{
Angle = 180
},
RenderTransform = new MatrixTransform
{
Matrix = new Matrix
{
OffsetX = 100,
OffsetY = 100
}
}
};
MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
{
Duration = TimeSpan.FromSeconds(r.Next(5,10)),
DoesRotateWithTangent = true,
AutoReverse = false,
PathGeometry = new PathGeometry
{
Figures = PathFigureCollection.Parse("m 10,286 h 800 c 130,10 190, 200 -105, 180 h -450 c -160,10 -200,250 -35,290 H 1200")
}
};
Storyboard.SetTarget(maup, car);
Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(maup);
//Canvas.SetTop(car, r.Next(1, 500));
//Canvas.SetLeft(car, r.Next(1, 500));
storyboard.Begin(car);
Canv.Children.Add(car);
}
}
Here is how wpf window look like:
enter image description here
I don't think you can use collision detection in an animation. You'd have to write your own code moved the car pixel by pixel. You could then use a distance calculation between some calculated edge point of your rectangle and anything else.
That's all possible but you'd be calculating angle of rotation yourself. Fair bit of fiddly work and it might not even be so smooth once you're finished.
I'd go with storyboard and animations.
Some trial and error will be necessary for this in order for the train to pass just after a car stops.
Use a storyboard and at least two matrix animations within that.
Each animation can have a begin time and duration. The first animation should have no begin time, you want that to start straight away.
You might want one of the easout easing functions so it slows down as it nears the crossing.
The second animation should have a begin time which makes it start up again after the train has passed. This time with an ease in easing function so it accelerates up to speed.
You will need to split your path geometry into two parts. Up to the crossing and then from the crossing to end of road. You could use inkscape or manually find where your crossing is using the points in the geometry.
You will apply this to your first car.
Off it goes.
Use async await to introduce a delay. Then repeat using your storyboard with the second car. It will of course do the same as the first one but start a bit later, giving a gap.
There is a bit of a complication though. Maybe you want your second car to stop behind the first.
That means you need two different geometries with the second ending earlier.
Not sure if you have your geometries.
I would use inkscape to draw the path. It's free. You could import your base picture, add a layer and draw a vectorin the new layer. That has line start and and nodes and curve handle nodes. You can drag the nodes and add more. There's a bit of a learning curve but it'll be fairly easy to do your neat line. Then select your line and save as xaml. You'll get a file with a path in it, and your geometry. Extra nodes for a second and third car stop position.
Are your cars looking ok with the matrix animation? I wrote a facing converter to rotate moving (infantry or cavalry) columns so they face the direction they are moving in.
I am working on a WPF Application. In this app, I need to move my train on a railway. I drew all the railway lines on a canvas. So I just need to move the trains.
I also searched the Internet and I found that! example.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using System.Windows.Media.Animation;
using System.Windows.Media;
namespace SDKSamples
{
// This example shows how to use PointAnimation to animate the
// position of an ellipse by animating the Center property of an
// EllipseGeometry. PointAnimation is used because the Center property
// takes a Point value.
public class PointAnimationExample : Page
{
public PointAnimationExample()
{
// Create a NameScope for this page so that
// Storyboards can be used.
NameScope.SetNameScope(this, new NameScope());
EllipseGeometry myEllipseGeometry = new EllipseGeometry();
myEllipseGeometry.Center = new Point(200, 100);
myEllipseGeometry.RadiusX = 15;
myEllipseGeometry.RadiusY = 15;
// Assign the EllipseGeometry a name so that
// it can be targeted by a Storyboard.
this.RegisterName(
"MyAnimatedEllipseGeometry", myEllipseGeometry);
Path myPath = new Path();
myPath.Fill = Brushes.Blue;
myPath.Margin = new Thickness(15);
myPath.Data = myEllipseGeometry;
PointAnimation myPointAnimation = new PointAnimation();
myPointAnimation.Duration = TimeSpan.FromSeconds(2);
// Set the animation to repeat forever.
myPointAnimation.RepeatBehavior = RepeatBehavior.Forever;
// Set the From and To properties of the animation.
myPointAnimation.From = new Point(200, 100);
myPointAnimation.To = new Point(450, 250);
// Set the animation to target the Center property
// of the object named "MyAnimatedEllipseGeometry."
Storyboard.SetTargetName(myPointAnimation, "MyAnimatedEllipseGeometry");
Storyboard.SetTargetProperty(
myPointAnimation, new PropertyPath(EllipseGeometry.CenterProperty));
// Create a storyboard to apply the animation.
Storyboard ellipseStoryboard = new Storyboard();
ellipseStoryboard.Children.Add(myPointAnimation);
// Start the storyboard when the Path loads.
myPath.Loaded += delegate(object sender, RoutedEventArgs e)
{
ellipseStoryboard.Begin(this);
};
Canvas containerCanvas = new Canvas();
containerCanvas.Children.Add(myPath);
Content = containerCanvas;
}
}
}
I tried this code and its works. But when I run the application, the roads I drew before no longer appear. So how can I move my trains on my railway?
i continued to searching and i found the solution.
I used to DoubleAnimation instance.
The working code is below.
public void move( Image target, double oldX, double oldY, double newX,
double newY,int time)
{
TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;
DoubleAnimation anim1 = new DoubleAnimation(oldY, newY,
TimeSpan.FromSeconds(time));
anim1.RepeatBehavior = RepeatBehavior.Forever;
trans.BeginAnimation(TranslateTransform.YProperty, anim1);
DoubleAnimation anim2 = new DoubleAnimation(oldX, newX,
TimeSpan.FromSeconds(time));
anim2.RepeatBehavior = RepeatBehavior.Forever;
trans.BeginAnimation(TranslateTransform.XProperty, anim2);
}
I am testing the Storyboard.SetTarget Method. I need to animate rectangle's width and height change.
I found Microsoft example, but when I include the code in my program, the Solution does not build and deploy.
I get error like this:
IDE0006 Error encountered while loading the project. Some project
features, such as full solution analysis for the failed project and
projects that depend on it, have been disabled.
error CS0246: The type or namespace name 'Color' could not be found (are you missing a using directive or an assembly reference?)
When I add namespace like:
System.Windows.Media.Animation
I get error:
error CS0234: The type or namespace name 'Media' does not exist in the
namespace 'System.Windows' (are you missing an assembly reference?)
Am I using example not for UWP??
Here is the code from example that I used:
private void Create_And_Run_Animation(object sender, EventArgs e)
{
// Create a yellow rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 20;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
LayoutRoot.Children.Add(myRectangle);
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTargetProperty(myDoubleAnimation2, new PropertyPath("(Canvas.Top)"));
myDoubleAnimation1.To = 200;
myDoubleAnimation2.To = 40;
// Make the Storyboard a resource.
LayoutRoot.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
Ok, I was using the example for Silverlight.
I found C# UWP sample here:
Storyboard Class
and it works now, but it changes the position of rectangle and not the Width.
How can I change the transition to be applied to the Width property of Rectangle?
New code is like this:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 20;
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.
InfoGrid.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 = 200;
myDoubleAnimation.To = 300;
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);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty));
// Set the X and Y properties of the Transform to be the target properties
// of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation, "X");
myDoubleAnimation.To = 200;
// Make the Storyboard a resource.
InfoGrid.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
But I cannot get the Rectangle.WidthProperty right in UWP.
Intelli says:
cannot convert from 'Windows.UI.Xaml.DependencyProperty' to 'string'
I can't find the resources on MSDN.
cannot convert from 'Windows.UI.Xaml.DependencyProperty' to 'string'
The problem is the Path parameter of SetTargetProperty method is string value. You could not pass PropertyPath to it. You just need to pass the Width string value.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 20;
myDoubleAnimation.To = 300;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard.SetTarget(myDoubleAnimation, myRectangle);
Storyboard.SetTargetProperty(myDoubleAnimation, "Width");
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
If you use the below code to animate with property, you will not see any effects. Because you have made a dependent animation. By default, the animation system won't run a dependent animation. You can still use this animation, but you must specifically enable each such dependent animation. To enable your animation, set the EnableDependentAnimation property of the animation object to true.
myDoubleAnimation.EnableDependentAnimation = true;
For more please refer Storyboarded animations official document.
I want to make a turning animation to show the vehicle turning in Junction. Also, I want to do it with c#(code behind) because my vehicles are dynamically added.
Solution tried:
I tried to use TranslateTransform and RotateTransform but I could only create sharp turn animation. I want to create a smooth turn animation.
Current Output:
Sample Code
//Code to add car
private void Click1_Click(object sender, RoutedEventArgs e)
{
var myCar = new Image()
{
Source = new BitmapImage(new Uri("ms-appx:///Assets/RedCar.png")),
Width = 140,
Height = 65,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top,
RenderTransform = new TranslateTransform()
{
X = 0,
Y = actualHeight / 2 - 145
}
};
VehicleGrid.Children.Add(myCar);
}
//Code to create forward animation
private void MoreForward(UIElement element)
{
Storyboard storyboard = new Storyboard();
DoubleAnimation doubleAnimation = new DoubleAnimation()
{
Duration = new Duration(new TimeSpan(0, 0, 3)),
To = LeftRoad.ActualWidth - 140
};
Storyboard.SetTarget(doubleAnimation, element.RenderTransform);
Storyboard.SetTargetProperty(doubleAnimation, "X");
storyboard.Children.Add(doubleAnimation);
storyboard.Begin();
}
Full Code
You can see my full code in Github: TrafficManagementSystem
There's an interesting post that details how to create a layout path where your object can move along with.
But in a simple scenario like yours, you basically just want a curved motion like what's described in this Android's Material Design Guideline. Yeah... Android's, as we don't have native curved motion API support just yet (the Windows UI team did mention that they are looking to support this in the future though).
However, it's not too difficult to create your own curved motion. In fact, many have used this trick on the web already - apply the opposite speed of an easing on each axis. Also in your case, you will want the curve of the easing to be sharp in order to produce a nice turning animation.
For example, for a car coming from left to right and then doing a left turn, you can apply a QuinticEase with EaseIn mode on x-axis and one with EaseOut on y-axis. To turn the vehicle, just apply another rotation animation to it but with a short delay and lesser duration to ensure the turning only happens at the crossroad.
By slightly modifying my answer in this question, you can achieve what I described above with the following code
The AnimateTransform helper method
public static void AnimateTransform(this UIElement target, string propertyToAnimate, Orientation? orientation, double? from, double to, int duration = 3000, int startTime = 0, EasingFunctionBase easing = null)
{
if (easing == null)
{
easing = new ExponentialEase();
}
var transform = target.RenderTransform as CompositeTransform;
if (transform == null)
{
transform = new CompositeTransform();
target.RenderTransform = transform;
}
target.RenderTransformOrigin = new Point(0.5, 0.5);
var db = new DoubleAnimation
{
To = to,
From = from,
EasingFunction = easing,
Duration = TimeSpan.FromMilliseconds(duration)
};
Storyboard.SetTarget(db, target);
var axis = string.Empty;
if (orientation.HasValue)
{
axis = orientation.Value == Orientation.Horizontal ? "X" : "Y";
}
Storyboard.SetTargetProperty(db, $"(UIElement.RenderTransform).(CompositeTransform.{propertyToAnimate}{axis})");
var sb = new Storyboard
{
BeginTime = TimeSpan.FromMilliseconds(startTime)
};
sb.Children.Add(db);
sb.Begin();
}
Create the turning animations
MyCar.AnimateTransform("Translate", Orientation.Horizontal, null, -600, duration: 3000, easing: new QuinticEase
{
EasingMode = EasingMode.EaseIn
});
MyCar.AnimateTransform("Translate", Orientation.Vertical, null, -600, duration: 3000, easing: new QuinticEase
{
EasingMode = EasingMode.EaseOut
});
MyCar.AnimateTransform("Rotation", null, null, -90, duration: 2000, startTime: 500);
Result in motion
Alternatively, you can replace the traditional Storyboard animation with the new Composition API, which provides fully customizable easing functions (see below), but the idea is the same.
public static CubicBezierEasingFunction EaseOutExpo(this Compositor compositor) =>
compositor.CreateCubicBezierEasingFunction(new Vector2(0.14f, 1f), new Vector2(0.34f, 1f));
Hope this helps!
I am trying to create a simple animation using code. I copy pasted the same code of the msdn which is the following:
public MainPage()
{
InitializeComponent();
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 200;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
LayoutRoot.Children.Add(myRectangle);
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(
myDoubleAnimation1, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTargetProperty(
myDoubleAnimation2, new PropertyPath("(Canvas.Top)"));
myDoubleAnimation1.To = 200;
myDoubleAnimation2.To = 200;
// Make the Storyboard a resource.
LayoutRoot.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
However, I obtain a red square that doesn't move when I run the emulator.
What could be the problem?
Thank you!