csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
4.3 KiB
120 lines
4.3 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Avalonia;
|
|
using Avalonia.Animation;
|
|
using Avalonia.Animation.Easings;
|
|
using Avalonia.Media;
|
|
using Avalonia.Styling;
|
|
using Avalonia.VisualTree;
|
|
|
|
namespace ControlCatalog.Pages
|
|
{
|
|
/// <summary>
|
|
/// Example custom IPageTransition: horizontal slide combined with cross-fade.
|
|
/// Both pages slide and fade simultaneously for a smooth blended effect.
|
|
/// </summary>
|
|
public class CompositeTransition : IPageTransition
|
|
{
|
|
public CompositeTransition() { }
|
|
|
|
public CompositeTransition(TimeSpan duration)
|
|
{
|
|
Duration = duration;
|
|
}
|
|
|
|
public TimeSpan Duration { get; set; } = TimeSpan.FromMilliseconds(300);
|
|
public Easing TransitionEasing { get; set; } = new LinearEasing();
|
|
|
|
public async Task Start(Visual? from, Visual? to, bool forward, CancellationToken cancellationToken)
|
|
{
|
|
if (cancellationToken.IsCancellationRequested)
|
|
return;
|
|
|
|
var tasks = new List<Task>();
|
|
var parent = GetVisualParent(from, to);
|
|
var distance = parent.Bounds.Width > 0 ? parent.Bounds.Width : 500d;
|
|
|
|
if (from != null)
|
|
{
|
|
var anim = new Avalonia.Animation.Animation
|
|
{
|
|
FillMode = FillMode.Forward,
|
|
Easing = TransitionEasing,
|
|
Duration = Duration,
|
|
Children =
|
|
{
|
|
new KeyFrame
|
|
{
|
|
Cue = new Cue(0d),
|
|
Setters =
|
|
{
|
|
new Setter(TranslateTransform.XProperty, 0d),
|
|
new Setter(Visual.OpacityProperty, 1d)
|
|
}
|
|
},
|
|
new KeyFrame
|
|
{
|
|
Cue = new Cue(1d),
|
|
Setters =
|
|
{
|
|
new Setter(TranslateTransform.XProperty, forward ? -distance : distance),
|
|
new Setter(Visual.OpacityProperty, 0d)
|
|
}
|
|
}
|
|
}
|
|
};
|
|
tasks.Add(anim.RunAsync(from, cancellationToken));
|
|
}
|
|
|
|
if (to != null)
|
|
{
|
|
to.IsVisible = true;
|
|
|
|
var anim = new Avalonia.Animation.Animation
|
|
{
|
|
FillMode = FillMode.Forward,
|
|
Easing = TransitionEasing,
|
|
Duration = Duration,
|
|
Children =
|
|
{
|
|
new KeyFrame
|
|
{
|
|
Cue = new Cue(0d),
|
|
Setters =
|
|
{
|
|
new Setter(TranslateTransform.XProperty, forward ? distance : -distance),
|
|
new Setter(Visual.OpacityProperty, 0d)
|
|
}
|
|
},
|
|
new KeyFrame
|
|
{
|
|
Cue = new Cue(1d),
|
|
Setters =
|
|
{
|
|
new Setter(TranslateTransform.XProperty, 0d),
|
|
new Setter(Visual.OpacityProperty, 1d)
|
|
}
|
|
}
|
|
}
|
|
};
|
|
tasks.Add(anim.RunAsync(to, cancellationToken));
|
|
}
|
|
|
|
await Task.WhenAll(tasks);
|
|
|
|
if (from != null && !cancellationToken.IsCancellationRequested)
|
|
from.IsVisible = false;
|
|
}
|
|
|
|
private static Visual GetVisualParent(Visual? from, Visual? to)
|
|
{
|
|
var p1 = (from ?? to)!.GetVisualParent();
|
|
if (from != null && to != null &&
|
|
!ReferenceEquals(from.GetVisualParent(), to.GetVisualParent()))
|
|
throw new ArgumentException("Transition elements have different parents.");
|
|
return p1 ?? throw new ArgumentException("Transition elements have no parent.");
|
|
}
|
|
}
|
|
}
|
|
|