riversong code showcase
This commit is contained in:
112
Source/Riversong/Game/UI/Framework/UIVisibilityAnimation.cs
Normal file
112
Source/Riversong/Game/UI/Framework/UIVisibilityAnimation.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using PrimeTween;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace DanieleMarotta.RiversongCodeShowcase
|
||||
{
|
||||
public class UIVisibilityAnimation
|
||||
{
|
||||
private VisualElement _element;
|
||||
|
||||
private Action<bool> _onCompleted;
|
||||
|
||||
private Sequence _visibilityAnimation;
|
||||
|
||||
public UIVisibilityAnimation(VisualElement element, Action<bool> onCompleted)
|
||||
{
|
||||
_element = element;
|
||||
_onCompleted = onCompleted;
|
||||
|
||||
IsOpen = element.resolvedStyle.display != DisplayStyle.None;
|
||||
TargetIsOpen = IsOpen;
|
||||
|
||||
ApplyCommittedState(IsOpen);
|
||||
}
|
||||
|
||||
public bool IsOpen { get; private set; }
|
||||
|
||||
public bool TargetIsOpen { get; private set; }
|
||||
|
||||
public bool IsAnimating => _visibilityAnimation.isAlive;
|
||||
|
||||
public void Show(bool show, bool animate = false)
|
||||
{
|
||||
TargetIsOpen = show;
|
||||
|
||||
if (IsAnimating) return;
|
||||
if (IsOpen == TargetIsOpen) return;
|
||||
|
||||
if (!animate)
|
||||
{
|
||||
ApplyCommittedState(TargetIsOpen);
|
||||
IsOpen = TargetIsOpen;
|
||||
_onCompleted?.Invoke(IsOpen);
|
||||
return;
|
||||
}
|
||||
|
||||
TryAdvance();
|
||||
}
|
||||
|
||||
private void TryAdvance()
|
||||
{
|
||||
if (IsAnimating) return;
|
||||
if (IsOpen == TargetIsOpen) return;
|
||||
|
||||
if (TargetIsOpen)
|
||||
PlayOpenAnimation();
|
||||
else
|
||||
PlayCloseAnimation();
|
||||
}
|
||||
|
||||
private void PlayOpenAnimation()
|
||||
{
|
||||
_element.style.display = DisplayStyle.Flex;
|
||||
_visibilityAnimation = PlayShowTween(_element).OnComplete(() => CompleteTransition(true));
|
||||
}
|
||||
|
||||
private void PlayCloseAnimation()
|
||||
{
|
||||
_element.style.display = DisplayStyle.Flex;
|
||||
_visibilityAnimation = PlayHideTween(_element).OnComplete(() => CompleteTransition(false));
|
||||
}
|
||||
|
||||
private void CompleteTransition(bool isOpen)
|
||||
{
|
||||
_visibilityAnimation = default;
|
||||
ApplyCommittedState(isOpen);
|
||||
IsOpen = isOpen;
|
||||
_onCompleted?.Invoke(IsOpen);
|
||||
TryAdvance();
|
||||
}
|
||||
|
||||
private void ApplyCommittedState(bool isOpen)
|
||||
{
|
||||
_element.style.display = isOpen ? DisplayStyle.Flex : DisplayStyle.None;
|
||||
_element.style.opacity = isOpen ? 1 : 0;
|
||||
if (isOpen)
|
||||
_element.style.scale = StyleKeyword.Null;
|
||||
else
|
||||
_element.SetScale(0.8f);
|
||||
}
|
||||
|
||||
public static Sequence PlayShowTween(VisualElement element, float duration = 0.3f)
|
||||
{
|
||||
element.style.opacity = 0;
|
||||
element.SetScale(0.8f);
|
||||
|
||||
return Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Custom(0.8f, 1, duration, element.SetScale, Ease.OutQuad))
|
||||
.Group(Tween.Custom(0, 1, duration, value => element.style.opacity = value, Ease.OutQuad));
|
||||
}
|
||||
|
||||
public static Sequence PlayHideTween(VisualElement element, float duration = 0.2f)
|
||||
{
|
||||
element.style.opacity = 1;
|
||||
element.SetScale(1);
|
||||
|
||||
return Sequence.Create(useUnscaledTime: true)
|
||||
.Group(Tween.Custom(1, 0.8f, duration, value => element.SetScale(value), Ease.OutQuad))
|
||||
.Group(Tween.Custom(1, 0, duration, value => element.style.opacity = value, Ease.OutQuad));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user