AlohaKit.Animations icon indicating copy to clipboard operation
AlohaKit.Animations copied to clipboard

I want to share a few animations, and "Simultaneous storyboard"

Open softlion opened this issue 6 months ago • 0 comments

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>

softlion avatar Aug 01 '25 05:08 softlion