Skip to content

Commit 4708a1e

Browse files
committed
Add AnimationPath
1 parent 797ccf8 commit 4708a1e

9 files changed

Lines changed: 440 additions & 0 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ Install-Package DevWinUI.SourceGenerator
110110

111111
## 🕰️ History
112112

113+
### AnimationPath
114+
![AnimationPath](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/AnimationPath.gif)
115+
113116
### LiveGraph
114117
![LiveGraph](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/LiveGraph.gif)
115118

dev/DevWinUI.Gallery/App.xaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
<ResourceDictionary Source="Themes/Converters.xaml" />
1515
</ResourceDictionary.MergedDictionaries>
1616

17+
<x:String x:Key="GithubGeometry">M512 0C229.12 0 0 229.12 0 512c0 226.56 146.56 417.92 350.08 485.76 25.6 4.48 35.2-10.88 35.2-24.32 0-12.16-0.64-52.48-0.64-95.36-128.64 23.68-161.92-31.36-172.16-60.16-5.76-14.72-30.72-60.16-52.48-72.32-17.92-9.6-43.52-33.28-0.64-33.92 40.32-0.64 69.12 37.12 78.72 52.48 46.08 77.44 119.68 55.68 149.12 42.24 4.48-33.28 17.92-55.68 32.64-68.48-113.92-12.8-232.96-56.96-232.96-252.8 0-55.68 19.84-101.76 52.48-137.6-5.12-12.8-23.04-65.28 5.12-135.68 0 0 42.88-13.44 140.8 52.48 40.96-11.52 84.48-17.28 128-17.28 43.52 0 87.04 5.76 128 17.28 97.92-66.56 140.8-52.48 140.8-52.48 28.16 70.4 10.24 122.88 5.12 135.68 32.64 35.84 52.48 81.28 52.48 137.6 0 196.48-119.68 240-233.6 252.8 18.56 16 34.56 46.72 34.56 94.72 0 68.48-0.64 123.52-0.64 140.8 0 13.44 9.6 29.44 35.2 24.32A512.832 512.832 0 0 0 1024 512c0-282.88-229.12-512-512-512z</x:String>
1718
<x:String x:Key="CodeIcon">M4.86842 13.8679L9.66536 2.49276C9.8392 2.08037 10.3094 1.88921 10.7157 2.06577C11.0928 2.22973 11.2821 2.6531 11.168 3.04292L11.1362 3.13215L6.33927 14.5073C6.16537 14.9196 5.69514 15.1108 5.28897 14.9343C4.91182 14.7703 4.72253 14.3469 4.83665 13.957L4.86842 13.8679ZM0.234313 7.92378L3.43431 4.67484C3.74674 4.35764 4.25326 4.35764 4.56569 4.67484C4.85407 4.96764 4.87626 5.42838 4.63224 5.74701L4.56569 5.82353L1.93137 8.4982L4.56569 11.1728C4.8781 11.49 4.8781 12.0042 4.56569 12.3215C4.2773 12.6142 3.82351 12.6368 3.50968 12.3891L3.43431 12.3215L0.234313 9.07254C-0.0540715 8.77972 -0.0762554 8.31893 0.167761 8.00037L0.234313 7.92378ZM11.4337 4.67384C11.7221 4.38105 12.1758 4.35855 12.4897 4.60631L12.565 4.67389L15.7657 7.92386C16.0542 8.21675 16.0762 8.67778 15.8319 8.99635L15.7653 9.07286L12.5646 12.3183C12.252 12.6352 11.7454 12.6349 11.4333 12.3175C11.145 12.0245 11.1232 11.5637 11.3674 11.2453L11.434 11.1688L14.0683 8.49779L11.4336 5.82253C11.1212 5.50531 11.1212 4.99102 11.4337 4.67384Z</x:String>
1819
<x:String x:Key="GitHubIcon">M8.00662 0C3.57917 0 0 3.66665 0 8.2028C0 11.8288 2.29329 14.8981 5.4747 15.9844C5.87246 16.0661 6.01816 15.8079 6.01816 15.5908C6.01816 15.4006 6.00505 14.7488 6.00505 14.0696C3.7778 14.5586 3.31399 13.0918 3.31399 13.0918C2.95606 12.1411 2.42572 11.8968 2.42572 11.8968C1.69674 11.3943 2.47882 11.3943 2.47882 11.3943C3.28744 11.4486 3.71175 12.2363 3.71175 12.2363C4.42745 13.4856 5.58074 13.1326 6.04471 12.9153C6.11092 12.3856 6.32315 12.0189 6.5485 11.8153C4.77211 11.6251 2.90312 10.919 2.90312 7.76813C2.90312 6.8718 3.22107 6.13847 3.72486 5.56814C3.64538 5.36448 3.36693 4.52231 3.80451 3.39515C3.80451 3.39515 4.48055 3.17782 6.00488 4.23715C6.6575 4.05759 7.33054 3.96625 8.00662 3.96548C8.68266 3.96548 9.37181 4.06065 10.0082 4.23715C11.5327 3.17782 12.2087 3.39515 12.2087 3.39515C12.6463 4.52231 12.3677 5.36448 12.2882 5.56814C12.8053 6.13847 13.1101 6.8718 13.1101 7.76813C13.1101 10.919 11.2411 11.6115 9.45146 11.8153C9.74318 12.0733 9.99492 12.5621 9.99492 13.3363C9.99492 14.4363 9.98181 15.3191 9.98181 15.5906C9.98181 15.8079 10.1277 16.0661 10.5253 15.9846C13.7067 14.8979 16 11.8288 16 8.2028C16.0131 3.66665 12.4208 0 8.00662 0Z</x:String>
1920
<x:String x:Key="LoremText">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec vestibulum id ex nec malesuada. Duis tristique elit vitae justo lobortis, id fermentum tellus tristique. Duis in volutpat augue, a blandit enim. Suspendisse a dolor tempor, commodo metus sit amet, venenatis orci. Phasellus eu nulla in eros vestibulum pharetra ut at dolor. Praesent dapibus leo et neque egestas aliquam. Aenean ex erat, pretium eu tincidunt et, commodo quis lectus. Cras vitae sapien sed sem eleifend hendrerit. Suspendisse dignissim egestas neque vitae sodales. Nullam dapibus a ligula a pellentesque.</x:String>

