Skip to content

Commit 5365ea5

Browse files
CopilotJen-Uno
andcommitted
docs: add Xamarin.Forms migration guides
Co-authored-by: Jen-Uno <214558326+Jen-Uno@users.noreply.github.com>
1 parent cb20dbc commit 5365ea5

File tree

7 files changed

+1585
-10
lines changed

7 files changed

+1585
-10
lines changed
Lines changed: 392 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,392 @@
1+
---
2+
uid: Uno.XamarinFormsMigration.Animations
3+
---
4+
5+
# Migrating Animations from Xamarin.Forms to Uno Platform
6+
7+
This guide explores how to migrate animations from Xamarin.Forms to Uno Platform. While both frameworks support rich animation capabilities, they use different APIs and approaches. This article will help you understand the differences and successfully migrate your animations.
8+
9+
## Animation Approaches
10+
11+
### Xamarin.Forms Animations
12+
13+
Xamarin.Forms provides a simple, code-based animation API through extension methods on the `View` class:
14+
15+
- `RotateTo`
16+
- `ScaleTo`, `ScaleXTo`, `ScaleYTo`
17+
- `TranslateTo`
18+
- `FadeTo`
19+
20+
These methods are called directly on view instances and allow you to animate properties over time with optional easing functions.
21+
22+
### Uno Platform Animations
23+
24+
Uno Platform, following the WinUI model, uses XAML-based animations through the `Storyboard` class. Animations are typically defined in XAML and controlled from code. This approach provides more flexibility and better separation of animation definitions from business logic.
25+
26+
## Animation Types
27+
28+
### Transform Animations
29+
30+
Transforms allow you to rotate, scale, translate, and skew visual elements without affecting their layout position.
31+
32+
#### Rotation
33+
34+
**Xamarin.Forms:**
35+
```csharp
36+
await myElement.RotateTo(360, 1000);
37+
```
38+
39+
**Uno Platform:**
40+
```xml
41+
<Storyboard x:Name="RotateStoryboard">
42+
<DoubleAnimation Storyboard.TargetName="myElement"
43+
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
44+
To="360"
45+
Duration="0:0:1"/>
46+
</Storyboard>
47+
```
48+
49+
To use transforms in Uno Platform, you must first apply the transform to the element:
50+
51+
```xml
52+
<Border x:Name="myElement">
53+
<Border.RenderTransform>
54+
<RotateTransform/>
55+
</Border.RenderTransform>
56+
</Border>
57+
```
58+
59+
#### Scaling
60+
61+
**Xamarin.Forms:**
62+
```csharp
63+
await myElement.ScaleTo(2.0, 1000);
64+
await myElement.ScaleXTo(2.0, 1000);
65+
await myElement.ScaleYTo(2.0, 1000);
66+
```
67+
68+
**Uno Platform:**
69+
```xml
70+
<Storyboard x:Name="ScaleStoryboard">
71+
<DoubleAnimation Storyboard.TargetName="myElement"
72+
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
73+
To="2.0"
74+
Duration="0:0:1"/>
75+
<DoubleAnimation Storyboard.TargetName="myElement"
76+
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
77+
To="2.0"
78+
Duration="0:0:1"/>
79+
</Storyboard>
80+
```
81+
82+
With the transform applied:
83+
84+
```xml
85+
<Border x:Name="myElement">
86+
<Border.RenderTransform>
87+
<ScaleTransform/>
88+
</Border.RenderTransform>
89+
</Border>
90+
```
91+
92+
#### Translation
93+
94+
**Xamarin.Forms:**
95+
```csharp
96+
await myElement.TranslateTo(100, 100, 1000);
97+
```
98+
99+
**Uno Platform:**
100+
```xml
101+
<Storyboard x:Name="TranslateStoryboard">
102+
<DoubleAnimation Storyboard.TargetName="myElement"
103+
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
104+
To="100"
105+
Duration="0:0:1"/>
106+
<DoubleAnimation Storyboard.TargetName="myElement"
107+
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
108+
To="100"
109+
Duration="0:0:1"/>
110+
</Storyboard>
111+
```
112+
113+
With the transform applied:
114+
115+
```xml
116+
<Border x:Name="myElement">
117+
<Border.RenderTransform>
118+
<TranslateTransform/>
119+
</Border.RenderTransform>
120+
</Border>
121+
```
122+
123+
### Opacity Animations
124+
125+
**Xamarin.Forms:**
126+
```csharp
127+
await myElement.FadeTo(0.5, 1000);
128+
```
129+
130+
**Uno Platform:**
131+
```xml
132+
<Storyboard x:Name="FadeStoryboard">
133+
<DoubleAnimation Storyboard.TargetName="myElement"
134+
Storyboard.TargetProperty="Opacity"
135+
To="0.5"
136+
Duration="0:0:1"/>
137+
</Storyboard>
138+
```
139+
140+
## Xamarin.Forms to Storyboard Mappings
141+
142+
| Xamarin.Forms Method | WinUI/Uno Storyboard Target |
143+
|---------------------|----------------------------|
144+
| `RotateTo` | `(UIElement.RenderTransform).(RotateTransform.Angle)` |
145+
| `ScaleTo` | `(UIElement.RenderTransform).(ScaleTransform.ScaleX)` and `(UIElement.RenderTransform).(ScaleTransform.ScaleY)` |
146+
| `ScaleXTo` | `(UIElement.RenderTransform).(ScaleTransform.ScaleX)` |
147+
| `ScaleYTo` | `(UIElement.RenderTransform).(ScaleTransform.ScaleY)` |
148+
| `TranslateTo` | `(UIElement.RenderTransform).(TranslateTransform.X)` and `(UIElement.RenderTransform).(TranslateTransform.Y)` |
149+
| `FadeTo` | `Opacity` |
150+
151+
## Composite Transforms
152+
153+
If you need to apply multiple transforms to a single element (e.g., rotate and scale), use `CompositeTransform` instead of individual transforms:
154+
155+
```xml
156+
<Border x:Name="myElement">
157+
<Border.RenderTransform>
158+
<CompositeTransform/>
159+
</Border.RenderTransform>
160+
</Border>
161+
162+
<Storyboard x:Name="CompositeStoryboard">
163+
<DoubleAnimation Storyboard.TargetName="myElement"
164+
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)"
165+
To="360"
166+
Duration="0:0:1"/>
167+
<DoubleAnimation Storyboard.TargetName="myElement"
168+
Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.ScaleX)"
169+
To="2.0"
170+
Duration="0:0:1"/>
171+
</Storyboard>
172+
```
173+
174+
## Easing Functions
175+
176+
Easing functions change how animations progress over time, enabling elements to speed up and slow down for more natural movements.
177+
178+
### Xamarin.Forms Easing
179+
180+
Xamarin.Forms uses the `Easing` class with built-in easing functions:
181+
182+
```csharp
183+
await myElement.ScaleTo(2.0, 1000, Easing.BounceOut);
184+
```
185+
186+
### Uno Platform Easing
187+
188+
WinUI uses `EasingFunctionBase`-derived classes:
189+
190+
```xml
191+
<DoubleAnimation Storyboard.TargetName="myElement"
192+
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)"
193+
To="2.0"
194+
Duration="0:0:1">
195+
<DoubleAnimation.EasingFunction>
196+
<BounceEase EasingMode="EaseOut"/>
197+
</DoubleAnimation.EasingFunction>
198+
</DoubleAnimation>
199+
```
200+
201+
### Easing Function Mappings
202+
203+
| Xamarin.Forms | WinUI/Uno Platform |
204+
|---------------|-------------------|
205+
| `Bounce` (`BounceIn`/`BounceOut`) | `BounceEase` |
206+
| `Cubic` (`CubicIn`/`CubicInOut`/`CubicOut`) | `CubicEase` |
207+
| `Linear` | (specify no `EasingFunction`) |
208+
| `Sin` (`SinIn`/`SinInOut`/`SinOut`) | `SineEase` |
209+
| `Spring` (`SpringIn`/`SpringOut`) | `ElasticEase` |
210+
211+
### Easing Modes
212+
213+
Easing functions in WinUI have an `EasingMode` property that controls the direction of the easing:
214+
215+
- `EaseIn`: Acceleration at the start
216+
- `EaseOut`: Deceleration at the end
217+
- `EaseInOut`: Acceleration at start and deceleration at end
218+
219+
```xml
220+
<BounceEase EasingMode="EaseOut"/>
221+
<CubicEase EasingMode="EaseInOut"/>
222+
<SineEase EasingMode="EaseIn"/>
223+
```
224+
225+
### Additional WinUI Easing Functions
226+
227+
WinUI provides additional easing functions not available in Xamarin.Forms:
228+
229+
- **QuadraticEase**: Quadratic acceleration/deceleration
230+
- **QuarticEase**: Quartic acceleration/deceleration
231+
- **QuinticEase**: Quintic acceleration/deceleration
232+
- **PowerEase**: Acceleration/deceleration using any power (provides more flexibility)
233+
- **BackEase**: Reverses direction slightly before starting (or overshoots on ending)
234+
- **CircleEase**: Acceleration/deceleration using a circular function
235+
- **ExponentialEase**: Acceleration/deceleration using an exponential function
236+
237+
Example using `PowerEase`:
238+
239+
```xml
240+
<PowerEase Power="3" EasingMode="EaseInOut"/>
241+
```
242+
243+
Example using `BackEase`:
244+
245+
```xml
246+
<BackEase Amplitude="0.5" EasingMode="EaseOut"/>
247+
```
248+
249+
## Custom Easing
250+
251+
Xamarin.Forms supports custom easing functions where you define your own progression from 0.0 to 1.0:
252+
253+
```csharp
254+
var customEasing = new Easing(t => Math.Sin(t * Math.PI * 2));
255+
await myElement.ScaleTo(2.0, 1000, customEasing);
256+
```
257+
258+
WinUI doesn't currently support custom easing functions directly. You can work around this limitation by:
259+
260+
1. Using the closest available easing function
261+
2. Using keyframe animation to specify required values along the timeline
262+
263+
### Keyframe Animations
264+
265+
Keyframe animations allow you to specify exact values at specific points in time:
266+
267+
```xml
268+
<Storyboard x:Name="KeyframeStoryboard">
269+
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="myElement"
270+
Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleX)">
271+
<LinearDoubleKeyFrame KeyTime="0:0:0" Value="1.0"/>
272+
<LinearDoubleKeyFrame KeyTime="0:0:0.25" Value="1.5"/>
273+
<LinearDoubleKeyFrame KeyTime="0:0:0.5" Value="0.8"/>
274+
<LinearDoubleKeyFrame KeyTime="0:0:0.75" Value="1.8"/>
275+
<LinearDoubleKeyFrame KeyTime="0:0:1" Value="2.0"/>
276+
</DoubleAnimationUsingKeyFrames>
277+
</Storyboard>
278+
```
279+
280+
Types of keyframes:
281+
- **LinearDoubleKeyFrame**: Linear interpolation between values
282+
- **DiscreteDoubleKeyFrame**: Jumps to the value (no interpolation)
283+
- **EasingDoubleKeyFrame**: Applies an easing function between keyframes
284+
- **SplineDoubleKeyFrame**: Uses a cubic Bezier curve for interpolation
285+
286+
## Controlling Animations from Code
287+
288+
### Starting Animations
289+
290+
**Xamarin.Forms:**
291+
```csharp
292+
await myElement.RotateTo(360, 1000);
293+
```
294+
295+
**Uno Platform:**
296+
```csharp
297+
RotateStoryboard.Begin();
298+
```
299+
300+
### Stopping Animations
301+
302+
**Uno Platform:**
303+
```csharp
304+
RotateStoryboard.Stop();
305+
```
306+
307+
### Pausing and Resuming
308+
309+
**Uno Platform:**
310+
```csharp
311+
RotateStoryboard.Pause();
312+
RotateStoryboard.Resume();
313+
```
314+
315+
### Handling Completion
316+
317+
**Xamarin.Forms:**
318+
```csharp
319+
await myElement.RotateTo(360, 1000);
320+
// Code here runs after animation completes
321+
```
322+
323+
**Uno Platform:**
324+
```csharp
325+
RotateStoryboard.Completed += (s, e) =>
326+
{
327+
// Code here runs after animation completes
328+
};
329+
RotateStoryboard.Begin();
330+
```
331+
332+
## Animation Repeat Behavior
333+
334+
### Repeat Forever
335+
336+
**Uno Platform:**
337+
```xml
338+
<Storyboard x:Name="RepeatStoryboard" RepeatBehavior="Forever">
339+
<DoubleAnimation Storyboard.TargetName="myElement"
340+
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
341+
From="0"
342+
To="360"
343+
Duration="0:0:2"/>
344+
</Storyboard>
345+
```
346+
347+
### Repeat Count
348+
349+
**Uno Platform:**
350+
```xml
351+
<Storyboard x:Name="RepeatStoryboard" RepeatBehavior="3x">
352+
<!-- Animation repeats 3 times -->
353+
</Storyboard>
354+
```
355+
356+
### Auto-Reverse
357+
358+
**Uno Platform:**
359+
```xml
360+
<Storyboard x:Name="ReverseStoryboard" AutoReverse="True">
361+
<!-- Animation plays forward, then backward -->
362+
</Storyboard>
363+
```
364+
365+
## Migration Strategy
366+
367+
When migrating animations from Xamarin.Forms to Uno Platform:
368+
369+
1. **Identify all animation calls** in your Xamarin.Forms code (look for `RotateTo`, `ScaleTo`, `TranslateTo`, `FadeTo`, etc.)
370+
2. **Create corresponding Storyboards** in XAML for each animation
371+
3. **Add necessary RenderTransforms** to elements that will be animated
372+
4. **Map easing functions** from Xamarin.Forms to WinUI equivalents
373+
5. **Replace animation method calls** with `Storyboard.Begin()` calls
374+
6. **Handle completion** using the `Completed` event instead of `await`
375+
7. **Test animations** on all target platforms to ensure consistency
376+
377+
## Summary
378+
379+
While Xamarin.Forms uses code-based animations and Uno Platform uses XAML-based Storyboards, the concepts are similar:
380+
381+
- Both support transform-based animations (rotation, scaling, translation)
382+
- Both support opacity animations
383+
- Both support easing functions (with similar built-in options)
384+
- Uno Platform provides more control through XAML definitions
385+
- Uno Platform supports additional easing functions and keyframe animations
386+
387+
The main difference is the declarative nature of Uno Platform animations, which provides better separation between animation definitions and business logic.
388+
389+
## Next Steps
390+
391+
- Continue with [Migrating Custom Controls](xref:Uno.XamarinFormsMigration.CustomControls)
392+
- Return to [Overview](xref:Uno.XamarinFormsMigration.Overview)

0 commit comments

Comments
 (0)