About the Move a graphic along a path in ArcMap Sample
[C#]
MapGraphicKeyframe.cs
using System; using System.Windows.Forms; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using ESRI.ArcGIS.Animation; using ESRI.ArcGIS.ADF; using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.SystemUI; using ESRI.ArcGIS.Geometry; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Display; namespace AnimationDeveloperSamples { [Guid("B2263D65-7FAF-4118-A255-5B0D47E453EE")] [ClassInterface(ClassInterfaceType.None)] [ProgId("AnimationDeveloperSamples.MapGraphicKeyframe")] public class MapGraphicKeyframe:IAGKeyframe, IAGKeyframeUI { private ILongArray activeProps; private IAGAnimationType animType; private string name; private bool bObjectsNeedRefresh; private IPoint Position; private double Rotation; private double timeStamp; #region constructor public MapGraphicKeyframe() { activeProps = new LongArrayClass(); activeProps.Add(0); activeProps.Add(1); animType = new AnimationTypeMapGraphic(); name = ""; bObjectsNeedRefresh = false; Position = new PointClass(); Rotation = 0.0; timeStamp = 0.0; } #endregion #region IAGKeyframe members public ILongArray ActiveProperties { get { return activeProps; } set { activeProps = value; } } public IAGAnimationType AnimationType { get { return animType; } } public void Apply(IAGAnimationTrack pTrack, IAGAnimationContainer pContainer, object pObject) { IElement elem = (IElement) pObject; UpdateGraphicObject(elem,pContainer,pTrack,Position,Rotation); return; } public void CaptureProperties(IAGAnimationContainer pContainer, object pObject) { IElement elem = pObject as IElement; IActiveView view = pContainer.CurrentView as IActiveView; IGraphicsContainerSelect graphicsConSel = view as IGraphicsContainerSelect; IDisplay disp = view.ScreenDisplay as IDisplay; IEnvelope elemEnv = GetElementBound(elem,pContainer); if (elem.Geometry.GeometryType == esriGeometryType.esriGeometryPoint) { Position = elem.Geometry as IPoint; } else { IEnvelope elementEnvelope = elem.Geometry.Envelope; IArea elementArea = elementEnvelope as IArea; Position = elementArea.Centroid; } IElementProperties elemProps = (IElementProperties)elem; if(elemProps.CustomProperty!=null) Rotation = (double)elemProps.CustomProperty; } public void Interpolate(IAGAnimationTrack pTrack, IAGAnimationContainer pContainer, object pObject, int propertyIndex, double time, IAGKeyframe pNextKeyframe, IAGKeyframe pPrevKeyframe, IAGKeyframe pAfterNextKeyframe) { if (time < TimeStamp || time > pNextKeyframe.TimeStamp) return; IElement elem = (IElement)pObject; IPoint new_pos = new PointClass(); if (propertyIndex == 0) { double x1; double y1; IPoint nextPosition = (IPoint)pNextKeyframe.get_PropertyValue(0); double timeFactor; timeFactor = (time - TimeStamp) / (pNextKeyframe.TimeStamp - TimeStamp); //ignoring pPrevKeyframe and pAfterNextKeyframe x1 = Position.X * (1 - timeFactor) + nextPosition.X * timeFactor; y1 = Position.Y * (1 - timeFactor) + nextPosition.Y * timeFactor; new_pos.PutCoords(x1, y1); if (!(elem is ILineElement)) { MoveElement(elem, new_pos, pContainer); TracePath(elem, new_pos, pContainer, pTrack, this); bObjectsNeedRefresh = true; } } if (propertyIndex == 1) { //this property only applies to the point graphic if (!(elem is ILineElement)) { RotateElement(elem, Rotation, pContainer); bObjectsNeedRefresh = true; } } return; } public bool get_IsActiveProperty(int propIndex) { bool bIsActive = false; int count = activeProps.Count; for (int i = 0; i < count; i++) { long temp = activeProps.get_Element(i); if (temp == propIndex) bIsActive = true; } return bIsActive; } public void set_IsActiveProperty(int propIndex, bool pbIsActiveProp) { if (pbIsActiveProp) { if (get_IsActiveProperty(propIndex) == false) { activeProps.Add(propIndex); } } else { if (get_IsActiveProperty(propIndex) == true) { int i = 0; int count = activeProps.Count; for (i = 0; i < count; i++) { long temp = activeProps.get_Element(i); if (temp == propIndex) break; } activeProps.Remove(i); } } } public string Name { get { return name; } set { name = value; } } public bool ObjectNeedsRefresh { get { return bObjectsNeedRefresh; } } public object get_PropertyValue(int propIndex) { if (propIndex == 0) return (object)Position; else if (propIndex == 1) return (object)Rotation; else return null; } public void set_PropertyValue(int propIndex, object pValue) { if (propIndex == 0) Position = (IPoint)pValue; else if (propIndex == 1) Rotation = (Double)pValue; else return; } public void RefreshObject(IAGAnimationTrack pTrack, IAGAnimationContainer pContainer, object pObject) { RefreshGraphicObject((IElement)pObject, pContainer); } public double TimeStamp { get { return timeStamp; } set { timeStamp = value; } } #endregion #region IAGKeyframeUI members public string GetText(int propIndex, int columnIndex) { string text; text = null; switch (propIndex) { case 0: { if (columnIndex == 0) { text = System.Convert.ToString(Position.X); } if (columnIndex == 1) { text = System.Convert.ToString(Position.Y); } } break; case 1: text = System.Convert.ToString(Rotation); break; } return text; } public void SetText(int propIndex, int columnIndex, string text) { switch (propIndex) { case 0: { if (columnIndex == 0) { Position.X = System.Convert.ToDouble(text); } if (columnIndex == 1) { Position.Y = System.Convert.ToDouble(text); } } break; case 1: { Rotation = System.Convert.ToDouble(text); } break; } return; } #endregion #region private methods private void RotateElement(IElement elem, double new_angle, IAGAnimationContainer pContainer) { ITransform2D transform2D = elem as ITransform2D; IPoint rotateOrigin; if (elem.Geometry.GeometryType == esriGeometryType.esriGeometryPoint) { rotateOrigin = elem.Geometry as IPoint; } else { IEnvelope elementEnvelope = elem.Geometry.Envelope; IArea elementArea = elementEnvelope as IArea; rotateOrigin = elementArea.Centroid; } AddPropertySet(elem); IElementProperties prop = (IElementProperties)elem; //record the old properties IPropertySet propSet; propSet = (IPropertySet)prop.CustomProperty; double old_angle; old_angle = (double)propSet.GetProperty("Angle"); propSet.SetProperty("Angle", new_angle); //update old angle transform2D.Rotate(rotateOrigin, new_angle-old_angle); } private void TracePath(IElement elem, IPoint new_pos, IAGAnimationContainer pContainer, IAGAnimationTrack pTrack, IAGKeyframe pKeyframe) { IAGAnimationTrackExtensions trackExtensions = (IAGAnimationTrackExtensions)(pTrack); IMapGraphicTrackExtension graphicTrackExtension; if (trackExtensions.ExtensionCount == 0) //if there is no extension, add one { graphicTrackExtension = new MapGraphicTrackExtension(); trackExtensions.AddExtension(graphicTrackExtension); } else { graphicTrackExtension = (IMapGraphicTrackExtension)trackExtensions.get_Extension(0); } ILineElement path = graphicTrackExtension.TraceElement; bool showTrace = graphicTrackExtension.ShowTrace; if (!showTrace) { if (CheckGraphicExistance((IElement)path, pContainer)) { RemoveGraphicFromDisplay((IElement)path, pContainer); } return; } //Add the path to the graphic container if (!CheckGraphicExistance((IElement)path, pContainer)) { AddGraphicToDisplay((IElement)path, pContainer); } RecreateLineGeometry((IElement)path, pTrack, pKeyframe, new_pos); } private void AddGraphicToDisplay(IElement elem, IAGAnimationContainer animContainer) { IActiveView view = animContainer.CurrentView as IActiveView; IGraphicsContainer graphicsContainer = view as IGraphicsContainer; graphicsContainer.AddElement(elem, 0); elem.Activate(view.ScreenDisplay); } private void RemoveGraphicFromDisplay(IElement elem, IAGAnimationContainer animContainer) { IActiveView view = animContainer.CurrentView as IActiveView; IGraphicsContainer graphicsContainer = view as IGraphicsContainer; graphicsContainer.DeleteElement(elem); } private bool CheckGraphicExistance(IElement elem, IAGAnimationContainer animContainer) { IActiveView view = animContainer.CurrentView as IActiveView; IGraphicsContainer graphicsContainer = view as IGraphicsContainer; graphicsContainer.Reset(); bool exists = false; IElement temp = graphicsContainer.Next(); while (temp != null) { if (temp == elem) { exists = true; break; } temp = graphicsContainer.Next(); } return exists; } private void MoveElement(IElement elem, IPoint new_pos, IAGAnimationContainer pContainer) { ITransform2D transform2D = elem as ITransform2D; IPoint origin; if (elem.Geometry.GeometryType == esriGeometryType.esriGeometryPoint) { origin = elem.Geometry as IPoint; } else { IEnvelope elementEnvelope = elem.Geometry.Envelope; IArea elementArea = elementEnvelope as IArea; origin = elementArea.Centroid; } AddPropertySet(elem); IElementProperties prop = (IElementProperties)elem; //record the old properties IPropertySet propSet; propSet = (IPropertySet)prop.CustomProperty; IEnvelope oldEnv = GetElementBound(elem, pContainer); propSet.SetProperty("Envelope", oldEnv); transform2D.Move(new_pos.X - origin.X, new_pos.Y - origin.Y); } private void RecreateLineGeometry(IElement elem, IAGAnimationTrack pTrack, IAGKeyframe pKeyframe, IPoint new_pos) { IGeometry newGeometry = new PolylineClass(); IPointCollection newPointCol = (IPointCollection)newGeometry; IAGAnimationTrackKeyframes trackKeyframes = (IAGAnimationTrackKeyframes)pTrack; int tCount = trackKeyframes.KeyframeCount; object missing = Type.Missing; for (int i = 0; i < tCount; i++) { IAGKeyframe tempKeyframe = trackKeyframes.get_Keyframe(i); newPointCol.AddPoint((IPoint)tempKeyframe.get_PropertyValue(0), ref missing, ref missing); if ((IPoint)tempKeyframe.get_PropertyValue(0) == (IPoint)pKeyframe.get_PropertyValue(0)) break; } if (new_pos != null) newPointCol.AddPoint(new_pos, ref missing, ref missing); elem.Geometry = newGeometry; } private IEnvelope GetElementBound(IElement elem, IAGAnimationContainer pContainer) { IActiveView view = pContainer.CurrentView as IActiveView; IGraphicsContainerSelect graphicsContainerSelect = view as IGraphicsContainerSelect; IDisplay disp = view.ScreenDisplay as IDisplay; IEnvelope elementEnvelope = new EnvelopeClass(); elem.QueryBounds(disp, elementEnvelope); if (graphicsContainerSelect.ElementSelected(elem)) { elementEnvelope = elem.SelectionTracker.get_Bounds(disp); } return elementEnvelope; } private void UpdateGraphicObject(IElement elem, IAGAnimationContainer pContainer, IAGAnimationTrack pTrack, IPoint new_pos, double new_angle) { if (elem == null||new_pos==null) return; //invalidate parameter MoveElement(elem, new_pos, pContainer); RotateElement(elem, new_angle, pContainer); return; } private void AddPropertySet(IElement elem) { if (elem == null) return; //invalidate parameter IElementProperties prop = (IElementProperties)elem; //record the old properties IPropertySet propSet; if (prop.CustomProperty == null) { propSet = new PropertySetClass(); propSet.SetProperty("Envelope", null); propSet.SetProperty("Angle", 0.0); prop.CustomProperty = propSet; } } private void RefreshGraphicObject(IElement elem, IAGAnimationContainer pContainer) { IActiveView view = pContainer.CurrentView as IActiveView; IEnvelope elemEnv = GetElementBound(elem, pContainer); IEnvelope oldEnv = new EnvelopeClass(); IElementProperties2 elemProps2 = (IElementProperties2) elem; oldEnv = (IEnvelope) elemProps2.CustomProperty; IViewRefresh animRefresh = (IViewRefresh)view; if (oldEnv != null) { elemEnv.Union(oldEnv); } animRefresh.AnimationRefresh(esriViewDrawPhase.esriViewGraphics, elem, elemEnv); } #endregion } }
[Visual Basic .NET]
MapGraphicKeyframe.vb
Imports Microsoft.VisualBasic Imports System Imports System.Windows.Forms Imports System.Collections.Generic Imports System.Text Imports System.Runtime.InteropServices Imports ESRI.ArcGIS.Animation Imports ESRI.ArcGIS.ADF Imports ESRI.ArcGIS.Carto Imports ESRI.ArcGIS.Controls Imports ESRI.ArcGIS.esriSystem Imports ESRI.ArcGIS.SystemUI Imports ESRI.ArcGIS.Geometry Imports ESRI.ArcGIS.Geodatabase Imports ESRI.ArcGIS.Display <Guid("A9250243-7A16-4F8D-AA06-29F559ADA0C5"), ClassInterface(ClassInterfaceType.None), ProgId("AnimationDeveloperSamples.MapGraphicKeyframe")> _ Public Class MapGraphicKeyframe : Implements IAGKeyframe, IAGKeyframeUI Private activeProps As ILongArray Private animType As IAGAnimationType Private name_Renamed As String Private bObjectsNeedRefresh As Boolean Private Position As IPoint Private Rotation As Double Private timeStamp_Renamed As Double #Region "constructor" Public Sub New() activeProps = New LongArrayClass() activeProps.Add(0) activeProps.Add(1) animType = New AnimationTypeMapGraphic() name_Renamed = "" bObjectsNeedRefresh = False Position = New PointClass() Rotation = 0.0 timeStamp_Renamed = 0.0 End Sub #End Region #Region "IAGKeyframe members" Public Property ActiveProperties() As ILongArray Implements IAGKeyframe.ActiveProperties Get Return activeProps End Get Set(ByVal value As ILongArray) activeProps = value End Set End Property Public ReadOnly Property AnimationType() As IAGAnimationType Implements IAGKeyframe.AnimationType Get Return animType End Get End Property Public Sub Apply(ByVal pTrack As IAGAnimationTrack, ByVal pContainer As IAGAnimationContainer, ByVal pObject As Object) Implements IAGKeyframe.Apply Dim elem As IElement = CType(pObject, IElement) UpdateGraphicObject(elem, pContainer, pTrack, Position, Rotation) Return End Sub Public Sub CaptureProperties(ByVal pContainer As IAGAnimationContainer, ByVal pObject As Object) Implements IAGKeyframe.CaptureProperties Dim elem As IElement = TryCast(pObject, IElement) Dim view As IActiveView = TryCast(pContainer.CurrentView, IActiveView) Dim graphicsConSel As IGraphicsContainerSelect = TryCast(view, IGraphicsContainerSelect) Dim disp As IDisplay = TryCast(view.ScreenDisplay, IDisplay) Dim elemEnv As IEnvelope = GetElementBound(elem, pContainer) If elem.Geometry.GeometryType = esriGeometryType.esriGeometryPoint Then Position = TryCast(elem.Geometry, IPoint) Else Dim elementEnvelope As IEnvelope = elem.Geometry.Envelope Dim elementArea As IArea = TryCast(elementEnvelope, IArea) Position = elementArea.Centroid End If Dim elemProps As IElementProperties = CType(elem, IElementProperties) If Not elemProps.CustomProperty Is Nothing Then Rotation = CDbl(elemProps.CustomProperty) End If End Sub Public Sub Interpolate(ByVal pTrack As IAGAnimationTrack, ByVal pContainer As IAGAnimationContainer, ByVal pObject As Object, ByVal propertyIndex As Integer, ByVal time As Double, ByVal pNextKeyframe As IAGKeyframe, ByVal pPrevKeyframe As IAGKeyframe, ByVal pAfterNextKeyframe As IAGKeyframe) Implements IAGKeyframe.Interpolate If time < TimeStamp OrElse time > pNextKeyframe.TimeStamp Then Return End If Dim elem As IElement = CType(pObject, IElement) Dim new_pos As IPoint = New PointClass() If propertyIndex = 0 Then Dim x1 As Double Dim y1 As Double Dim nextPosition As IPoint = CType(pNextKeyframe.PropertyValue(0), IPoint) Dim timeFactor As Double timeFactor = (time - TimeStamp) / (pNextKeyframe.TimeStamp - TimeStamp) 'ignoring pPrevKeyframe and pAfterNextKeyframe x1 = Position.X * (1 - timeFactor) + nextPosition.X * timeFactor y1 = Position.Y * (1 - timeFactor) + nextPosition.Y * timeFactor new_pos.PutCoords(x1, y1) If Not (TypeOf elem Is ILineElement) Then MoveElement(elem, new_pos, pContainer) TracePath(elem, new_pos, pContainer, pTrack, Me) bObjectsNeedRefresh = True End If End If If propertyIndex = 1 Then 'this property only applies to the point graphic If Not (TypeOf elem Is ILineElement) Then RotateElement(elem, Rotation, pContainer) bObjectsNeedRefresh = True End If End If Return End Sub Public Property IsActiveProperty(ByVal propIndex As Integer) As Boolean Implements IAGKeyframe.IsActiveProperty Get Dim bIsActive As Boolean = False Dim count As Integer = activeProps.Count Dim i As Integer = 0 Do While i < count Dim temp As Long = activeProps.Element(i) If temp = propIndex Then bIsActive = True End If i += 1 Loop Return bIsActive End Get Set(ByVal value As Boolean) If value Then If IsActiveProperty(propIndex) = False Then activeProps.Add(propIndex) End If Else If IsActiveProperty(propIndex) = True Then Dim i As Integer = 0 Dim count As Integer = activeProps.Count i = 0 Do While i < count Dim temp As Long = activeProps.Element(i) If temp = propIndex Then Exit Do End If i += 1 Loop activeProps.Remove(i) End If End If End Set End Property Public Property Name() As String Implements IAGKeyframe.Name Get Return name_Renamed End Get Set(ByVal value As String) name_Renamed = value End Set End Property Public ReadOnly Property ObjectNeedsRefresh() As Boolean Implements IAGKeyframe.ObjectNeedsRefresh Get Return bObjectsNeedRefresh End Get End Property Public Property PropertyValue(ByVal propIndex As Integer) As Object Implements IAGKeyframe.PropertyValue Get If propIndex = 0 Then Return CObj(Position) ElseIf propIndex = 1 Then Return CObj(Rotation) Else Return Nothing End If End Get Set(ByVal value As Object) If propIndex = 0 Then Position = CType(value, IPoint) ElseIf propIndex = 1 Then Rotation = CType(value, Double) Else Return End If End Set End Property Public Sub RefreshObject(ByVal pTrack As IAGAnimationTrack, ByVal pContainer As IAGAnimationContainer, ByVal pObject As Object) Implements IAGKeyframe.RefreshObject RefreshGraphicObject(CType(pObject, IElement), pContainer) End Sub Public Property TimeStamp() As Double Implements IAGKeyframe.TimeStamp Get Return timeStamp_Renamed End Get Set(ByVal value As Double) timeStamp_Renamed = value End Set End Property #End Region #Region "IAGKeyframeUI members" Public Function GetText(ByVal propIndex As Integer, ByVal columnIndex As Integer) As String Implements IAGKeyframeUI.GetText Dim text As String text = Nothing Select Case propIndex Case 0 If columnIndex = 0 Then text = System.Convert.ToString(Position.X) End If If columnIndex = 1 Then text = System.Convert.ToString(Position.Y) End If Case 1 text = System.Convert.ToString(Rotation) End Select Return text End Function Public Sub SetText(ByVal propIndex As Integer, ByVal columnIndex As Integer, ByVal text As String) Implements IAGKeyframeUI.SetText Select Case propIndex Case 0 If columnIndex = 0 Then Position.X = System.Convert.ToDouble(text) End If If columnIndex = 1 Then Position.Y = System.Convert.ToDouble(text) End If Case 1 Rotation = System.Convert.ToDouble(text) End Select Return End Sub #End Region #Region "private methods" Private Sub RotateElement(ByVal elem As IElement, ByVal new_angle As Double, ByVal pContainer As IAGAnimationContainer) Dim transform2D As ITransform2D = TryCast(elem, ITransform2D) Dim rotateOrigin As IPoint If elem.Geometry.GeometryType = esriGeometryType.esriGeometryPoint Then rotateOrigin = TryCast(elem.Geometry, IPoint) Else Dim elementEnvelope As IEnvelope = elem.Geometry.Envelope Dim elementArea As IArea = TryCast(elementEnvelope, IArea) rotateOrigin = elementArea.Centroid End If AddPropertySet(elem) Dim prop As IElementProperties = CType(elem, IElementProperties) 'record the old properties Dim propSet As IPropertySet propSet = CType(prop.CustomProperty, IPropertySet) Dim old_angle As Double old_angle = CDbl(propSet.GetProperty("Angle")) propSet.SetProperty("Angle", new_angle) 'update old angle transform2D.Rotate(rotateOrigin, new_angle - old_angle) End Sub Private Sub TracePath(ByVal elem As IElement, ByVal new_pos As IPoint, ByVal pContainer As IAGAnimationContainer, ByVal pTrack As IAGAnimationTrack, ByVal pKeyframe As IAGKeyframe) Dim trackExtensions As IAGAnimationTrackExtensions = CType(pTrack, IAGAnimationTrackExtensions) Dim graphicTrackExtension As IMapGraphicTrackExtension If trackExtensions.ExtensionCount = 0 Then 'if there is no extension, add one graphicTrackExtension = New MapGraphicTrackExtension() trackExtensions.AddExtension(graphicTrackExtension) Else graphicTrackExtension = CType(trackExtensions.Extension(0), IMapGraphicTrackExtension) End If Dim path As ILineElement = graphicTrackExtension.TraceElement Dim showTrace As Boolean = graphicTrackExtension.ShowTrace If (Not showTrace) Then If CheckGraphicExistance(CType(path, IElement), pContainer) Then RemoveGraphicFromDisplay(CType(path, IElement), pContainer) End If Return End If 'Add the path to the graphic container If (Not CheckGraphicExistance(CType(path, IElement), pContainer)) Then AddGraphicToDisplay(CType(path, IElement), pContainer) End If RecreateLineGeometry(CType(path, IElement), pTrack, pKeyframe, new_pos) End Sub Private Sub AddGraphicToDisplay(ByVal elem As IElement, ByVal animContainer As IAGAnimationContainer) Dim view As IActiveView = TryCast(animContainer.CurrentView, IActiveView) Dim graphicsContainer As IGraphicsContainer = TryCast(view, IGraphicsContainer) graphicsContainer.AddElement(elem, 0) elem.Activate(view.ScreenDisplay) End Sub Private Sub RemoveGraphicFromDisplay(ByVal elem As IElement, ByVal animContainer As IAGAnimationContainer) Dim view As IActiveView = TryCast(animContainer.CurrentView, IActiveView) Dim graphicsContainer As IGraphicsContainer = TryCast(view, IGraphicsContainer) graphicsContainer.DeleteElement(elem) End Sub Private Function CheckGraphicExistance(ByVal elem As IElement, ByVal animContainer As IAGAnimationContainer) As Boolean Dim view As IActiveView = TryCast(animContainer.CurrentView, IActiveView) Dim graphicsContainer As IGraphicsContainer = TryCast(view, IGraphicsContainer) graphicsContainer.Reset() Dim exists As Boolean = False Dim temp As IElement = graphicsContainer.Next() Do While Not temp Is Nothing If temp Is elem Then exists = True Exit Do End If temp = graphicsContainer.Next() Loop Return exists End Function Private Sub MoveElement(ByVal elem As IElement, ByVal new_pos As IPoint, ByVal pContainer As IAGAnimationContainer) Dim transform2D As ITransform2D = TryCast(elem, ITransform2D) Dim origin As IPoint If elem.Geometry.GeometryType = esriGeometryType.esriGeometryPoint Then origin = TryCast(elem.Geometry, IPoint) Else Dim elementEnvelope As IEnvelope = elem.Geometry.Envelope Dim elementArea As IArea = TryCast(elementEnvelope, IArea) origin = elementArea.Centroid End If AddPropertySet(elem) Dim prop As IElementProperties = CType(elem, IElementProperties) 'record the old properties Dim propSet As IPropertySet propSet = CType(prop.CustomProperty, IPropertySet) Dim oldEnv As IEnvelope = GetElementBound(elem, pContainer) propSet.SetProperty("Envelope", oldEnv) transform2D.Move(new_pos.X - origin.X, new_pos.Y - origin.Y) End Sub Private Sub RecreateLineGeometry(ByVal elem As IElement, ByVal pTrack As IAGAnimationTrack, ByVal pKeyframe As IAGKeyframe, ByVal new_pos As IPoint) Dim newGeometry As IGeometry = New PolylineClass() Dim newPointCol As IPointCollection = CType(newGeometry, IPointCollection) Dim trackKeyframes As IAGAnimationTrackKeyframes = CType(pTrack, IAGAnimationTrackKeyframes) Dim tCount As Integer = trackKeyframes.KeyframeCount Dim missing As Object = Type.Missing Dim i As Integer = 0 Do While i < tCount Dim tempKeyframe As IAGKeyframe = trackKeyframes.Keyframe(i) newPointCol.AddPoint(CType(tempKeyframe.PropertyValue(0), IPoint), missing, missing) If CType(tempKeyframe.PropertyValue(0), IPoint) Is CType(pKeyframe.PropertyValue(0), IPoint) Then Exit Do End If i += 1 Loop If Not new_pos Is Nothing Then newPointCol.AddPoint(new_pos, missing, missing) End If elem.Geometry = newGeometry End Sub Private Function GetElementBound(ByVal elem As IElement, ByVal pContainer As IAGAnimationContainer) As IEnvelope Dim view As IActiveView = TryCast(pContainer.CurrentView, IActiveView) Dim graphicsContainerSelect As IGraphicsContainerSelect = TryCast(view, IGraphicsContainerSelect) Dim disp As IDisplay = TryCast(view.ScreenDisplay, IDisplay) Dim elementEnvelope As IEnvelope = New EnvelopeClass() elem.QueryBounds(disp, elementEnvelope) If graphicsContainerSelect.ElementSelected(elem) Then elementEnvelope = elem.SelectionTracker.Bounds(disp) End If Return elementEnvelope End Function Private Sub UpdateGraphicObject(ByVal elem As IElement, ByVal pContainer As IAGAnimationContainer, ByVal pTrack As IAGAnimationTrack, ByVal new_pos As IPoint, ByVal new_angle As Double) If elem Is Nothing OrElse new_pos Is Nothing Then Return 'invalidate parameter End If MoveElement(elem, new_pos, pContainer) RotateElement(elem, new_angle, pContainer) Return End Sub Private Sub AddPropertySet(ByVal elem As IElement) If elem Is Nothing Then Return 'invalidate parameter End If Dim prop As IElementProperties = CType(elem, IElementProperties) 'record the old properties Dim propSet As IPropertySet If prop.CustomProperty Is Nothing Then propSet = New PropertySetClass() propSet.SetProperty("Envelope", Nothing) propSet.SetProperty("Angle", 0.0) prop.CustomProperty = propSet End If End Sub Private Sub RefreshGraphicObject(ByVal elem As IElement, ByVal pContainer As IAGAnimationContainer) Dim view As IActiveView = TryCast(pContainer.CurrentView, IActiveView) Dim elemEnv As IEnvelope = GetElementBound(elem, pContainer) Dim oldEnv As IEnvelope = New EnvelopeClass() Dim elemProps2 As IElementProperties2 = CType(elem, IElementProperties2) oldEnv = CType(elemProps2.CustomProperty, IEnvelope) Dim animRefresh As IViewRefresh = CType(view, IViewRefresh) If Not oldEnv Is Nothing Then elemEnv.Union(oldEnv) End If animRefresh.AnimationRefresh(esriViewDrawPhase.esriViewGraphics, elem, elemEnv) End Sub #End Region End Class