AlohaKit.Animations
AlohaKit.Animations copied to clipboard
I want to share a few animations, and "Simultaneous storyboard"
Simultaneous storyboard
A storyboard that triggers all child animations at the same time instead of sequentially.
Ex:
<ak:SimultaneousStoryBoard x:Key="FlipRight" Target="{x:Reference ZonePanel}">
<ak:StoryBoard>
<ak:RotateYToAnimation Rotation="90" Duration="150"/>
<ak:RotateYToAnimation Rotation="-90" Duration="0" />
<ak:RotateYToAnimation Rotation="0" Duration="150" />
</ak:StoryBoard>
<ak:ExecAnimation Delay="150" Execute="ExecAnimation_OnExecute" />
</ak:SimultaneousStoryBoard>
[ContentProperty(nameof(Animations))]
public class SimultaneousStoryBoard : AnimationBase
{
public SimultaneousStoryBoard() => Animations = new();
public SimultaneousStoryBoard(List<AnimationBase> animations) => Animations = animations;
public List<AnimationBase> Animations { get; }
protected override async Task BeginAnimation()
{
var storyBoard = this;
var tasks = new List<Task>();
foreach (var animation in storyBoard.Animations)
{
animation.Target ??= storyBoard.Target;
tasks.Add(Task.Run(() => animation.Begin()));
}
await Task.WhenAll(tasks);
}
}
ExecAnimation
Adds an animation step that can trigger a method. Typically when a storybard is triggered by a behavior
Ex:
<ak:ExecAnimation Delay="150" Execute="ExecAnimation_OnExecute" />
public class ExecAnimation : AnimationBase
{
public event EventHandler<EventArgs> Execute;
protected override Task BeginAnimation()
{
Execute?.Invoke(this, EventArgs.Empty);
return Task.CompletedTask;
}
}
TranslateTo2Animation
An improved TranslateTo animation with offset and multipliers
/// <summary>
/// TranslateX final = (TranslateX * TranslateXMultiplier) + TranslateXOffset
/// </summary>
public class TranslateTo2Animation : AnimationBase
{
public static readonly BindableProperty TranslateXProperty = BindableProperty.Create(nameof (TranslateX), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public static readonly BindableProperty TranslateXOffsetProperty = BindableProperty.Create(nameof (TranslateXOffset), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public static readonly BindableProperty TranslateXMultiplierProperty = BindableProperty.Create(nameof (TranslateXMultiplier), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public static readonly BindableProperty TranslateYProperty = BindableProperty.Create(nameof (TranslateY), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public static readonly BindableProperty TranslateYOffsetProperty = BindableProperty.Create(nameof (TranslateYOffset), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public static readonly BindableProperty TranslateYMultiplierProperty = BindableProperty.Create(nameof (TranslateYMultiplier), typeof (double), typeof (TranslateToAnimation), (object) 0.0, BindingMode.TwoWay);
public double TranslateX
{
get => (double) GetValue(TranslateXProperty);
set => SetValue(TranslateXProperty, value);
}
public double TranslateXOffset
{
get => (double) GetValue(TranslateXOffsetProperty);
set => SetValue(TranslateXOffsetProperty, value);
}
public double TranslateXMultiplier
{
get => (double) GetValue(TranslateXMultiplierProperty);
set => SetValue(TranslateXMultiplierProperty, value);
}
public double TranslateY
{
get => (double) GetValue(TranslateYProperty);
set => SetValue(TranslateYProperty, value);
}
public double TranslateYOffset
{
get => (double) GetValue(TranslateYOffsetProperty);
set => SetValue(TranslateYOffsetProperty, value);
}
public double TranslateYMultiplier
{
get => (double) GetValue(TranslateYMultiplierProperty);
set => SetValue(TranslateYMultiplierProperty, value);
}
protected override Task BeginAnimation()
{
if (Target == null)
throw new NullReferenceException("Null Target property.");
return Target.TranslateTo((TranslateX*TranslateXMultiplier)+TranslateXOffset, (TranslateY*TranslateYMultiplier)+TranslateYOffset, Convert.ToUInt32(Duration), EasingHelper.GetEasing(Easing));
}
}
ShowHideAnimation
An animation step that is used to show or hide a View at some point in a storyboard.
Ex usage:
<ak:SimultaneousStoryBoard x:Key="ZoomOpen" Target="{x:Reference ZonePanel}">
<ak:FadeToAnimation Opacity="0" Duration="250" />
<ak:FadeToAnimation Opacity="0" Duration="250" Target="{x:Reference FrontSwitch}" />
<ak:ExecAnimation Delay="250" Execute="ZoomOpenAnimationFinished_OnExecute" />
<ak:FadeToAnimation Opacity="1" Duration="150" Delay="350" />
<ak:StoryBoard Delay="350" Target="{x:Reference UnzoomButton}">
<ak:ShowHideAnimation Show="True" />
<ak:FadeToAnimation Opacity="1" Duration="150" />
</ak:StoryBoard>
</ak:SimultaneousStoryBoard>
public class ShowHideAnimation : AnimationBase
{
public static readonly BindableProperty ShowProperty = BindableProperty.Create(nameof(Show), typeof (bool), typeof (ShowHideAnimation));
public bool Show
{
get => (bool) GetValue(ShowProperty);
set => SetValue(ShowProperty, value);
}
protected override async Task BeginAnimation()
{
if (Target == null)
throw new NullReferenceException("Null Target property.");
await MainThread.InvokeOnMainThreadAsync(() => Target.IsVisible = Show);
}
}
A "3D" Flip animation, left or right
<ak:SimultaneousStoryBoard x:Key="FlipRight" Target="{x:Reference ZonePanel}">
<ak:StoryBoard>
<ak:RotateYToAnimation Rotation="90" Duration="150"/>
<ak:RotateYToAnimation Rotation="-90" Duration="0" />
<ak:RotateYToAnimation Rotation="0" Duration="150" />
</ak:StoryBoard>
<ak:ExecAnimation Delay="150" Execute="ExecAnimation_OnExecute" />
</ak:SimultaneousStoryBoard>
<ak:SimultaneousStoryBoard x:Key="FlipLeft" Target="{x:Reference ZonePanel}">
<ak:StoryBoard>
<ak:RotateYToAnimation Rotation="-90" Duration="150" />
<ak:RotateYToAnimation Rotation="90" Duration="0"/>
<ak:RotateYToAnimation Rotation="0" Duration="150"/>
</ak:StoryBoard>
<ak:ExecAnimation Delay="150" Execute="ExecAnimation_OnExecute" />
</ak:SimultaneousStoryBoard>