Click here to Skip to main content
15,896,912 members
Articles / Programming Languages / C#

Animation Along a Path for Silverlight

Rate me:
Please Sign up or sign in to vote.
4.89/5 (18 votes)
4 Mar 2009CPOL4 min read 146.6K   2.6K   69  
Animates an object along a geometric path
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

using Petzold.Shapes;
using System.Collections.Generic;
using System.ComponentModel;

namespace PathAnimation
{
    public class PointAnimationUsingPath : BaseAnimationUsingPath
    {
        public override void CreateStory()
        {
            if (!IsStoryDirty)
                return;

            if (Duration == null ||
                Target == null ||
                TargetProperty == null ||
                PathGeometry == null ||
                PathGeometry is GeometryGroup) // won't work with GeometryGroups!
            {
                Story = null;
                return;
            }

            Story = new Storyboard();
            Story.BeginTime = BeginTime;
            Story.Duration = Duration;
            Story.AutoReverse = AutoReverse;
            Story.FillBehavior = FillBehavior;
            Story.RepeatBehavior = RepeatBehavior;

            Story.Completed += delegate(object sender, EventArgs e) { OnCompleted(e); };

            Storyboard.SetTarget(Story, Target);
            Storyboard.SetTargetProperty(Story, TargetProperty);

            PathGeometryHelper helper = new PathGeometryHelper();
            PathGeometry flattenedGeometry = helper.FlattenGeometry(PathGeometry, Tolerance);

            double length;

            List<Point> points = GetPointsOnFlattenedPath(flattenedGeometry, out length);

            PointAnimationUsingKeyFrames keyFrames = new PointAnimationUsingKeyFrames();

            // handle first keyframe 
            LinearPointKeyFrame keyFrameZero = new LinearPointKeyFrame();
            keyFrameZero.KeyTime = TimeSpan.Zero;
            keyFrameZero.Value = points[0];

            keyFrames.KeyFrames.Add(keyFrameZero);

            double accumLength = 0;

            for (int i = 0; i < points.Count - 1; i++)
            {
                accumLength += CalculateDistance(points[i], points[i + 1]);
                double fractionOfOverAllLength = accumLength / length;

                LinearPointKeyFrame keyFrame = new LinearPointKeyFrame();

                keyFrame.KeyTime = new TimeSpan(0, 0, 0, 0, (int)(Duration.TotalMilliseconds * fractionOfOverAllLength));

                keyFrame.Value = points[i + 1];

                keyFrames.KeyFrames.Add(keyFrame);
            }

            Story.Children.Add(keyFrames);

            IsStoryDirty = false;
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I work in the Bay Area primarily developing software on the Windows platform using C++, .NET/C#, WPF, and Silverlight.

Comments and Discussions