// --------------------------------------------------------------------------------------------------------------------
//
// Copyright (c) VRMADA, All rights reserved.
//
// --------------------------------------------------------------------------------------------------------------------
using System;
using System.Threading;
using System.Threading.Tasks;
using UltimateXR.Animation.Interpolation;
using UltimateXR.Extensions.System.Threading;
using UltimateXR.Extensions.Unity;
using UnityEngine;
namespace UltimateXR.Animation.UI
{
///
/// Tweening component to animate the of a component
/// programatically or using the inspector.
///
[RequireComponent(typeof(CanvasGroup))]
public class UxrCanvasAlphaTween : UxrTween
{
#region Inspector Properties/Serialized Fields
[SerializeField] private float _startAlpha;
[SerializeField] private float _endAlpha;
#endregion
#region Public Types & Data
public CanvasGroup TargetCanvasGroup => GetCachedComponent();
///
/// Animation start alpha
///
public float StartAlpha
{
get => _startAlpha;
set => _startAlpha = value;
}
///
/// Animation end alpha
///
public float EndAlpha
{
get => _endAlpha;
set => _endAlpha = value;
}
#endregion
#region Public Methods
///
/// Creates and starts a tweening animation for the value of a
/// component.
///
/// Target
/// Start alpha
/// End alpha
/// Interpolation settings that control the animation
/// Optional callback when the animation finished
///
/// Tweening component that will update itself automatically. Can be used to stop the animation prematurely or
/// change parameters on the fly.
///
public static UxrCanvasAlphaTween Animate(CanvasGroup canvasGroup, float startAlpha, float endAlpha, UxrInterpolationSettings settings, Action finishedCallback = null)
{
UxrCanvasAlphaTween canvasAlphaTween = canvasGroup.GetOrAddComponent();
canvasAlphaTween.StartAlpha = startAlpha;
canvasAlphaTween.EndAlpha = endAlpha;
canvasAlphaTween.InterpolationSettings = settings;
canvasAlphaTween.FinishedCallback = finishedCallback;
canvasAlphaTween.Restart();
return canvasAlphaTween;
}
///
/// Creates and starts a fade-in tweening animation for the value of a
/// component. The alpha value will go from 0.0 to 1.0.
///
/// Target
/// Duration in seconds of the fade-in animation
/// Seconds to wait until the animation starts
/// Optional callback when the animation finished
///
/// Tweening component that will update itself automatically. Can be used to stop the animation prematurely or
/// change parameters on the fly.
///
public static UxrCanvasAlphaTween FadeIn(CanvasGroup canvasGroup, float durationSeconds, float delaySeconds = 0.0f, Action finishedCallback = null)
{
return Animate(canvasGroup, 0.0f, 1.0f, new UxrInterpolationSettings(durationSeconds, delaySeconds), finishedCallback);
}
///
/// Creates and starts a fade-out tweening animation for the value of a
/// component. The alpha value will go from 1.0 to 0.0.
///
/// Target
/// Duration in seconds of the fade-in animation
/// Seconds to wait until the animation starts
/// Optional callback when the animation finished
///
/// Tweening component that will update itself automatically. Can be used to stop the animation prematurely or
/// change parameters on the fly.
///
public static UxrCanvasAlphaTween FadeOut(CanvasGroup canvasGroup, float durationSeconds, float delaySeconds = 0.0f, Action finishedCallback = null)
{
return Animate(canvasGroup, 1.0f, 0.0f, new UxrInterpolationSettings(durationSeconds, delaySeconds), finishedCallback);
}
///
/// Same as but for use with async/await.
///
///
/// Cancellation token to cancel the asynchronous animation. to
/// ignore.
///
/// Target
/// Start alpha
/// End alpha
/// Interpolation settings that control the animation
///
/// Task representing the asynchronous process.
///
public static Task AnimateAsync(CancellationToken ct, CanvasGroup canvasGroup, float startAlpha, float endAlpha, UxrInterpolationSettings settings)
{
if (ct.IsCancellationRequested)
{
return null;
}
bool hasFinishedFading = false;
UxrCanvasAlphaTween canvasAlphaTween = Animate(canvasGroup, startAlpha, endAlpha, settings, t => hasFinishedFading = true);
return TaskExt.WaitUntil(() => hasFinishedFading, settings.DelaySeconds + settings.DurationSeconds, () => canvasAlphaTween.Stop(), ct);
}
///
/// Same as but for use with async/await.
///
///
/// Cancellation token to cancel the asynchronous animation. to
/// ignore.
///
/// Target
/// Duration in seconds of the fade-in animation
/// Seconds to wait until the animation starts
///
/// Task representing the asynchronous process.
///
public static Task FadeInAsync(CancellationToken ct, CanvasGroup canvasGroup, float durationSeconds, float delaySeconds = 0.0f)
{
if (ct.IsCancellationRequested)
{
return null;
}
bool hasFinishedFading = false;
UxrCanvasAlphaTween canvasAlphaTween = FadeIn(canvasGroup, durationSeconds, delaySeconds, t => hasFinishedFading = true);
return TaskExt.WaitUntil(() => hasFinishedFading, delaySeconds + durationSeconds, () => canvasAlphaTween.Stop(), ct);
}
///
/// Same as but for use with async/await.
///
///
/// Cancellation token to cancel the asynchronous animation. to
/// ignore.
///
/// Target
/// Duration in seconds of the fade-in animation
/// Seconds to wait until the animation starts
///
/// Task representing the asynchronous process.
///
public static Task FadeOutAsync(CancellationToken ct, CanvasGroup canvasGroup, float durationSeconds, float delaySeconds = 0.0f)
{
if (ct.IsCancellationRequested)
{
return null;
}
bool hasFinishedFading = false;
UxrCanvasAlphaTween canvasAlphaTween = FadeOut(canvasGroup, durationSeconds, delaySeconds, t => hasFinishedFading = true);
return TaskExt.WaitUntil(() => hasFinishedFading, delaySeconds + durationSeconds, () => canvasAlphaTween.Stop(), ct);
}
#endregion
#region Protected Overrides UxrTween
///
protected override Behaviour TargetBehaviour => TargetCanvasGroup;
///
protected override void StoreOriginalValue()
{
_originalAlpha = TargetCanvasGroup.alpha;
}
///
protected override void RestoreOriginalValue()
{
TargetCanvasGroup.alpha = _originalAlpha;
}
///
protected override void Interpolate(float t)
{
TargetCanvasGroup.alpha = Mathf.Lerp(StartAlpha, EndAlpha, t);
}
#endregion
#region Private Types & Data
private float _originalAlpha;
private Behaviour _targetBehaviour;
#endregion
}
}