Click here to Skip to main content
15,885,757 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I need to animate UIElements through a path, in steps. The case is: simulate a manufacturing line, that advances animated objects but stops at discrete positions. One path must be a circle and the other a closed path that looks like a tall zero.

The first solution I thought of was using DoubleAnimationUsingPath inside a Storyboard. This is great for any path. The problem is I can't find a way to make advancements in regular steps. There's PauseStoryboard and ResumeStoryboard in Animation class, but how can I call them when, let's say 1/10th (let's suppose 10 steps) of the path has been done?

For something like that, PointAnimationUsingKeyFrames looks like the solution, but I can't find a simple way to implement it with keyframes.

Any suggestions? Thanks in advance.
Posted
Updated 31-Oct-11 8:42am
v3
Comments
hzawary 31-Oct-11 14:07pm    
I think that you can use several keyframes on regular steps in your time-line and use hold-in function or look like it for skip, resume, etc from keyframes;)
Sergey Alexandrovich Kryukov 31-Oct-11 16:35pm    
Good question and also: WPF is a good choice for simulation of manufacturing process, so I voted 5 for the question.
Good luck,
--SA

You can divide your path to some little pathes and, use DoubleAnimationUsingPath for each little path. For pausing after each step, you can set the BeginTime property of the animations appropriately.


For example, see the following Grid:


XML
<Grid>
    <Grid.Resources>
        <PathGeometry x:Key="path1" 
                        Figures="M0,0 L10,10 C20,100 30,10 60,120 C30,130 20,170 120,175" />
        <PathGeometry x:Key="path2" 
                        Figures="M120,175 C130,150 140,180 160,130 C170,150 175,170 190,120 C200,80 200,60 40,40" />
        <Storyboard x:Key="sb1">
            <DoubleAnimationUsingPath Storyboard.TargetName="rectTranslateTransform"
                                        Storyboard.TargetProperty="X"
                                        PathGeometry="{StaticResource path1}"
                                        Source="X" 
                                        Duration="0:0:2" />
            <DoubleAnimationUsingPath Storyboard.TargetName="rectTranslateTransform"
                                        Storyboard.TargetProperty="Y"
                                        PathGeometry="{StaticResource path1}"
                                        Source="Y" 
                                        Duration="0:0:2" />
            <DoubleAnimationUsingPath Storyboard.TargetName="rectTranslateTransform"
                                        Storyboard.TargetProperty="X"
                                        PathGeometry="{StaticResource path2}"
                                        Source="X" 
                                        Duration="0:0:2"
                                        BeginTime="0:0:3"/>
            <DoubleAnimationUsingPath Storyboard.TargetName="rectTranslateTransform"
                                        Storyboard.TargetProperty="Y"
                                        PathGeometry="{StaticResource path2}"
                                        Source="Y" 
                                        Duration="0:0:2"
                                        BeginTime="0:0:3"/>
        </Storyboard>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Path Data="M0,0 L10,10 C20,100 30,10 60,120 C30,130 20,170 120,175" Stroke="Green" StrokeThickness="2" />
    <Path Data="M120,175 C130,150 140,180 160,130 C170,150 175,170 190,120 C200,80 200,60 40,40" Stroke="Blue" StrokeThickness="2" />
    <Canvas>
        <Rectangle Fill="Red" 
                    Stroke="DarkRed" StrokeThickness="1"
                    Height="15" Width="15" 
                    Canvas.Left="0" Canvas.Top="0" 
                    x:Name="rect1" >
            <Rectangle.RenderTransform>
                <TranslateTransform x:Name="rectTranslateTransform"  />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas>
    <Button Content="Animate" Grid.Row="1">
        <Button.Triggers>
            <EventTrigger RoutedEvent="ButtonBase.Click">
                <BeginStoryboard Storyboard="{StaticResource sb1}" />
            </EventTrigger>
        </Button.Triggers>
    </Button>
</Grid>

In this Grid there is a Rectangle that is animated 2 seconds on the 1st part of the path, paused for 1 second and, animated 2 seconds on the 2nd part of the path.

 
Share this answer
 
