I have a project that I need to make an image follow a spline.
I build the spline using Graphics.DrawCurve through an array of Points.
I'm trying to use PointAnimationUsingPath but I can't seem to get it to work. Apparently it doesn't work in C# with Windows form.
Can someone give me a light on how to do this?
Thank you All.
-----EDIT-----
Change to a WPF UserControl as recommend in comments.
Still need some help as the shape does not move exactly following the dots, below my code:
public partial class SplineBox : UserControl
{
Point[] finalPoint;
public SplineBox()
{
InitializeComponent();
}
public void MoveShape(Point[] _path)
{
// Create a NameScope for the page so that
// we can use Storyboards.
NameScope.SetNameScope(this, new NameScope());
// Create the EllipseGeometry to animate.
EllipseGeometry animatedEllipseGeometry =
new EllipseGeometry(new Point(10, 100), 15, 15);
// Register the EllipseGeometry's name with
// the page so that it can be targeted by a
// storyboard.
this.RegisterName("AnimatedEllipseGeometry", animatedEllipseGeometry);
// Create a Path element to display the geometry.
Path ellipsePath = new Path();
ellipsePath.Data = animatedEllipseGeometry;
ellipsePath.Fill = Brushes.Blue;
ellipsePath.Margin = new Thickness(15);
SplineCanvas.Children.Add(ellipsePath);
this.Content = SplineCanvas;
// Create the animation path.
PathGeometry animationPath = new PathGeometry();
PathFigure pFigure = new PathFigure();
pFigure.StartPoint = _path[0];
PolyBezierSegment pBezierSegment = new PolyBezierSegment();
for (int p = 1; p < _path.Length; p++)
{
pBezierSegment.Points.Add(_path[p]);
}
pFigure.Segments.Add(pBezierSegment);
animationPath.Figures.Add(pFigure);
// Freeze the PathGeometry for performance benefits.
animationPath.Freeze();
// Create a PointAnimationgUsingPath to move
// the EllipseGeometry along the animation path.
PointAnimationUsingPath centerPointAnimation = new PointAnimationUsingPath();
centerPointAnimation.PathGeometry = animationPath;
centerPointAnimation.Duration = TimeSpan.FromSeconds(5);
centerPointAnimation.RepeatBehavior = RepeatBehavior.Forever;
// Set the animation to target the Center property
// of the EllipseGeometry named "AnimatedEllipseGeometry".
Storyboard.SetTargetName(centerPointAnimation, "AnimatedEllipseGeometry");
Storyboard.SetTargetProperty(centerPointAnimation,
new PropertyPath(EllipseGeometry.CenterProperty));
// Create a Storyboard to contain and apply the animation.
Storyboard pathAnimationStoryboard = new Storyboard();
pathAnimationStoryboard.RepeatBehavior = RepeatBehavior.Forever;
pathAnimationStoryboard.AutoReverse = true;
pathAnimationStoryboard.Children.Add(centerPointAnimation);
// Start the Storyboard when ellipsePath is loaded.
ellipsePath.Loaded += delegate (object sender, RoutedEventArgs e)
{
// Start the storyboard.
pathAnimationStoryboard.Begin(this);
};
}
public void Paint(ScreenObject _spline)
{
List<Point> points = new List<Point>();
if (true)
{
var spline = _spline;
foreach (System.Windows.Point point in spline.SplineAnchors)
{
Point tempP = new Point((int)point.X, (int)point.Y);
points.Add(tempP);
}
finalPoint = points.ToArray();
//Pen pen = new Pen(Color.FromArgb(255, 0, 0, 255), 1);
//e.Graphics.DrawCurve(pen, finalPoint);
foreach (Point p in finalPoint)
{
// Create a red Ellipse.
Ellipse myEllipse = new Ellipse();
// Create a SolidColorBrush with a red color to fill the
// Ellipse with.
SolidColorBrush mySolidColorBrush = new SolidColorBrush();
// Describes the brush's color using RGB values.
// Each value has a range of 0-255.
mySolidColorBrush.Color = Color.FromArgb(255, 100, 255, 0);
myEllipse.Fill = mySolidColorBrush;
myEllipse.StrokeThickness = 2;
myEllipse.Stroke = Brushes.Black;
// Set the width and height of the Ellipse.
myEllipse.Width = 10;
myEllipse.Height = 10;
myEllipse.Margin = new Thickness(p.X - 5, p.Y - 5, 0, 0);
//e.Graphics.DrawRectangle(pen, new Rectangle(p.X - 5, p.Y - 5, 10, 10));
//e.Graphics.FillRectangle(Brushes.Red, new Rectangle(p.X - 5, p.Y - 5, 10, 10));
SplineCanvas.Children.Add(myEllipse);
}
}
}
}