ND_SimulationAutomaticControl/Assets/XCharts/Runtime/Component/Animation/AnimationInfo.cs

496 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using UnityEngine;
namespace XCharts.Runtime
{
/// <summary>
/// the animation info.
/// ||动画配置参数。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationInfo
{
[SerializeField][Since("v3.8.0")] private bool m_Enable = true;
[SerializeField][Since("v3.8.0")] private bool m_Reverse = false;
[SerializeField][Since("v3.8.0")] private float m_Delay = 0;
[SerializeField][Since("v3.8.0")] private float m_Duration = 1000;
[SerializeField][Since("v3.14.0")] private float m_Speed = 0;
public AnimationInfoContext context = new AnimationInfoContext();
/// <summary>
/// whether enable animation.
/// ||是否开启动画效果。
/// </summary>
public bool enable { get { return m_Enable; } set { m_Enable = value; } }
/// <summary>
/// whether enable reverse animation.
/// ||是否开启反向动画效果。
/// </summary>
public bool reverse { get { return m_Reverse; } set { m_Reverse = value; } }
/// <summary>
/// the delay time before animation start.
/// ||动画开始前的延迟时间。
/// </summary>
public float delay { get { return m_Delay; } set { m_Delay = value; } }
/// <summary>
/// the duration of animation. Default is used to calculate the speed of animation. It can also be specified by speed.
/// ||动画的时长。默认用于计算动画的速度。也可以通过speed指定速度。
/// </summary>
public float duration { get { return m_Duration; } set { m_Duration = value; } }
/// <summary>
/// the speed of animation. When speed is specified, duration will be invalid. Default is 0, which means no speed specified.
/// ||动画的速度。当指定speed时duration将失效。默认为0表示不指定速度。
/// </summary>
public float speed { get { return m_Speed; } set { m_Speed = value; } }
/// <summary>
/// the callback function of animation start.
/// ||动画开始的回调。
/// </summary>
public Action OnAnimationStart { get; set; }
/// <summary>
/// the callback function of animation end.
/// ||动画结束的回调。
/// </summary>
public Action OnAnimationEnd { get; set; }
/// <summary>
/// the delegate function of animation delay.
/// ||动画延迟的委托函数。
/// </summary>
public AnimationDelayFunction delayFunction { get; set; }
/// <summary>
/// the delegate function of animation duration.
/// ||动画时长的委托函数。
/// </summary>
public AnimationDurationFunction durationFunction { get; set; }
/// <summary>
/// Reset animation.
/// ||重置动画。
/// </summary>
public void Reset()
{
if (!enable) return;
context.init = false;
context.start = false;
context.pause = false;
context.end = false;
context.startTime = 0;
context.currProgress = 0;
context.destProgress = 0;
context.totalProgress = 0;
context.sizeProgress = 0;
context.currPointIndex = 0;
context.currPoint = Vector3.zero;
context.destPoint = Vector3.zero;
context.dataCurrProgress.Clear();
context.dataDestProgress.Clear();
}
/// <summary>
/// Start animation.
/// ||开始动画。
/// </summary>
/// <param name="reset">是否重置上一次的参数</param>
public void Start(bool reset = true)
{
if (!enable) return;
if (context.start)
{
context.pause = false;
return;
}
context.init = false;
context.start = true;
context.end = false;
context.pause = false;
context.startTime = Time.time;
if (reset)
{
context.currProgress = 0;
context.destProgress = 1;
context.totalProgress = 0;
context.sizeProgress = 0;
context.dataCurrProgress.Clear();
context.dataDestProgress.Clear();
}
if (OnAnimationStart != null)
{
OnAnimationStart();
}
}
/// <summary>
/// Pause animation.
/// ||暂停动画。
/// </summary>
public void Pause()
{
if (!enable) return;
if (!context.start || context.end) return;
context.pause = true;
}
/// <summary>
/// Resume animation.
/// ||恢复动画。
/// </summary>
public void Resume()
{
if (!enable) return;
if (!context.pause) return;
context.pause = false;
}
/// <summary>
/// End animation.
/// ||结束动画。
/// </summary>
public void End()
{
if (!enable) return;
if (!context.start || context.end) return;
context.init = false;
context.start = false;
context.end = true;
context.currPointIndex = context.destPointIndex;
context.startTime = Time.time;
if (OnAnimationEnd != null)
{
OnAnimationEnd();
}
}
/// <summary>
/// Initialize animation.
/// ||初始化动画。
/// </summary>
/// <param name="curr">当前进度</param>
/// <param name="dest">目标进度</param>
/// <param name="totalPointIndex">目标索引</param>
/// <returns></returns>
public bool Init(float curr, float dest, int totalPointIndex)
{
if (!enable || !context.start) return false;
context.totalProgress = dest - curr;
context.destPointIndex = totalPointIndex;
if (reverse)
{
if (!context.init) context.currProgress = dest;
context.destProgress = curr;
}
else
{
if (!context.init) context.currProgress = curr;
context.destProgress = dest;
}
context.init = true;
return true;
}
/// <summary>
/// Whether animation is finish.
/// ||动画是否结束。
/// </summary>
public bool IsFinish()
{
if (!context.start) return true;
if (context.end) return true;
if (context.pause) return false;
if (!context.init) return false;
return m_Reverse ? context.currProgress <= context.destProgress
: context.currProgress >= context.destProgress;
}
/// <summary>
/// Whether animation is in delay.
/// ||动画是否在延迟中。
/// </summary>
public bool IsInDelay()
{
if (!context.start)
return false;
else
return m_Delay > 0 && Time.time - context.startTime < m_Delay / 1000;
}
/// <summary>
/// Whether animation is in index delay.
/// ||动画是否在索引延迟中。
/// </summary>
/// <param name="dataIndex"></param>
/// <returns></returns>
public bool IsInIndexDelay(int dataIndex)
{
if (context.start)
return Time.time - context.startTime < GetIndexDelay(dataIndex) / 1000f;
else
return false;
}
/// <summary>
/// Get animation delay.
/// ||获取动画延迟。
/// </summary>
/// <param name="dataIndex"></param>
/// <returns></returns>
public float GetIndexDelay(int dataIndex)
{
if (!context.start) return 0;
if (delayFunction != null)
return delayFunction(dataIndex);
return delay;
}
internal float GetCurrAnimationDuration(int dataIndex = -1)
{
if (dataIndex >= 0)
{
if (context.start && durationFunction != null)
return durationFunction(dataIndex) / 1000f;
}
return m_Duration > 0 ? m_Duration / 1000 : 1f;
}
internal void SetDataCurrProgress(int index, float state)
{
context.dataCurrProgress[index] = state;
}
internal float GetDataCurrProgress(int index, float initValue, float destValue, ref bool isBarEnd)
{
if (IsInDelay())
{
isBarEnd = false;
return initValue;
}
var c1 = !context.dataCurrProgress.ContainsKey(index);
var c2 = !context.dataDestProgress.ContainsKey(index);
if (c1 || c2)
{
if (c1)
context.dataCurrProgress.Add(index, initValue);
if (c2)
context.dataDestProgress.Add(index, destValue);
isBarEnd = false;
}
else
{
isBarEnd = context.dataCurrProgress[index] == context.dataDestProgress[index];
}
return context.dataCurrProgress[index];
}
internal void CheckProgress(double total, bool m_UnscaledTime)
{
if (!context.start || !context.init || context.pause) return;
if (IsInDelay()) return;
var delta = GetDelta(total, m_UnscaledTime);
if (reverse)
{
context.currProgress -= delta;
if (context.currProgress <= context.destProgress)
{
context.currProgress = context.destProgress;
End();
}
}
else
{
context.currProgress += delta;
if (context.currProgress >= context.destProgress)
{
context.currProgress = context.destProgress;
End();
}
}
}
internal float CheckItemProgress(int dataIndex, float destProgress, ref bool isEnd, float startProgress, bool m_UnscaledTime)
{
if (m_Reverse)
{
var temp = startProgress;
startProgress = destProgress;
destProgress = temp;
}
var currHig = GetDataCurrProgress(dataIndex, startProgress, destProgress, ref isEnd);
if (IsFinish())
{
return destProgress;
}
else if (IsInDelay() || IsInIndexDelay(dataIndex))
{
return startProgress;
}
else if (context.pause)
{
return currHig;
}
else
{
var delta = GetDelta(destProgress - startProgress, m_UnscaledTime);
currHig += delta;
if (reverse)
{
if ((destProgress > 0 && currHig <= 0) || (destProgress < 0 && currHig >= 0))
{
currHig = 0;
isEnd = true;
}
}
else
{
if ((destProgress - startProgress > 0 && currHig > destProgress) ||
(destProgress - startProgress < 0 && currHig < destProgress))
{
currHig = destProgress;
isEnd = true;
}
}
SetDataCurrProgress(dataIndex, currHig);
return currHig;
}
}
internal void CheckSymbol(float dest, bool m_UnscaledTime)
{
if (!context.start || !context.init || context.pause) return;
if (IsInDelay())
return;
var delta = GetDelta(dest, m_UnscaledTime);
if (reverse)
{
context.sizeProgress -= delta;
if (context.sizeProgress < 0)
context.sizeProgress = 0;
}
else
{
context.sizeProgress += delta;
if (context.sizeProgress > dest)
context.sizeProgress = dest;
}
}
private float GetDelta(double total, bool unscaledTime)
{
if (m_Speed > 0)
{
context.currDuration = (float)total / m_Speed;
return (float)(m_Speed * (unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime));
}
else
{
context.currDuration = 0;
return (float)(total / GetCurrAnimationDuration() * (unscaledTime ? Time.unscaledDeltaTime : Time.deltaTime));
}
}
}
/// <summary>
/// Fade in animation.
/// ||淡入动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationFadeIn : AnimationInfo
{
}
/// <summary>
/// Fade out animation.
/// ||淡出动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationFadeOut : AnimationInfo
{
}
/// <summary>
/// Data change animation.
/// ||数据变更动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationChange : AnimationInfo
{
}
/// <summary>
/// Data addition animation.
/// ||数据新增动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationAddition : AnimationInfo
{
}
/// <summary>
/// Data hiding animation.
/// ||数据隐藏动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationHiding : AnimationInfo
{
}
/// <summary>
/// Interactive animation of charts.
/// ||交互动画。
/// </summary>
[Since("v3.8.0")]
[System.Serializable]
public class AnimationInteraction : AnimationInfo
{
[SerializeField][Since("v3.8.0")] private MLValue m_Width = new MLValue(1.1f);
[SerializeField][Since("v3.8.0")] private MLValue m_Radius = new MLValue(1.1f);
[SerializeField][Since("v3.8.0")] private MLValue m_Offset = new MLValue(MLValue.Type.Absolute, 5f);
/// <summary>
/// the mlvalue of width.
/// ||宽度的多样式数值。
/// </summary>
public MLValue width { get { return m_Width; } set { m_Width = value; } }
/// <summary>
/// the mlvalue of radius.
/// ||半径的多样式数值。
/// </summary>
public MLValue radius { get { return m_Radius; } set { m_Radius = value; } }
/// <summary>
/// the mlvalue of offset. Such as the offset of the pie chart when the sector is selected.
/// ||交互的多样式数值。如饼图的扇形选中时的偏移。
/// </summary>
public MLValue offset { get { return m_Offset; } set { m_Offset = value; } }
public float GetRadius(float radius)
{
return m_Radius.GetValue(radius);
}
public float GetWidth(float width)
{
return m_Width.GetValue(width);
}
public float GetOffset(float total)
{
return m_Offset.GetValue(total);
}
public float GetOffset()
{
return m_Offset.value;
}
}
}