Skip to content

Commit e66ab77

Browse files
committed
MotionPath documented
1 parent c7a53eb commit e66ab77

File tree

12 files changed

+291
-36
lines changed

12 files changed

+291
-36
lines changed

CustomControls/Controls/MotionPath.cs

+51-32
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public class MotionPath : ContentControl
3838
private readonly Storyboard _storyboard = new Storyboard();
3939

4040
#endregion
41-
41+
4242
public new double Width
4343
{
4444
get { return base.Width; }
@@ -138,23 +138,27 @@ public MotionPath()
138138

139139
static MotionPath()
140140
{
141+
AutoRewindProperty = DependencyProperty.Register("AutoRewind", typeof(bool), typeof(MotionPath), new PropertyMetadata(false));
142+
141143
CurrentPointProperty = DependencyProperty.Register("CurrentPoint", typeof(Point), typeof(MotionPath), new PropertyMetadata(new Point(double.NaN, double.NaN)));
142144

143-
AutoRewindProperty = DependencyProperty.Register("AutoRewind", typeof(bool), typeof(MotionPath), new PropertyMetadata(false));
145+
CurrentTimeProperty = DependencyProperty.Register("CurrentTime", typeof(TimeSpan), typeof(MotionPath), new PropertyMetadata(default(TimeSpan)));
144146

145147
DurationProperty = DependencyProperty.Register("Duration", typeof(TimeSpan), typeof(MotionPath), new PropertyMetadata(TimeSpan.FromSeconds(1)));
146148

147-
StateProperty = DependencyProperty.Register("State", typeof(AnimationState), typeof(MotionPath), new PropertyMetadata(AnimationState.Ready,
148-
delegate (DependencyObject o, DependencyPropertyChangedEventArgs e)
149-
{
150-
var sender = (MotionPath)o;
151-
var val = (AnimationState)e.NewValue;
149+
EasingFunctionProperty = DependencyProperty.Register("EasingFunction", typeof(EasingFunctionBase), typeof(MotionPath), new PropertyMetadata(default(EasingFunctionBase)));
152150

153-
sender.StateChanged?.Invoke(sender, val);
154-
if (val == AnimationState.Complete)
155-
sender.Completed?.Invoke(sender);
156-
}));
151+
LineRelativeEndProperty = DependencyProperty.Register("LineRelativeEnd", typeof(Point), typeof(MotionPath),
152+
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
157153

154+
LineAbsoluteStartProperty = DependencyProperty.Register("LineAbsoluteStart", typeof(Point), typeof(MotionPath),
155+
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
156+
157+
LineAbsoluteEndProperty = DependencyProperty.Register("LineAbsoluteEnd", typeof(Point), typeof(MotionPath),
158+
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
159+
160+
OrientToPathProperty = DependencyProperty.Register("OrientToPath", typeof(bool), typeof(MotionPath), new PropertyMetadata(default(bool)));
161+
158162
ProgressProperty = DependencyProperty.Register("Progress", typeof(double), typeof(MotionPath), new PropertyMetadata(0.0,
159163
delegate (DependencyObject o, DependencyPropertyChangedEventArgs e)
160164
{
@@ -169,22 +173,18 @@ static MotionPath()
169173
sender.UpdatePathData(data);
170174
}));
171175

172-
LineAbsoluteStartProperty = DependencyProperty.Register("LineAbsoluteStart", typeof(Point), typeof(MotionPath),
173-
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
174-
175-
LineAbsoluteEndProperty = DependencyProperty.Register("LineAbsoluteEnd", typeof(Point), typeof(MotionPath),
176-
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
177-
178-
LineRelativeEndProperty = DependencyProperty.Register("LineRelativeEnd", typeof(Point), typeof(MotionPath),
179-
new PropertyMetadata(new Point(double.NaN, double.NaN), RefreshCalculations));
180-
181-
PathVisibilityProperty = DependencyProperty.Register("PathVisibility", typeof(Visibility), typeof(MotionPath), new PropertyMetadata(default(Visibility)));
182-
183-
CurrentTimeProperty = DependencyProperty.Register("CurrentTime", typeof(TimeSpan), typeof(MotionPath), new PropertyMetadata(default(TimeSpan)));
184-
185-
OrientToPathProperty = DependencyProperty.Register("OrientToPath", typeof(bool), typeof(MotionPath), new PropertyMetadata(default(bool)));
186-
187-
EasingFunctionProperty = DependencyProperty.Register("EasingFunction", typeof(EasingFunctionBase), typeof(MotionPath), new PropertyMetadata(default(EasingFunctionBase)));
176+
PathVisibilityProperty = DependencyProperty.Register("PathVisibility", typeof(Visibility), typeof(MotionPath), new PropertyMetadata(default(Visibility)));
177+
178+
StateProperty = DependencyProperty.Register("State", typeof(AnimationState), typeof(MotionPath), new PropertyMetadata(AnimationState.Ready,
179+
delegate (DependencyObject o, DependencyPropertyChangedEventArgs e)
180+
{
181+
var sender = (MotionPath)o;
182+
var val = (AnimationState)e.NewValue;
183+
184+
sender.StateChanged?.Invoke(sender, val);
185+
if (val == AnimationState.Complete)
186+
sender.Completed?.Invoke(sender);
187+
}));
188188
}
189189

190190
private static void RefreshCalculations(DependencyObject o, DependencyPropertyChangedEventArgs e)
@@ -203,17 +203,21 @@ private static void RefreshCalculations(DependencyObject o, DependencyPropertyCh
203203
public delegate void StateChangedEventHandler(object sender, AnimationState state);
204204
public delegate void EventHandler(object sender);
205205
/// <summary>
206-
/// Raised when state is ready and we are starting a new animation
206+
/// Occurs when state is ready and we are starting a new animation
207207
/// </summary>
208208
public event CancelEventHandler Starting;
209209
/// <summary>
210-
/// Raising when a new animation starts
210+
/// Occurs when a new animation starts
211211
/// </summary>
212212
public event EventHandler Started;
213213
/// <summary>
214-
/// Raising when an animation completes
214+
/// Occurs when an animation completes
215215
/// </summary>
216216
public event EventHandler Completed;
217+
218+
/// <summary>
219+
/// Occurs when animation state changes.
220+
/// </summary>
217221
public event StateChangedEventHandler StateChanged;
218222
#endregion
219223

@@ -262,12 +266,19 @@ private static void RefreshCalculations(DependencyObject o, DependencyPropertyCh
262266

263267
#region public methods
264268

269+
/// <summary>
270+
/// Starts the animation
271+
/// </summary>
265272
public void Start()
266273
{
267274
TryStart();
268275
Started?.Invoke(this);
269276
}
270277

278+
/// <summary>
279+
/// Starts the animation asynchronously
280+
/// </summary>
281+
/// <returns></returns>
271282
public async Task StartAsync()
272283
{
273284
await Task.Run(delegate
@@ -340,7 +351,7 @@ private void StartProgressAnimation()
340351
});
341352
}
342353

343-
if (Path == null || true)
354+
if (Path == null )
344355
{
345356
CalculateLineMovement();
346357
_initialContentPoint = GetChildAbsolutePoint();
@@ -356,6 +367,9 @@ private void StartProgressAnimation()
356367
_storyboard.Begin();
357368
}
358369

370+
/// <summary>
371+
/// Resets current animation and child position
372+
/// </summary>
359373
public void Reset()
360374
{
361375
if (State != AnimationState.Ready)
@@ -370,6 +384,9 @@ public void Reset()
370384
CalculateLineMovement();
371385
}
372386

387+
/// <summary>
388+
/// Rewinds the animation when playing
389+
/// </summary>
373390
public void RewindNow()
374391
{
375392
if (AutoRewind)
@@ -383,7 +400,9 @@ public void RewindNow()
383400
}
384401
}
385402

386-
403+
/// <summary>
404+
/// Pauses the animation
405+
/// </summary>
387406
public void Pause()
388407
{
389408
if (State == AnimationState.Running || State == AnimationState.Rewinding)
-18.5 KB
Loading
65 KB
Loading
197 KB
Loading

Documentation/layoutPathUG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# Layout Path
1+
# Layout Path ![layoutPath](images/layoutPathExample.gif)
22
A control used for placing / animating UIElements along a path.
33

4-
![inner](images/layoutPathExample.gif)
4+
55

66
It provides some usefull options such as rotation / translation smoothing, start / end behavior and more.
77

Documentation/motionPathUG.md

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Motion Path
2+
A control used for moving an element by specifying coordinates or a path geometry.
3+
![motionPath](images/motionPathExample.gif)
4+
5+
#### Declaration / Instantiation
6+
In order to start using `MotionPath`, you must specify motion coordinates or the `Path` geometry where child will be translated.
7+
8+
'MotionPath' contains a default constructor, so you can declare it as follows:
9+
###### C#:
10+
```cs
11+
MotionPath mp = new MotionPath();
12+
mp.Content = new TextBlock() { Text = "A" };
13+
mp.LineAbsoluteEnd = new Point(0, 0);
14+
```
15+
###### Xaml:
16+
```xml
17+
<controls:MotionPath LineAbsoluteEnd="0,0">
18+
<TextBlock Text="A" />
19+
</controls:MotionPath>
20+
```
21+
22+
**Important note:** All coordinates has a Point with `X = Y = double.NaN` by default. So, specifying `LineAbsoluteEnd=Point(0,0)`
23+
makes MotionPath to move child to 0,0 position.
24+
25+
If you wish to clear this point, set `LineAbsoluteEnd=Point(double.NaN,double.NaN)`
26+
27+
#### Properties
28+
29+
Properties of `MotionPath` control:
30+
31+
| Property | Description |
32+
| :------- | :---------- |
33+
| `AutoRewind` | Set to true if you wish your animation to auto rewind. |
34+
| `CurrentPoint` | Gets the current point of element. |
35+
| `CurrentTime` | Gets current animation time. |
36+
| `Duration` | The duration of animation. |
37+
| `EasingFunction` | The easing function of the animation. |
38+
| `LineRelativeEnd` | The animation line relative end point. |
39+
| `LineAbsoluteStart` | The animation absolute start point. |
40+
| `LineAbsoluteEndProperty` | The animation line absolute end point. Specifying this will make `MotionPath` to ignore `LineRelativeEnd` point. |
41+
| `OrientToPath` | Set true if you want the child to rotate in order to follow animation orientation. |
42+
| `Progress` | Current progress of animation |
43+
| `Path` | Set `Path` if you wish your child to move over it. Setting `Path` will make `MotionPath` to ignore all specified points. |
44+
| `State` | The current state of animation (`Ready`, `Running`, `Complete`, `Rewinding`, `Paused`) |
45+
46+
#### Methods
47+
The following methods are available in `MotionPath`:
48+
49+
| Method | Description |
50+
| :------- | :---------- |
51+
| void Start() | Starts the animation. |
52+
| async Task StartAsync() | Starts the animation asynchronously. |
53+
| void Reset() | Resets current animation and child position. |
54+
| void RewindNow() | Rewinds the animation when playing. |
55+
| void Pause() | Pauses the animation. |
56+
57+
#### Events
58+
The following events are available in `MotionPath`:
59+
60+
| Event | Description |
61+
| :------- | :---------- |
62+
| Starting | Cancelable event that occurs when state is ready and we are starting a new animation. |
63+
| Started | Occurs when a new animation starts. |
64+
| Completed | Occurs when an animation completes. |
65+
| StateChanged | Occurs when animation state changes. |
66+
67+
#### FAQ
68+
**ViewBox detected. Please specify control width and height.** <br/>
69+
Because `ViewBox` causes problems when calculating point coordinates, when you want to have a `MotionPath` element inside a `ViewBox`,
70+
you have to explicitly specify MotionPath Width and Height values. This limitation does not apply when you are using a `Path` geometry.

README.md

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@
44
### Extended Path Geometry
55
A class, extending current windows 10 PathGeometry class for providing missing functionality ([user guide](Documentation/extendedPathGeometryUG.md)).
66

7-
### Layout Path
7+
### Layout Path
88
A control used for placing / animating UIElements along a path ([user guide](Documentation/layoutPathUG.md)).
99

10+
11+
![layoutPath](Documentation/images/layoutPathExample.gif)
12+
1013
### Motion Path
11-
A control used for moving an element over a path or by specifying destination coordinates
14+
A control used for moving an element by specifying coordinates or a path geometry.
1215
([user guide](Documentation/motionPathUG.md)).
16+
![layoutPath](Documentation/images/motionPathExample.gif)
17+
18+

SampleProject/Assets/Thumbs/mp3.png

9.51 KB
Loading

SampleProject/SampleProject.csproj

+8
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@
131131
<DependentUpon>MainPage.xaml</DependentUpon>
132132
</Compile>
133133
<Compile Include="Properties\AssemblyInfo.cs" />
134+
<Compile Include="Views\MotionPathSamples\MotionPathAllCases.xaml.cs">
135+
<DependentUpon>MotionPathAllCases.xaml</DependentUpon>
136+
</Compile>
134137
<Compile Include="Views\MotionPathSamples\MotionPathBehaviorsChildUC.xaml.cs">
135138
<DependentUpon>MotionPathBehaviorsChildUC.xaml</DependentUpon>
136139
</Compile>
@@ -154,6 +157,7 @@
154157
<Content Include="Assets\Thumbs\lp3.png" />
155158
<Content Include="Assets\Thumbs\lp4.png" />
156159
<Content Include="Assets\Thumbs\lp5.png" />
160+
<Content Include="Assets\Thumbs\mp3.png" />
157161
<Content Include="Assets\Thumbs\mp1.png" />
158162
<Content Include="Assets\Thumbs\mp2.png" />
159163
<Content Include="Properties\Default.rd.xml" />
@@ -206,6 +210,10 @@
206210
<Generator>MSBuild:Compile</Generator>
207211
<SubType>Designer</SubType>
208212
</Page>
213+
<Page Include="Views\MotionPathSamples\MotionPathAllCases.xaml">
214+
<SubType>Designer</SubType>
215+
<Generator>MSBuild:Compile</Generator>
216+
</Page>
209217
<Page Include="Views\MotionPathSamples\MotionPathBehaviorsChildUC.xaml">
210218
<SubType>Designer</SubType>
211219
<Generator>MSBuild:Compile</Generator>

SampleProject/ViewModels/MainPageVM.cs

+6
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ public class MainPageVM
6363
Description = "Manipulate all properties of MotionPath control.",
6464
ThumbnailUri = new Uri("ms-appx:///Assets/Thumbs/mp1.png", UriKind.RelativeOrAbsolute),
6565
Command = new DelegateCommand(delegate { App.Frame.Navigate(typeof(MotionPathPage)); })
66+
}, new TileModel()
67+
{
68+
Title = "All cases sample",
69+
Description = "A sample containing all possible property combinations for MotionPath.",
70+
ThumbnailUri = new Uri("ms-appx:///Assets/Thumbs/mp3.png", UriKind.RelativeOrAbsolute),
71+
Command = new DelegateCommand(delegate { App.Frame.Navigate(typeof(MotionPathAllCases)); })
6672
},
6773
new TileModel()
6874
{

0 commit comments

Comments
 (0)