dev/DevWinUI.Gallery/Assets/NavViewMenu/AppData.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,13 @@
903903
"Title": "Features (Win2D)",
904904
"ImagePath": "ms-appx:///Assets/Fluent/Canvas.png",
905905
"Items": [
906+
{
907+
"UniqueId": "DevWinUIGallery.Views.AnimationPathPage",
908+
"Title": "Animation Path",
909+
"Subtitle": "Achieve a fixed path animation effect",
910+
"IsNew": true,
911+
"ImagePath": "ms-appx:///Assets/Fluent/Line.png"
912+
},
906913
{
907914
"UniqueId": "DevWinUIGallery.Views.LiveGraphPage",
908915
"Title": "Live Graph",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Page x:Class="DevWinUIGallery.Views.AnimationPathPage"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:dev="using:DevWinUI"
7+
xmlns:local="using:DevWinUIGallery"
8+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9+
mc:Ignorable="d">
10+
11+
<ScrollViewer>
12+
<StackPanel Margin="10" dev:PanelAttach.ChildrenTransitions="Default" Spacing="10">
13+
<local:ControlExample DocPage="controls/animationPath">
14+
<local:ControlExample.Xaml>
15+
<x:String>
16+
&lt;dev:AnimationPath Data="{StaticResource GithubGeometry}" /&gt;
17+
</x:String>
18+
</local:ControlExample.Xaml>
19+
<local:ControlExample.Pane>
20+
<ToggleSwitch x:Name="TgIsPlay" Header="IsPlaying" IsOn="True" />
21+
</local:ControlExample.Pane>
22+
<StackPanel Orientation="Horizontal" Spacing="5">
23+
<dev:AnimationPath Data="{StaticResource GithubGeometry}" IsPlaying="{x:Bind TgIsPlay.IsOn, Mode=OneWay}" />
24+
<dev:AnimationPath Data="{StaticResource GithubGeometry}" Foreground="{ThemeResource SystemFillColorSuccessBrush}" IsPlaying="{x:Bind TgIsPlay.IsOn, Mode=OneWay}" />
25+
<dev:AnimationPath Data="{StaticResource GithubGeometry}" Foreground="{ThemeResource SystemFillColorCautionBrush}" IsPlaying="{x:Bind TgIsPlay.IsOn, Mode=OneWay}" />
26+
<dev:AnimationPath Data="{StaticResource GithubGeometry}" Foreground="{ThemeResource SystemFillColorCriticalBrush}" IsPlaying="{x:Bind TgIsPlay.IsOn, Mode=OneWay}" />
27+
</StackPanel>
28+
</local:ControlExample>
29+
</StackPanel>
30+
</ScrollViewer>
31+
</Page>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace DevWinUIGallery.Views;
2+
3+
public sealed partial class AnimationPathPage : Page
4+
{
5+
public AnimationPathPage()
6+
{
7+
InitializeComponent();
8+
}
9+
}
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
namespace DevWinUI;
2+
3+
public partial class AnimationPath
4+
{
5+
public TimeSpan Duration
6+
{
7+
get { return (TimeSpan)GetValue(DurationProperty); }
8+
set { SetValue(DurationProperty, value); }
9+
}
10+
11+
public static readonly DependencyProperty DurationProperty =
12+
DependencyProperty.Register(nameof(Duration), typeof(TimeSpan), typeof(AnimationPath), new PropertyMetadata(TimeSpan.FromSeconds(6), OnDurationChanged));
13+
14+
private static void OnDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
15+
{
16+
if (d is AnimationPath ctl && ctl._shape != null)
17+
ctl.AnimateStroke(ctl._length);
18+
}
19+
20+
public AnimationIterationBehavior RepeatBehavior
21+
{
22+
get { return (AnimationIterationBehavior)GetValue(RepeatBehaviorProperty); }
23+
set { SetValue(RepeatBehaviorProperty, value); }
24+
}
25+
26+
public static readonly DependencyProperty RepeatBehaviorProperty =
27+
DependencyProperty.Register(nameof(RepeatBehavior), typeof(AnimationIterationBehavior), typeof(AnimationPath), new PropertyMetadata(AnimationIterationBehavior.Forever, OnRepeatBehaviorChanged));
28+
29+
private static void OnRepeatBehaviorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
30+
{
31+
if (d is AnimationPath ctl && ctl._shape != null)
32+
ctl.AnimateStroke(ctl._length);
33+
}
34+
35+
public string Data
36+
{
37+
get { return (string)GetValue(DataProperty); }
38+
set { SetValue(DataProperty, value); }
39+
}
40+
41+
public static readonly DependencyProperty DataProperty =
42+
DependencyProperty.Register(nameof(Data), typeof(string), typeof(AnimationPath), new PropertyMetadata(null, OnDataChanged));
43+
44+
private static void OnDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
45+
{
46+
if (d is AnimationPath ctl && ctl.hostBorder != null)
47+
ctl.Init();
48+
}
49+
50+
public double StrokeThickness
51+
{
52+
get { return (double)GetValue(StrokeThicknessProperty); }
53+
set { SetValue(StrokeThicknessProperty, value); }
54+
}
55+
56+
public static readonly DependencyProperty StrokeThicknessProperty =
57+
DependencyProperty.Register(nameof(StrokeThickness), typeof(double), typeof(AnimationPath), new PropertyMetadata(10.0d, OnStrokeThicknessChanged));
58+
59+
private static void OnStrokeThicknessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
60+
{
61+
if (d is AnimationPath ctl && ctl._shape != null)
62+
ctl._shape.StrokeThickness = (float)(double)e.NewValue;
63+
}
64+
65+
public new Brush Foreground
66+
{
67+
get { return (Brush)GetValue(ForegroundProperty); }
68+
set { SetValue(ForegroundProperty, value); }
69+
}
70+
71+
public new static readonly DependencyProperty ForegroundProperty =
72+
DependencyProperty.Register(nameof(Foreground), typeof(Brush), typeof(AnimationPath), new PropertyMetadata(null, OnForegroundChanged));
73+
74+
private static void OnForegroundChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
75+
{
76+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
77+
{
78+
Color color = ctl.GetColorFromBrush();
79+
ctl._shape.StrokeBrush = ctl._compositor.CreateColorBrush(color);
80+
}
81+
}
82+
83+
public CompositionStrokeCap StrokeStartCap
84+
{
85+
get { return (CompositionStrokeCap)GetValue(StrokeStartCapProperty); }
86+
set { SetValue(StrokeStartCapProperty, value); }
87+
}
88+
89+
public static readonly DependencyProperty StrokeStartCapProperty =
90+
DependencyProperty.Register(nameof(StrokeStartCap), typeof(CompositionStrokeCap), typeof(AnimationPath), new PropertyMetadata(CompositionStrokeCap.Flat, OnStrokeStartCapChanged));
91+
92+
private static void OnStrokeStartCapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
93+
{
94+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
95+
{
96+
ctl._shape.StrokeStartCap = (CompositionStrokeCap)e.NewValue;
97+
}
98+
}
99+
100+
public double StrokeMiterLimit
101+
{
102+
get { return (double)GetValue(StrokeMiterLimitProperty); }
103+
set { SetValue(StrokeMiterLimitProperty, value); }
104+
}
105+
106+
public static readonly DependencyProperty StrokeMiterLimitProperty =
107+
DependencyProperty.Register(nameof(StrokeMiterLimit), typeof(double), typeof(AnimationPath), new PropertyMetadata(1.0d, OnStrokeMiterLimitChanged));
108+
109+
private static void OnStrokeMiterLimitChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
110+
{
111+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
112+
{
113+
ctl._shape.StrokeMiterLimit = (float)(double)e.NewValue;
114+
}
115+
}
116+
117+
public CompositionStrokeCap StrokeEndCap
118+
{
119+
get { return (CompositionStrokeCap)GetValue(StrokeEndCapProperty); }
120+
set { SetValue(StrokeEndCapProperty, value); }
121+
}
122+
123+
public static readonly DependencyProperty StrokeEndCapProperty =
124+
DependencyProperty.Register(nameof(StrokeEndCap), typeof(CompositionStrokeCap), typeof(AnimationPath), new PropertyMetadata(CompositionStrokeCap.Flat, OnStrokeEndCapChanged));
125+
126+
private static void OnStrokeEndCapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
127+
{
128+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
129+
{
130+
ctl._shape.StrokeEndCap = (CompositionStrokeCap)e.NewValue;
131+
}
132+
}
133+
134+
public double StrokeDashOffset
135+
{
136+
get { return (double)GetValue(StrokeDashOffsetProperty); }
137+
set { SetValue(StrokeDashOffsetProperty, value); }
138+
}
139+
140+
public static readonly DependencyProperty StrokeDashOffsetProperty =
141+
DependencyProperty.Register(nameof(StrokeDashOffset), typeof(double), typeof(AnimationPath), new PropertyMetadata(default(double), OnStrokeDashOffsetChanged));
142+
143+
private static void OnStrokeDashOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
144+
{
145+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
146+
{
147+
ctl._shape.StrokeDashOffset = (float)(double)e.NewValue;
148+
}
149+
}
150+
151+
public CompositionStrokeCap StrokeDashCap
152+
{
153+
get { return (CompositionStrokeCap)GetValue(StrokeDashCapProperty); }
154+
set { SetValue(StrokeDashCapProperty, value); }
155+
}
156+
157+
public static readonly DependencyProperty StrokeDashCapProperty =
158+
DependencyProperty.Register(nameof(StrokeDashCap), typeof(CompositionStrokeCap), typeof(AnimationPath), new PropertyMetadata(CompositionStrokeCap.Flat, OnStrokeDashCapChanged));
159+
160+
private static void OnStrokeDashCapChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
161+
{
162+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
163+
{
164+
ctl._shape.StrokeDashCap = (CompositionStrokeCap)e.NewValue;
165+
}
166+
}
167+
168+
public CompositionStrokeLineJoin StrokeLineJoin
169+
{
170+
get { return (CompositionStrokeLineJoin)GetValue(StrokeLineJoinProperty); }
171+
set { SetValue(StrokeLineJoinProperty, value); }
172+
}
173+
174+
public static readonly DependencyProperty StrokeLineJoinProperty =
175+
DependencyProperty.Register(nameof(StrokeLineJoin), typeof(CompositionStrokeLineJoin), typeof(AnimationPath), new PropertyMetadata(CompositionStrokeLineJoin.Miter, OnStrokeLineJoinChanged));
176+
177+
private static void OnStrokeLineJoinChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
178+
{
179+
if (d is AnimationPath ctl && ctl._shape != null && ctl._compositor != null)
180+
{
181+
ctl._shape.StrokeLineJoin = (CompositionStrokeLineJoin)e.NewValue;
182+
}
183+
}
184+
185+
public bool IsPlaying
186+
{
187+
get => (bool)GetValue(IsPlayingProperty);
188+
set => SetValue(IsPlayingProperty, value);
189+
}
190+
public static readonly DependencyProperty IsPlayingProperty =
191+
DependencyProperty.Register(nameof(IsPlaying), typeof(bool), typeof(AnimationPath), new PropertyMetadata(true, OnIsPlayingChanged));
192+
193+
private static void OnIsPlayingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
194+
{
195+
var ctl = (AnimationPath)d;
196+
ctl.HandleAnimationState();
197+
}
198+
}

0 commit comments

Comments
 (0)