The MindFusion Forums
Archived Boards >> Silverlight >> Animation
https://mindfusion.eu/Forum/YaBB.pl?num=1301505202

Message started by pwdparis on Mar 30th, 2011 at 5:13pm

Title: Animation
Post by pwdparis on Mar 30th, 2011 at 5:13pm
Is it possible to animate a link in diagramLite? We are looking to programmatically place a node on a diagram and have that node be linked to an existing node using a smooth color animation (say a red link progressively moving like a drawing from the origin point to the destination point).

Thanks,

Mark

Title: Re: Animation
Post by Stoyo on Mar 30th, 2011 at 5:46pm
DiagramLinks do not provide dependency properties for control points, so you will have to use an intermediate class to apply the PointAnimation upon. Here's an example:


Code (]
public class LinkAnimator : DependencyObject
{
     public LinkAnimator(DiagramLink link, int pointIndex)
     {
           this.link = link;
           this.pointIndex = pointIndex;
     }

     public static DependencyProperty PointProperty = DependencyProperty.Register(
           "Point",
           typeof(Point),
           typeof(LinkAnimator),
           new PropertyMetadata(OnPointChanged));

     private static void OnPointChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
     {
           var linkAnimator = (LinkAnimator)d;
           var link = linkAnimator.link;
           link.ControlPoints[linkAnimator.pointIndex):

= (Point)e.NewValue;
           link.UpdateFromPoints();
     }

     public Point Point
     {
           get { return (Point)GetValue(PointProperty); }
           set { SetValue(PointProperty, value); }
     }

     public void Animate(Point from, Point to)
     {
           var animation = new PointAnimation();
           animation.From = from;
           animation.To = to;

           var storyboard = new Storyboard();
           storyboard.Children.Add(animation);
           Storyboard.SetTarget(animation, this);
           Storyboard.SetTargetProperty(
                 animation, new PropertyPath(PointProperty));

           storyboard.Begin();
     }

     private DiagramLink link;
     private int pointIndex;
}

new LinkAnimator(link, 1).Animate(new Point(100, 100), new Point(200, 200));


I hope that helps,
Stoyan

Title: Re: Animation
Post by pwdparis on Apr 18th, 2011 at 8:54pm
Stoyan,

We're getting some interesting results with this code ~ the links appear to animate in straight lines (between the start point and end point of a link) instead of along the segments. I've tried to create a PointAnimationUsingKeyFrames animation with a EasingPointKeyFrames containing the control points and estimated key times (based on the length of the link as a whole). Unfortunately, we get the same sort of results, only this time applied to the initial segment (as opposed to previously, where the entire linke was fllipped).

Here's the code I'm using:

public const delayConst = 1;



public void Animate(Point from, Point to)



{




var animation = new PointAnimationUsingKeyFrames();








double lineLength = 0;








int segmentCount = this.link.ControlPoints.Count;




List<KeyValuePair<double, Point>> segmentArray = new List<KeyValuePair<double, Point>>();





for (int x = 0; x < segmentCount; x++)




{





double xVal = 0;





double yVal = 0;





if (x == segmentCount - 1)





{






xVal = link.ControlPoints[x].X - link.EndPoint.X;






yVal = link.ControlPoints[x].Y - link.EndPoint.Y;





}





else





{






xVal = link.ControlPoints[x].X - link.ControlPoints[x + 1].X;






yVal = link.ControlPoints[x].Y - link.ControlPoints[x + 1].Y;





}






double xValSquared = Math.Pow(xVal, 2);





double yValSquared = Math.Pow(yVal, 2);






double segmentLength = Math.Sqrt(xValSquared + yValSquared);





segmentArray.Add(new KeyValuePair<double, Point>(segmentLength, link.ControlPoints[x]));










lineLength += segmentLength;




}





int delayConstInMilli = delayConst * 1000;





foreach (KeyValuePair<double,Point> pair in segmentArray)




{





EasingPointKeyFrame frame = new EasingPointKeyFrame()





{






KeyTime = new TimeSpan(0, 0, 0, 0, (int)Math.Ceiling((pair.Key * delayConstInMilli) / lineLength)),






Value = pair.Value





};






animation.KeyFrames.Add(frame);









}








var storyboard = new Storyboard();




storyboard.Children.Add(animation);




Storyboard.SetTarget(animation, this);




Storyboard.SetTargetProperty(animation, new PropertyPath(PointProperty));




storyboard.Begin();
}

All help much appreciated,

Mark
Goolara, LLC

Title: Re: Animation
Post by Stoyo on Apr 19th, 2011 at 6:24am
Yes, that class animates only a single point and was intended for single-segment links. Animations update a single value, so in any case you will have to map it to one of the link segments and grow the link segment by segment.

To animate link passing through a list of points, you could apply several times the LinkAnimator above by handling the animation' Completed event. The handler should add a new segment and run a new animation for its end point until all points from the list have been processed.

I suppose you could as well use a PointAnimationUsingKeyFrames, and add a new segment each time the animation reaches a key point, and then increment pointIndex so that the animation starts moving the new end point. That will save you the trouble of handling the Completed event.

I hope that helps,
Stoyan

Title: Re: Animation
Post by pwdparis on May 12th, 2011 at 3:27pm
Not quite sure how to get the various segments out of the link, since the segment-related functions I can find for the DiagramLink class don't appear to return this data?

Thanks,

Mark

Title: Re: Animation
Post by Stoyo on May 12th, 2011 at 5:30pm
You can get and set the segment end points through link.ControlPoints. Initially you can get the ControlPoints values assigned by the control and set them up as key points for the animation, then reset ControlPoints so that the link is a single segment with coinciding end points at the position of ControlPoints[0]. While the animation proceeds, assign the key points through which the animation already passed + the current animation value to ControlPoints and call UpdateFromPoints().

I hope that helps,
Stoyan

Title: Re: Animation
Post by davidl on Jan 8th, 2017 at 5:35pm
Hi Stoyan,

I'm having trouble getting this example to work, and I think it is because I don't have the correct point locations of the Link.

Can you provide an example that shows how to get the starting and end point locations of an existing link and pass them into the animate function?

-David

Title: Re: Animation
Post by Slavcho on Jan 9th, 2017 at 1:52pm
Hi there,

You can find current start and end coordinates of a link by checking its StartPoint and EndPoint properties, which are shortcuts to the first and last elements of ControlPoints. For example this LinkCreated handler code retraces the link's path -

[code]
void OnLinkCreated(object sender, LinkEventArgs e)
{
     var link = e.Link;
     new LinkAnimator(link, 1).
           Animate(
                 link.StartPoint, link.EndPoint);
}[/code]

https://mindfusion.eu/_samples/AnimateLinks.zip

As described in thread above this class animates a single control point, so in current form it's good for single-segment links. Let me know if you need an example with PointAnimationUsingKeyFrames which would let you animate multiple segments.

Regards,
Slavcho
Mindfusion

Title: Re: Animation
Post by davidl on Jan 13th, 2017 at 2:10pm
Thank you Slavcho, the example in the ZIP file really helps.

Do you know if there is any way to do this in a Windows Forms application?

Title: Re: Animation
Post by Slavcho on Jan 13th, 2017 at 2:46pm
It should be easy to create a custom Windows Forms PointAnimation class similar to Silverlight's standard one - using either a timer or a thread that adds directional vector to current point. If you want sample code for that, please post in the Windows Forms forum board.

The MindFusion Forums » Powered by YaBB 2.6.11!
YaBB Forum Software © 2000-2024. All Rights Reserved.