Comments
Espen Harlinn 31-Oct-11 17:26pm    
Well answered Shmuel! My 5!
Shmuel Zang 1-Nov-11 4:21am    
Thank you Espen.
Nice solution, Shmuel. However, I must advance each step based on external events, so I can't set BeginTime from XAML nor code. So far, I'm working with multiple storyboards, each one representing one step. On each event, I call these storyboards sequentially. The solution is similar to yours, but with multiple Storyboards using 1 DoubleAnimationUsingPath for X and 1 DoubleAnimationUsingPath for Y. Lemme show you:
C#
<page>
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<grid>
    <grid.resources>
        <pathgeometry x:key="path1" xmlns:x="#unknown">
                        Figures="M0,0 L10,10 C20,100 30,10 60,120 C30,130 20,170 120,175" />
        <pathgeometry x:key="path2">
                        Figures="M120,175 C130,150 140,180 160,130 C170,150 175,170 190,120 C200,80 200,60 40,40" />
        <storyboard x:key="sb1">
            <doubleanimationusingpath storyboard.targetname="rectTranslateTransform">
                                        Storyboard.TargetProperty="X"
                                        PathGeometry="{StaticResource path1}"
                                        Source="X" 
                                        Duration="0:0:2" />
            <doubleanimationusingpath storyboard.targetname="rectTranslateTransform">
                                        Storyboard.TargetProperty="Y"
                                        PathGeometry="{StaticResource path1}"
                                        Source="Y" 
                                        Duration="0:0:2" />
        </doubleanimationusingpath></doubleanimationusingpath></storyboard>
       <storyboard x:key="sb2">
             <doubleanimationusingpath storyboard.targetname="rectTranslateTransform">
                                        Storyboard.TargetProperty="X"
                                        PathGeometry="{StaticResource path2}"
                                        Source="X" 
                                        Duration="0:0:2"/>
            <doubleanimationusingpath storyboard.targetname="rectTranslateTransform">
                                        Storyboard.TargetProperty="Y"
                                        PathGeometry="{StaticResource path2}"
                                        Source="Y" 
                                        Duration="0:0:2"/>
        </doubleanimationusingpath></doubleanimationusingpath></storyboard>
    </pathgeometry></pathgeometry></grid.resources>
    <grid.rowdefinitions>
        <rowdefinition />
        <rowdefinition height="Auto" />
        <rowdefinition height="Auto" />
    </grid.rowdefinitions>
    <path data="M0,0 L10,10 C20,100 30,10 60,120 C30,130 20,170 120,175" stroke="Green" strokethickness="2" />
    <path data="M120,175 C130,150 140,180 160,130 C170,150 175,170 190,120 C200,80 200,60 40,40" stroke="Blue" strokethickness="2" />
    <canvas>
        <rectangle fill="Red">
                    Stroke="DarkRed" StrokeThickness="1"
                    Height="15" Width="15" 
                    Canvas.Left="0" Canvas.Top="0" 
                    x:Name="rect1" >
            <rectangle.rendertransform>
                <translatetransform x:name="rectTranslateTransform" xmlns:x="#unknown" />
            </rectangle.rendertransform>
        </rectangle>
    </canvas>
    <button content="Animate 1" grid.row="1">
        <button.triggers>
            <eventtrigger routedevent="ButtonBase.Click">
                <beginstoryboard storyboard="{StaticResource sb1}" />
            </eventtrigger>
        </button.triggers>
    </button>
    <button content="Animate 2" grid.row="2">
        <button.triggers>
            <eventtrigger routedevent="ButtonBase.Click">
                <beginstoryboard storyboard="{StaticResource sb2}" />
            </eventtrigger>
        </button.triggers>
    </button>
</grid>
</page>


I preciate your work. I still think maybe there's a better solution. Time will tell.
 
Share this answer
 
Comments
GRF75 1-Nov-11 13:10pm    
Warning: Code copied from Kaxaml. Some errors were introduced unintentionally.
Sergey Alexandrovich Kryukov 23-Apr-13 14:28pm    
This is not an answer. You should have put in in the question using "Improve question".
—SA

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900