Skip to content

Commit 795d14d

Browse files
committed
Add MorphingAnimation
1 parent 4708a1e commit 795d14d

9 files changed

Lines changed: 409 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+
### MorphingAnimation
114+
![MorphingAnimation](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/MorphingAnimation.gif)
115+
113116
### AnimationPath
114117
![AnimationPath](https://raw.githubusercontent.com/ghost1372/DevWinUI-Resources/refs/heads/main/DevWinUI-Docs/AnimationPath.gif)
115118

dev/DevWinUI.Gallery/App.xaml

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

17+
<x:String x:Key="FaceBookGeometry">m 41.416254,90 c -0.327378,-7.4702 0.20833,-32.7284 0,-39.901 -5.386902,-0.2083 -4.521603,0.3274 -9.848987,0 0.20833,-5.50595 0.36436,-7.66666 0.126269,-13.32142 4.646472,0.0181 3.439989,-0.009 9.848987,-0.1894 0.09586,-3.7736 0.133082,-3.0791 0.126269,-7.38674 0.18259,-3.73943 -0.486609,-10.54308 4.293149,-14.96288 4.779758,-4.4198 13.606811,-3.64808 22.223356,-3.53554 -0.04417,5.73754 -0.03936,9.37986 0,12.87945 -5.049924,0.46388 -7.309188,-0.33689 -10.85914,1.26269 -1.403378,3.17794 -1.569601,4.80531 -1.262691,11.93242 3.147964,-0.13336 8.201788,-0.1378 12.626907,0 -0.995158,6.00899 -0.948285,7.62376 -1.767767,13.06882 -3.676625,0.088 -5.605721,-0.1488 -11.111678,0 -0.148814,6.756 0.357147,33.0107 0,40.1536 -6.428576,0.1786 -8.174438,-0.03 -14.394674,0 z</x:String>
18+
<x:String x:Key="TwitterGeometry">m 10.44335,90 c 11.073313,0.3952 19.483106,-1.8358 23.901837,-7.1603 -7.9736,-1.4292 -11.832311,-4.1933 -15.078321,-11.0837 3.459698,0.8219 5.795894,0.6358 7.606781,-0.607 -7.19593,-1.719 -12.734543,-6.7971 -13.741664,-15.836 2.766355,1.55307 5.466848,2.66623 7.828682,2.0203 -4.336544,-2.92911 -9.838998,-10.47636 -5.555839,-22.47589 8.400675,11.87052 23.824269,17.67568 33.840111,17.67767 -0.936406,-9.74688 5.88057,-19.46521 15.302849,-19.97853 8.13118,-0.50719 10.57457,4.01944 12.476346,4.82624 3.644547,0.13419 7.393301,-1.74401 10.354063,-3.53553 -1.380842,4.47157 -5.06769,5.62903 -6.313453,8.58629 5.42317,0.41513 5.891376,-1.53111 8.333758,-2.0203 -2.071414,3.75017 -5.393863,5.00034 -7.323606,8.08122 -1.633654,16.12573 -5.16049,27.57123 -14.647212,36.36553 -13.825764,11.3764 -34.755458,17.369 -56.984332,5.14 z</x:String>
1719
<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>
1820
<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>
1921
<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>

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.MorphingAnimationPage",
908+
"Title": "Morphing Animation",
909+
"Subtitle": "Change a geometry with animation to a different geometry",
910+
"IsNew": true,
911+
"ImagePath": "ms-appx:///Assets/Fluent/ConnectedAnimation.png"
912+
},
906913
{
907914
"UniqueId": "DevWinUIGallery.Views.AnimationPathPage",
908915
"Title": "Animation Path",
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<Page x:Class="DevWinUIGallery.Views.MorphingAnimationPage"
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/morphingAnimation">
14+
<local:ControlExample.Xaml>
15+
<x:String>
16+
&lt;dev:MorphingAnimation PrimaryData="{StaticResource TwitterGeometry}" SecondaryData="{StaticResource FaceBookGeometry}" /&gt;
17+
</x:String>
18+
</local:ControlExample.Xaml>
19+
<StackPanel Orientation="Horizontal" Spacing="10">
20+
<dev:MorphingAnimation PrimaryColor="{ThemeResource SystemFillColorSuccess}" PrimaryData="{StaticResource TwitterGeometry}" SecondaryColor="{ThemeResource SystemFillColorCritical}" SecondaryData="{StaticResource FaceBookGeometry}" />
21+
<dev:MorphingAnimation PrimaryColor="{ThemeResource SystemAccentColor}" PrimaryData="{StaticResource TwitterGeometry}" SecondaryColor="{ThemeResource SystemAccentColorDark1}" SecondaryData="{StaticResource FaceBookGeometry}" />
22+
</StackPanel>
23+
</local:ControlExample>
24+
</StackPanel>
25+
</ScrollViewer>
26+
27+
</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 MorphingAnimationPage : Page
4+
{
5+
public MorphingAnimationPage()
6+
{
7+
InitializeComponent();
8+
}
9+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
namespace DevWinUI;
2+
3+
public partial class MorphingAnimation
4+
{
5+
public Color PrimaryColor
6+
{
7+
get { return (Color)GetValue(PrimaryColorProperty); }
8+
set { SetValue(PrimaryColorProperty, value); }
9+
}
10+
11+
public static readonly DependencyProperty PrimaryColorProperty =
12+
DependencyProperty.Register(nameof(PrimaryColor), typeof(Color), typeof(MorphingAnimation), new PropertyMetadata(Colors.Transparent, OnPrimaryColorChanged));
13+
private static void OnPrimaryColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
14+
{
15+
var ctl = (MorphingAnimation)d;
16+
ctl.primaryColor = (Color)e.NewValue;
17+
}
18+
19+
public Color SecondaryColor
20+
{
21+
get { return (Color)GetValue(SecondaryColorProperty); }
22+
set { SetValue(SecondaryColorProperty, value); }
23+
}
24+
25+
public static readonly DependencyProperty SecondaryColorProperty =
26+
DependencyProperty.Register(nameof(SecondaryColor), typeof(Color), typeof(MorphingAnimation), new PropertyMetadata(Colors.Transparent, OnSecondaryColorChanged));
27+
28+
29+
private static void OnSecondaryColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
30+
{
31+
var ctl = (MorphingAnimation)d;
32+
ctl.secondaryColor = (Color)e.NewValue;
33+
}
34+
35+
public TimeSpan AnimationDuration
36+
{
37+
get { return (TimeSpan)GetValue(AnimationDurationProperty); }
38+
set { SetValue(AnimationDurationProperty, value); }
39+
}
40+
41+
public static readonly DependencyProperty AnimationDurationProperty =
42+
DependencyProperty.Register(nameof(AnimationDuration), typeof(TimeSpan), typeof(MorphingAnimation), new PropertyMetadata(TimeSpan.FromMilliseconds(500), OnDurationChanged));
43+
44+
private static void OnDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
45+
{
46+
var ctl = (MorphingAnimation)d;
47+
ctl.animDuration = ((TimeSpan)e.NewValue).TotalSeconds;
48+
}
49+
50+
public TimeSpan HoldDuration
51+
{
52+
get { return (TimeSpan)GetValue(HoldDurationProperty); }
53+
set { SetValue(HoldDurationProperty, value); }
54+
}
55+
56+
public static readonly DependencyProperty HoldDurationProperty =
57+
DependencyProperty.Register(nameof(HoldDuration), typeof(TimeSpan), typeof(MorphingAnimation), new PropertyMetadata(TimeSpan.FromSeconds(1), OnHoldDurationChanged));
58+
59+
private static void OnHoldDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
60+
{
61+
var ctl = (MorphingAnimation)d;
62+
ctl.holdDuration = ((TimeSpan)e.NewValue).TotalSeconds;
63+
}
64+
65+
public string PrimaryData
66+
{
67+
get { return (string)GetValue(PrimaryDataProperty); }
68+
set { SetValue(PrimaryDataProperty, value); }
69+
}
70+
71+
public static readonly DependencyProperty PrimaryDataProperty =
72+
DependencyProperty.Register(nameof(PrimaryData), typeof(string), typeof(MorphingAnimation), new PropertyMetadata(null, OnPrimaryDataChanged));
73+
74+
private static void OnPrimaryDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
75+
{
76+
var ctl = (MorphingAnimation)d;
77+
ctl.primaryData = (string)e.NewValue;
78+
ctl.GetShapesPoint();
79+
ctl.canvas?.Invalidate();
80+
}
81+
82+
public string SecondaryData
83+
{
84+
get { return (string)GetValue(SecondaryDataProperty); }
85+
set { SetValue(SecondaryDataProperty, value); }
86+
}
87+
88+
public static readonly DependencyProperty SecondaryDataProperty =
89+
DependencyProperty.Register(nameof(SecondaryData), typeof(string), typeof(MorphingAnimation), new PropertyMetadata(null, OnSecondaryDataChanged));
90+
91+
private static void OnSecondaryDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
92+
{
93+
var ctl = (MorphingAnimation)d;
94+
ctl.secondaryData = (string)e.NewValue;
95+
ctl.GetShapesPoint();
96+
ctl.canvas?.Invalidate();
97+
}
98+
99+
public int PointCount
100+
{
101+
get { return (int)GetValue(PointCountProperty); }
102+
set { SetValue(PointCountProperty, value); }
103+
}
104+
105+
public static readonly DependencyProperty PointCountProperty =
106+
DependencyProperty.Register(nameof(PointCount), typeof(int), typeof(MorphingAnimation), new PropertyMetadata(300, OnPointCountChanged));
107+
108+
private static void OnPointCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
109+
{
110+
var ctl = (MorphingAnimation)d;
111+
ctl.pointCount = (int)e.NewValue;
112+
ctl.canvas?.Invalidate();
113+
}
114+
}
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
namespace DevWinUI;
2+
3+
[TemplatePart(Name = nameof(PART_Canvas), Type = typeof(CanvasAnimatedControl))]
4+
public partial class MorphingAnimation : Control
5+
{
6+
private const string PART_Canvas = "PART_Canvas";
7+
8+
private CanvasAnimatedControl canvas;
9+
10+
private Windows.UI.Color primaryColor = Windows.UI.Color.FromArgb(255, 0x1D, 0xA1, 0xF2);
11+
private Windows.UI.Color secondaryColor = Windows.UI.Color.FromArgb(255, 0x18, 0x77, 0xF2);
12+
13+
private string primaryData;
14+
private string secondaryData;
15+
16+
private enum MorphingAnimationPhase { ToSecondary, HoldSecondary, ToPrimary, HoldPrimary }
17+
18+
private double animDuration = 0.5; // seconds – morph travel time
19+
private double holdDuration = 1.0; // seconds – pause at each end
20+
21+
private List<Vector2> primaryShape;
22+
private List<Vector2> secondaryShape;
23+
24+
private MorphingAnimationPhase phase = MorphingAnimationPhase.ToSecondary;
25+
private double phaseTime = 0.0;
26+
private float progress = 0f; // 0 = Primary, 1 = Secondary
27+
28+
private int pointCount = 300;
29+
30+
public MorphingAnimation()
31+
{
32+
DefaultStyleKey = typeof(MorphingAnimation);
33+
}
34+
35+
protected override void OnApplyTemplate()
36+
{
37+
base.OnApplyTemplate();
38+
39+
canvas = GetTemplateChild(PART_Canvas) as CanvasAnimatedControl;
40+
41+
GetShapesPoint();
42+
43+
canvas.Draw -= OnDraw;
44+
canvas.Draw += OnDraw;
45+
46+
canvas.Update -= OnUpdate;
47+
canvas.Update += OnUpdate;
48+
}
49+
50+
private void GetShapesPoint()
51+
{
52+
primaryShape = SamplePointsOnPath(primaryData, pointCount);
53+
secondaryShape = SamplePointsOnPath(secondaryData, pointCount);
54+
}
55+
56+
private void OnUpdate(ICanvasAnimatedControl sender, CanvasAnimatedUpdateEventArgs args)
57+
{
58+
double dt = args.Timing.ElapsedTime.TotalSeconds;
59+
60+
phaseTime += dt;
61+
62+
switch (phase)
63+
{
64+
case MorphingAnimationPhase.ToSecondary:
65+
progress = (float)Math.Min(phaseTime / animDuration, 1.0);
66+
if (phaseTime >= animDuration)
67+
{
68+
progress = 1f;
69+
phaseTime = 0.0;
70+
phase = MorphingAnimationPhase.HoldSecondary;
71+
}
72+
break;
73+
74+
case MorphingAnimationPhase.HoldSecondary:
75+
if (phaseTime >= holdDuration)
76+
{
77+
phaseTime = 0.0;
78+
phase = MorphingAnimationPhase.ToPrimary;
79+
}
80+
break;
81+
82+
case MorphingAnimationPhase.ToPrimary:
83+
progress = (float)Math.Max(1.0 - phaseTime / animDuration, 0.0);
84+
if (phaseTime >= animDuration)
85+
{
86+
progress = 0f;
87+
phaseTime = 0.0;
88+
phase = MorphingAnimationPhase.HoldPrimary;
89+
}
90+
break;
91+
92+
case MorphingAnimationPhase.HoldPrimary:
93+
if (phaseTime >= holdDuration)
94+
{
95+
phaseTime = 0.0;
96+
phase = MorphingAnimationPhase.ToSecondary;
97+
}
98+
break;
99+
}
100+
}
101+
102+
private void OnDraw(ICanvasAnimatedControl sender, CanvasAnimatedDrawEventArgs args)
103+
{
104+
var ds = args.DrawingSession;
105+
106+
float eased = EaseInOut(progress);
107+
108+
if (primaryShape == null || secondaryShape == null)
109+
return;
110+
111+
var morphed = Morph(primaryShape, secondaryShape, eased);
112+
113+
// Scale and center the morphed points to always fit the current canvas size.
114+
var fitted = FitToCanvas(morphed, (float)sender.Size.Width, (float)sender.Size.Height);
115+
116+
using var builder = new CanvasPathBuilder(sender.Device);
117+
118+
builder.BeginFigure(fitted[0]);
119+
for (int i = 1; i < fitted.Count; i++)
120+
builder.AddLine(fitted[i]);
121+
builder.EndFigure(CanvasFigureLoop.Closed);
122+
123+
using var geometry = CanvasGeometry.CreatePath(builder);
124+
125+
var fillColor = LerpColor(primaryColor, secondaryColor, eased);
126+
ds.FillGeometry(geometry, fillColor);
127+
}
128+
129+
/// <summary>
130+
/// Uniformly scales and centers <paramref name="points"/> to fit inside the given canvas
131+
/// dimensions with a small padding. Because it reads <c>sender.Size</c> every frame,
132+
/// this also handles any SizeChanged automatically.
133+
/// </summary>
134+
private static List<Vector2> FitToCanvas(List<Vector2> points, float canvasWidth, float canvasHeight, float padding = 8f)
135+
{
136+
if (points == null || points.Count == 0 || canvasWidth <= 0 || canvasHeight <= 0)
137+
return points;
138+
139+
float minX = points[0].X, maxX = points[0].X;
140+
float minY = points[0].Y, maxY = points[0].Y;
141+
142+
foreach (var p in points)
143+
{
144+
if (p.X < minX) minX = p.X;
145+
if (p.X > maxX) maxX = p.X;
146+
if (p.Y < minY) minY = p.Y;
147+
if (p.Y > maxY) maxY = p.Y;
148+
}
149+
150+
float geomW = maxX - minX;
151+
float geomH = maxY - minY;
152+
153+
float availW = canvasWidth - padding * 2f;
154+
float availH = canvasHeight - padding * 2f;
155+
156+
// Uniform scale so the shape fits without distortion.
157+
float scale = (geomW > 0 && geomH > 0)
158+
? Math.Min(availW / geomW, availH / geomH)
159+
: 1f;
160+
161+
// Offset to center the scaled shape on the canvas.
162+
float offsetX = padding + (availW - geomW * scale) / 2f - minX * scale;
163+
float offsetY = padding + (availH - geomH * scale) / 2f - minY * scale;
164+
165+
var result = new List<Vector2>(points.Count);
166+
foreach (var p in points)
167+
result.Add(new Vector2(p.X * scale + offsetX, p.Y * scale + offsetY));
168+
169+
return result;
170+
}
171+
172+
private static List<Vector2> SamplePointsOnPath(string svgPath, int pointCount)
173+
{
174+
if (string.IsNullOrEmpty(svgPath))
175+
return null;
176+
177+
var device = CanvasDevice.GetSharedDevice();
178+
using var geometry = CanvasObject.CreateGeometry(svgPath);
179+
float length = geometry.ComputePathLength();
180+
181+
var points = new List<Vector2>(pointCount);
182+
for (int i = 0; i < pointCount; i++)
183+
{
184+
float t = i / (float)(pointCount - 1);
185+
points.Add(geometry.ComputePointOnPath(t * length));
186+
}
187+
return points;
188+
}
189+
190+
private static Windows.UI.Color LerpColor(Windows.UI.Color a, Windows.UI.Color b, float t) => Windows.UI.Color.FromArgb(
191+
(byte)(a.A + (b.A - a.A) * t),
192+
(byte)(a.R + (b.R - a.R) * t),
193+
(byte)(a.G + (b.G - a.G) * t),
194+
(byte)(a.B + (b.B - a.B) * t));
195+
196+
private static float EaseInOut(float t) => t * t * (3f - 2f * t);
197+
198+
private static List<Vector2> Morph(List<Vector2> a, List<Vector2> b, float t)
199+
{
200+
var result = new List<Vector2>(a.Count);
201+
202+
for (int i = 0; i < a.Count; i++)
203+
{
204+
result.Add(Vector2.Lerp(a[i], b[i], t));
205+
}
206+
207+
return result;
208+
}
209+
}

0 commit comments

Comments
 (0)