Files
XCharts/Runtime/Component/Sub/SerieAnimation.cs
monitor1394 489095865d XCharts 2.0
2021-01-11 08:54:28 +08:00

513 lines
17 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.
/************************************************/
/* */
/* Copyright (c) 2018 - 2021 monitor1394 */
/* https://github.com/monitor1394 */
/* */
/************************************************/
using System.Collections.Generic;
using UnityEngine;
using System;
namespace XCharts
{
public delegate float CustomAnimationDelay(int dataIndex);
public delegate float CustomAnimationDuration(int dataIndex);
/// <summary>
/// the animation of serie.
/// 动画表现。
/// </summary>
[System.Serializable]
public class SerieAnimation : SubComponent
{
public enum Easing
{
Linear,
}
[SerializeField] private bool m_Enable = true;
[SerializeField] private Easing m_Easting;
[SerializeField] private int m_Threshold = 2000;
[SerializeField] private float m_FadeInDuration = 1000;
[SerializeField] private float m_FadeInDelay = 0;
[SerializeField] private float m_FadeOutDuration = 1000f;
[SerializeField] private float m_FadeOutDelay = 0;
[SerializeField] private bool m_DataChangeEnable = true;
[SerializeField] private float m_DataChangeDuration = 500;
[SerializeField] private float m_ActualDuration;
/// <summary>
/// 自定义渐入动画延时函数。返回ms值。
/// </summary>
public CustomAnimationDelay customFadeInDelay;
/// <summary>
/// 自定义渐入动画时长函数。返回ms值。
/// </summary>
public CustomAnimationDuration customFadeInDuration;
/// <summary>
/// 自定义渐出动画延时函数。返回ms值。
/// </summary>
public CustomAnimationDelay customFadeOutDelay;
/// <summary>
/// 自定义渐出动画时长函数。返回ms值。
/// </summary>
public CustomAnimationDuration customFadeOutDuration;
/// <summary>
/// Whether to enable animation.
/// 是否开启动画效果。
/// </summary>
public bool enable { get { return m_Enable; } set { m_Enable = value; } }
/// <summary>
/// Easing method used for the first animation.
/// 动画的缓动效果。
/// </summary>
//public Easing easing { get { return m_Easting; } set { m_Easting = value; } }
/// <summary>
/// The milliseconds duration of the fadeIn animation.
/// 设定的渐入动画时长毫秒。如果要设置单个数据项的渐入时长可以用代码定制customFadeInDuration。
/// </summary>
public float fadeInDuration { get { return m_FadeInDuration; } set { m_FadeInDuration = value < 0 ? 0 : value; } }
/// <summary>
/// The milliseconds duration of the fadeOut animation.
/// 设定的渐出动画时长毫秒。如果要设置单个数据项的渐出时长可以用代码定制customFadeOutDuration。
/// </summary>
public float fadeOutDuration { get { return m_FadeOutDuration; } set { m_FadeOutDuration = value < 0 ? 0 : value; } }
/// <summary>
/// The milliseconds actual duration of the first animation.
/// 实际的动画时长(毫秒)。
/// </summary>
public float actualDuration { get { return m_ActualDuration; } }
/// <summary>
/// Whether to set graphic number threshold to animation. Animation will be disabled when graphic number is larger than threshold.
/// 是否开启动画的阈值,当单个系列显示的图形数量大于这个阈值时会关闭动画。
/// </summary>
public int threshold { get { return m_Threshold; } set { m_Threshold = value; } }
/// <summary>
/// The milliseconds delay before updating the first animation.
/// 渐入动画延时毫秒。如果要设置单个数据项的延时可以用代码定制customFadeInDelay。
/// </summary>
public float fadeInDelay { get { return m_FadeInDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
/// <summary>
/// 渐出动画延时毫秒。如果要设置单个数据项的延时可以用代码定制customFadeOutDelay。
/// </summary>
public float fadeOutDelay { get { return m_FadeOutDelay; } set { m_FadeInDelay = value < 0 ? 0 : value; } }
/// <summary>
/// 是否开启数据变更动画。
/// </summary>
public bool dataChangeEnable { get { return m_DataChangeEnable; } set { m_DataChangeEnable = value; } }
/// <summary>
/// The milliseconds duration of the data change animation.
/// 数据变更的动画时长(毫秒)。
/// </summary>
public float dataChangeDuration { get { return m_DataChangeDuration; } set { m_DataChangeDuration = value < 0 ? 0 : value; } }
/// <summary>
/// 渐入动画完成回调
/// </summary>
public Action fadeInFinishCallback { get; set; }
/// <summary>
/// 渐出动画完成回调
/// </summary>
public Action fadeOutFinishCallback { get; set; }
private Dictionary<int, float> m_DataCurrProgress = new Dictionary<int, float>();
private Dictionary<int, float> m_DataDestProgress = new Dictionary<int, float>();
private bool m_FadeIn = false;
private bool m_IsEnd = true;
private bool m_IsPause = false;
private bool m_FadeOut = false;
private bool m_FadeOuted = false;
private bool m_IsInit = false;
private float startTime { get; set; }
private int m_CurrDataProgress { get; set; }
private int m_DestDataProgress { get; set; }
[SerializeField] private float m_CurrDetailProgress;
[SerializeField] private float m_DestDetailProgress;
private float m_CurrSymbolProgress;
public void FadeIn()
{
if (m_FadeOut) return;
if (m_IsPause)
{
m_IsPause = false;
return;
}
if (m_FadeIn) return;
startTime = Time.time;
m_FadeIn = true;
m_IsEnd = false;
m_IsInit = false;
m_IsPause = false;
m_FadeOuted = false;
m_CurrDataProgress = 1;
m_DestDataProgress = 1;
m_CurrDetailProgress = 0;
m_DestDetailProgress = 1;
m_CurrSymbolProgress = 0;
m_DataCurrProgress.Clear();
m_DataDestProgress.Clear();
}
public void Restart()
{
Reset();
FadeIn();
}
public void FadeOut()
{
if (m_IsPause)
{
m_IsPause = false;
return;
}
m_FadeOut = true;
startTime = Time.time;
m_FadeIn = true;
m_IsEnd = false;
m_IsInit = false;
m_IsPause = false;
m_CurrDataProgress = 0;
m_DestDataProgress = 0;
m_CurrDetailProgress = 0;
m_DestDetailProgress = 1;
m_CurrSymbolProgress = 0;
m_DataCurrProgress.Clear();
m_DataDestProgress.Clear();
}
public void Pause()
{
if (!m_IsPause)
{
m_IsPause = true;
}
}
public void Resume()
{
if (m_IsPause)
{
m_IsPause = false;
}
}
private void End()
{
if (m_IsEnd) return;
m_ActualDuration = (int)((Time.time - startTime) * 1000) - (m_FadeOut ? fadeOutDelay : fadeInDelay);
m_CurrDataProgress = m_DestDataProgress + (m_FadeOut ? -1 : 1);
m_IsEnd = true;
m_IsInit = false;
if (m_FadeIn)
{
m_FadeIn = false;
if (fadeInFinishCallback != null)
{
fadeInFinishCallback();
}
}
if (m_FadeOut)
{
m_FadeOut = false;
m_FadeOuted = true;
if (fadeOutFinishCallback != null)
{
fadeOutFinishCallback();
}
}
}
public void Reset()
{
m_FadeIn = false;
m_IsEnd = true;
m_IsInit = false;
m_IsPause = false;
m_FadeOut = false;
m_FadeOuted = false;
m_DataCurrProgress.Clear();
}
public void InitProgress(int data, float curr, float dest)
{
if (m_IsInit || m_IsEnd) return;
if (curr > dest) return;
m_IsInit = true;
m_DestDataProgress = data;
if (m_FadeOut)
{
m_CurrDetailProgress = dest;
m_DestDetailProgress = curr;
}
else
{
m_CurrDetailProgress = curr;
m_DestDetailProgress = dest;
}
}
public void SetDataFinish(int dataIndex)
{
if (m_IsEnd) return;
m_CurrDataProgress = dataIndex + (m_FadeOut ? -1 : 1);
}
private void SetDataCurrProgress(int index, float state)
{
m_DataCurrProgress[index] = state;
}
private float GetDataCurrProgress(int index, float initValue, float destValue, out bool isBarEnd)
{
if (IsInDelay())
{
isBarEnd = false;
return initValue;
}
var c1 = !m_DataCurrProgress.ContainsKey(index);
var c2 = !m_DataDestProgress.ContainsKey(index);
if (c1 || c2)
{
if (c1) m_DataCurrProgress.Add(index, initValue);
if (c2) m_DataDestProgress.Add(index, destValue);
isBarEnd = false;
}
else
{
isBarEnd = m_DataCurrProgress[index] == m_DataDestProgress[index];
}
return m_DataCurrProgress[index];
}
public bool IsFinish()
{
#if UNITY_EDITOR
if (!Application.isPlaying) return true;
#endif
return !m_Enable || m_IsEnd || (m_CurrDataProgress > m_DestDataProgress && m_CurrDetailProgress > m_DestDetailProgress);
}
public bool IsInFadeOut()
{
return m_FadeOut;
}
public bool IsInDelay()
{
if (m_FadeOut) return (fadeOutDelay > 0 && Time.time - startTime < fadeOutDelay / 1000);
return (fadeInDelay > 0 && Time.time - startTime < fadeInDelay / 1000);
}
public float GetDataDelay(int dataIndex)
{
if (m_FadeOut && customFadeOutDelay != null) return customFadeOutDelay(dataIndex);
if (m_FadeIn && customFadeInDelay != null) return customFadeInDelay(dataIndex);
return 0;
}
public bool IsInDataDelay(int dataIndex)
{
return Time.time - startTime < GetDataDelay(dataIndex) / 1000f;
}
public bool IsAllOutDelay(int dataCount)
{
var nowTime = Time.time - startTime;
for (int i = 0; i < dataCount; i++)
{
if (nowTime < GetDataDelay(i) / 1000) return false;
}
return true;
}
public bool IsAllDataFinishProgress(int dataCount)
{
for (int i = 0; i < dataCount; i++)
{
if (m_DataDestProgress.ContainsKey(i) && m_DataCurrProgress.ContainsKey(i))
{
if (m_DataCurrProgress[i] != m_DataDestProgress[i]) return false;
}
else
{
return false;
}
}
return true;
}
public bool CheckDetailBreak(float detail)
{
return !IsFinish() && detail > m_CurrDetailProgress;
}
public bool CheckDetailBreak(Vector3 pos, bool isYAxis)
{
if (IsFinish()) return false;
if (isYAxis) return pos.y > m_CurrDetailProgress;
else return pos.x > m_CurrDetailProgress;
}
public bool NeedAnimation(int dataIndex)
{
if (!m_Enable || m_IsEnd) return true;
if (IsInDelay()) return false;
if (m_FadeOut) return dataIndex > 0;
else return dataIndex <= m_CurrDataProgress;
}
internal void CheckProgress(float total)
{
if (IsFinish()) return;
if (!m_IsInit || m_IsPause || m_IsEnd) return;
if (IsInDelay()) return;
m_ActualDuration = (int)((Time.time - startTime) * 1000) - fadeInDelay;
var duration = GetCurrAnimationDuration();
var delta = total / duration * Time.deltaTime;
if (m_FadeOut)
{
m_CurrDetailProgress -= delta;
if (m_CurrDetailProgress <= m_DestDetailProgress)
{
m_CurrDetailProgress = m_DestDetailProgress;
End();
}
}
else
{
m_CurrDetailProgress += delta;
if (m_CurrDetailProgress >= m_DestDetailProgress)
{
m_CurrDetailProgress = m_DestDetailProgress;
End();
}
}
}
internal float GetCurrAnimationDuration(int dataIndex = -1)
{
if (dataIndex >= 0)
{
if (m_FadeOut && customFadeOutDuration != null) return customFadeOutDuration(dataIndex) / 1000f;
if (m_FadeIn && customFadeInDuration != null) return customFadeInDuration(dataIndex) / 1000f;
}
if (m_FadeOut) return m_FadeOutDuration > 0 ? m_FadeOutDuration / 1000 : 1f;
else return m_FadeInDuration > 0 ? m_FadeInDuration / 1000 : 1f;
}
internal float CheckBarProgress(int dataIndex, float barHig, int dataCount, out bool isBarEnd)
{
isBarEnd = false;
var initHig = m_FadeOut ? barHig : 0;
var destHig = m_FadeOut ? 0 : barHig;
var currHig = GetDataCurrProgress(dataIndex, initHig, destHig, out isBarEnd);
if (isBarEnd || IsFinish())
{
return m_FadeOuted ? 0 : barHig;
}
else if (IsInDelay() || IsInDataDelay(dataIndex))
{
return m_FadeOut ? barHig : 0;
}
else if (m_IsPause)
{
return currHig;
}
else
{
var duration = GetCurrAnimationDuration(dataIndex);
var delta = barHig / duration * Time.deltaTime;
currHig = currHig + (m_FadeOut ? -delta : delta);
if (m_FadeOut)
{
if ((initHig > 0 && currHig <= 0) || (initHig < 0 && currHig >= 0))
{
currHig = 0;
isBarEnd = true;
}
}
else if (Mathf.Abs(currHig) >= Mathf.Abs(barHig))
{
currHig = barHig;
isBarEnd = true;
}
SetDataCurrProgress(dataIndex, currHig);
return currHig;
}
}
internal void AllBarEnd()
{
End();
}
internal void CheckSymbol(float dest)
{
if (!enable || m_IsEnd || m_IsPause || !m_IsInit) return;
if (IsInDelay()) return;
var duration = GetCurrAnimationDuration();
var delta = dest / duration * Time.deltaTime;
if (m_FadeOut)
{
m_CurrSymbolProgress -= delta;
if (m_CurrSymbolProgress < 0) m_CurrSymbolProgress = 0;
}
else
{
m_CurrSymbolProgress += delta;
if (m_CurrSymbolProgress > dest) m_CurrSymbolProgress = dest;
}
}
public float GetSysmbolSize(float dest)
{
#if UNITY_EDITOR
if (!Application.isPlaying) return dest;
#endif
if (!enable) return dest;
if (m_IsEnd) return m_FadeOut ? 0 : dest;
return m_CurrSymbolProgress;
}
public float GetCurrDetail()
{
return m_CurrDetailProgress;
}
public float GetCurrRate()
{
#if UNITY_EDITOR
if (!Application.isPlaying) return 1;
#endif
if (!enable || m_IsEnd) return 1;
return m_CurrDetailProgress;
}
public int GetCurrIndex()
{
#if UNITY_EDITOR
if (!Application.isPlaying) return -1;
#endif
if (!enable || m_IsEnd) return -1;
return (int)m_CurrDetailProgress;
}
public float GetCurrData()
{
return m_CurrDataProgress;
}
public float GetUpdateAnimationDuration()
{
if (m_Enable && m_DataChangeEnable && IsFinish()) return m_DataChangeDuration;
else return 0;
}
public bool HasFadeOut()
{
return enable && m_FadeOuted && m_IsEnd;
}
}
}