Reputation: 4021
(x,y) =(10,20),(50,30),(20,20),(40,22),(45,20),(50,35),.........
I want to create an animation with .Net.Normally I am using windows form. But if needed, i can use WPF.
It starts with (10,20) point.Actually a line starts from (10,20) then goes to (50,30) point with 10ms delay. then, from (50,30) to (20,20) after 10ms and so on.
This values will be read from a text file. I can simply make two ArrayList x&y, to put values from the text file.I just Have to know how could i generate the animated line from this x,y with 10 ms delay from each node to another?
If my question is difficult to understand, please let me know. I will try to make it easier.
Thanks in Advance.
Upvotes: 4
Views: 4501
Reputation: 9527
Here's a variation on Nico's great answer. I use PointAnimation
to animate the EndPoint
of a LineGeometry
which serves as the Data
for a Path
.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SoGeneratingAnimatedLine
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
var canvas = new Canvas();
Content = canvas;
var points =
new List<Point>()
{
new Point(10, 10),
new Point(90, 10),
new Point(90, 90),
new Point(10, 90),
new Point(10, 10)
};
var sb = new Storyboard();
for (int i = 0; i < points.Count - 1; i++)
{
var lineGeometry = new LineGeometry(points[i], points[i]);
var path =
new Path()
{
Stroke = Brushes.Black,
StrokeThickness = 2,
Data = lineGeometry
};
canvas.Children.Add(path);
var animation =
new PointAnimation(points[i], points[i + 1], new Duration(TimeSpan.FromMilliseconds(1000)))
{
BeginTime = TimeSpan.FromMilliseconds(i * 1010)
};
sb.Children.Add(animation);
RegisterName("geometry" + i, lineGeometry);
Storyboard.SetTargetName(animation, "geometry" + i);
Storyboard.SetTargetProperty(animation, new PropertyPath(LineGeometry.EndPointProperty));
}
MouseDown += (s, e) => sb.Begin(this);
}
}
}
Upvotes: 2
Reputation: 32597
If I understand you correctly, you want to animate the line as it would be just drawn. Here is a simple example with your values.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Canvas Name="lineCanvas" MouseLeftButtonDown="lineCanvas_MouseLeftButtonDown" Background="White" />
</Window>
The event handler will start the animation later. First, we'll define the data:
List<Point> Points = new List<Point>();
Storyboard sb;
public MainWindow()
{
InitializeComponent();
Points.Add(new Point(10, 20));
Points.Add(new Point(50, 30));
Points.Add(new Point(20, 20));
Points.Add(new Point(40, 22));
Points.Add(new Point(45, 20));
Points.Add(new Point(50, 35));
InitAnimation();
}
sb
is the Storyboard
that will contain the animation. Points
can easily be filled with the values from a file.
Let's initialize the animation. A new line will be added for each segment. Then the endpoint of the line will be animated.
public void InitAnimation()
{
sb = new Storyboard();
for (int i = 0; i < Points.Count - 1; ++i)
{
//new line for current line segment
var l = new Line();
l.Stroke = Brushes.Black;
l.StrokeThickness = 2;
//data from list
var startPoint = Points[i];
var endPoint = Points[i + 1];
//set startpoint = endpoint will result in the line not being drawn
l.X1 = startPoint.X;
l.Y1 = startPoint.Y;
l.X2 = startPoint.X;
l.Y2 = startPoint.Y;
lineCanvas.Children.Add(l);
//Initialize the animations with duration of 1 second for each segment
var daX = new DoubleAnimation(endPoint.X, new Duration(TimeSpan.FromMilliseconds(1000)));
var daY = new DoubleAnimation(endPoint.Y, new Duration(TimeSpan.FromMilliseconds(1000)));
//Define the begin time. This is sum of durations of earlier animations + 10 ms delay for each
daX.BeginTime = TimeSpan.FromMilliseconds(i * 1010);
daY.BeginTime = TimeSpan.FromMilliseconds(i * 1010);
sb.Children.Add(daX);
sb.Children.Add(daY);
//Set the targets for the animations
Storyboard.SetTarget(daX, l);
Storyboard.SetTarget(daY, l);
Storyboard.SetTargetProperty(daX, new PropertyPath(Line.X2Property));
Storyboard.SetTargetProperty(daY, new PropertyPath(Line.Y2Property));
}
}
The duration of the animations can easily be changed according to the length of the line to make it look nicer.
Last task, show the animation:
private void lineCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
sb.Begin(this);
}
Upvotes: 9