AnimationInfo.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. using System;
  2. using UnityEngine;
  3. namespace XCharts.Runtime
  4. {
  5. /// <summary>
  6. /// the animation info.
  7. /// ||动画配置参数。
  8. /// </summary>
  9. [Since("v3.8.0")]
  10. [System.Serializable]
  11. public class AnimationInfo
  12. {
  13. [SerializeField][Since("v3.8.0")] private bool m_Enable = true;
  14. [SerializeField][Since("v3.8.0")] private bool m_Reverse = false;
  15. [SerializeField][Since("v3.8.0")] private float m_Delay = 0;
  16. [SerializeField][Since("v3.8.0")] private float m_Duration = 1000;
  17. public AnimationInfoContext context = new AnimationInfoContext();
  18. /// <summary>
  19. /// whether enable animation.
  20. /// ||是否开启动画效果。
  21. /// </summary>
  22. public bool enable { get { return m_Enable; } set { m_Enable = value; } }
  23. /// <summary>
  24. /// whether enable reverse animation.
  25. /// ||是否开启反向动画效果。
  26. /// </summary>
  27. public bool reverse { get { return m_Reverse; } set { m_Reverse = value; } }
  28. /// <summary>
  29. /// the delay time before animation start.
  30. /// ||动画开始前的延迟时间。
  31. /// </summary>
  32. public float delay { get { return m_Delay; } set { m_Delay = value; } }
  33. /// <summary>
  34. /// the duration of animation.
  35. /// ||动画的时长。
  36. /// </summary>
  37. public float duration { get { return m_Duration; } set { m_Duration = value; } }
  38. /// <summary>
  39. /// the callback function of animation start.
  40. /// ||动画开始的回调。
  41. /// </summary>
  42. public Action OnAnimationStart { get; set; }
  43. /// <summary>
  44. /// the callback function of animation end.
  45. /// ||动画结束的回调。
  46. /// </summary>
  47. public Action OnAnimationEnd { get; set; }
  48. /// <summary>
  49. /// the delegate function of animation delay.
  50. /// ||动画延迟的委托函数。
  51. /// </summary>
  52. public AnimationDelayFunction delayFunction { get; set; }
  53. /// <summary>
  54. /// the delegate function of animation duration.
  55. /// ||动画时长的委托函数。
  56. /// </summary>
  57. public AnimationDurationFunction durationFunction { get; set; }
  58. /// <summary>
  59. /// Reset animation.
  60. /// ||重置动画。
  61. /// </summary>
  62. public void Reset()
  63. {
  64. if (!enable) return;
  65. context.init = false;
  66. context.start = false;
  67. context.pause = false;
  68. context.end = false;
  69. context.startTime = 0;
  70. context.currProgress = 0;
  71. context.destProgress = 0;
  72. context.totalProgress = 0;
  73. context.sizeProgress = 0;
  74. context.currPointIndex = 0;
  75. context.currPoint = Vector3.zero;
  76. context.destPoint = Vector3.zero;
  77. context.dataCurrProgress.Clear();
  78. context.dataDestProgress.Clear();
  79. }
  80. /// <summary>
  81. /// Start animation.
  82. /// ||开始动画。
  83. /// </summary>
  84. /// <param name="reset">是否重置上一次的参数</param>
  85. public void Start(bool reset = true)
  86. {
  87. if (!enable) return;
  88. if (context.start)
  89. {
  90. context.pause = false;
  91. return;
  92. }
  93. context.init = false;
  94. context.start = true;
  95. context.end = false;
  96. context.pause = false;
  97. context.startTime = Time.time;
  98. if (reset)
  99. {
  100. context.currProgress = 0;
  101. context.destProgress = 1;
  102. context.totalProgress = 0;
  103. context.sizeProgress = 0;
  104. context.dataCurrProgress.Clear();
  105. context.dataDestProgress.Clear();
  106. }
  107. if (OnAnimationStart != null)
  108. {
  109. OnAnimationStart();
  110. }
  111. }
  112. /// <summary>
  113. /// Pause animation.
  114. /// ||暂停动画。
  115. /// </summary>
  116. public void Pause()
  117. {
  118. if (!enable) return;
  119. if (!context.start || context.end) return;
  120. context.pause = true;
  121. }
  122. /// <summary>
  123. /// Resume animation.
  124. /// ||恢复动画。
  125. /// </summary>
  126. public void Resume()
  127. {
  128. if (!enable) return;
  129. if (!context.pause) return;
  130. context.pause = false;
  131. }
  132. /// <summary>
  133. /// End animation.
  134. /// ||结束动画。
  135. /// </summary>
  136. public void End()
  137. {
  138. if (!enable) return;
  139. if (!context.start || context.end) return;
  140. context.start = false;
  141. context.end = true;
  142. context.currPointIndex = context.destPointIndex;
  143. context.startTime = Time.time;
  144. if (OnAnimationEnd != null)
  145. {
  146. OnAnimationEnd();
  147. }
  148. }
  149. /// <summary>
  150. /// Initialize animation.
  151. /// ||初始化动画。
  152. /// </summary>
  153. /// <param name="curr">当前进度</param>
  154. /// <param name="dest">目标进度</param>
  155. /// <param name="totalPointIndex">目标索引</param>
  156. /// <returns></returns>
  157. public bool Init(float curr, float dest, int totalPointIndex)
  158. {
  159. if (!enable || !context.start) return false;
  160. if (context.init || context.end) return false;
  161. context.init = true;
  162. context.totalProgress = dest - curr;
  163. context.destPointIndex = totalPointIndex;
  164. if (reverse)
  165. {
  166. context.currProgress = dest;
  167. context.destProgress = curr;
  168. }
  169. else
  170. {
  171. context.currProgress = curr;
  172. context.destProgress = dest;
  173. }
  174. return true;
  175. }
  176. /// <summary>
  177. /// Whether animation is finish.
  178. /// ||动画是否结束。
  179. /// </summary>
  180. public bool IsFinish()
  181. {
  182. if (!context.start) return true;
  183. if (context.end) return true;
  184. if (context.pause) return false;
  185. if (!context.init) return false;
  186. return m_Reverse ? context.currProgress <= context.destProgress
  187. : context.currProgress >= context.destProgress;
  188. }
  189. /// <summary>
  190. /// Whether animation is in delay.
  191. /// ||动画是否在延迟中。
  192. /// </summary>
  193. public bool IsInDelay()
  194. {
  195. if (!context.start)
  196. return false;
  197. else
  198. return (m_Delay > 0 && Time.time - context.startTime < m_Delay / 1000);
  199. }
  200. /// <summary>
  201. /// Whether animation is in index delay.
  202. /// ||动画是否在索引延迟中。
  203. /// </summary>
  204. /// <param name="dataIndex"></param>
  205. /// <returns></returns>
  206. public bool IsInIndexDelay(int dataIndex)
  207. {
  208. if (context.start)
  209. return Time.time - context.startTime < GetIndexDelay(dataIndex) / 1000f;
  210. else
  211. return false;
  212. }
  213. /// <summary>
  214. /// Get animation delay.
  215. /// ||获取动画延迟。
  216. /// </summary>
  217. /// <param name="dataIndex"></param>
  218. /// <returns></returns>
  219. public float GetIndexDelay(int dataIndex)
  220. {
  221. if (!context.start) return 0;
  222. if (delayFunction != null)
  223. return delayFunction(dataIndex);
  224. return delay;
  225. }
  226. internal float GetCurrAnimationDuration(int dataIndex = -1)
  227. {
  228. if (dataIndex >= 0)
  229. {
  230. if (context.start && durationFunction != null)
  231. return durationFunction(dataIndex) / 1000f;
  232. }
  233. return m_Duration > 0 ? m_Duration / 1000 : 1f;
  234. }
  235. internal void SetDataCurrProgress(int index, float state)
  236. {
  237. context.dataCurrProgress[index] = state;
  238. }
  239. internal float GetDataCurrProgress(int index, float initValue, float destValue, ref bool isBarEnd)
  240. {
  241. if (IsInDelay())
  242. {
  243. isBarEnd = false;
  244. return initValue;
  245. }
  246. var c1 = !context.dataCurrProgress.ContainsKey(index);
  247. var c2 = !context.dataDestProgress.ContainsKey(index);
  248. if (c1 || c2)
  249. {
  250. if (c1)
  251. context.dataCurrProgress.Add(index, initValue);
  252. if (c2)
  253. context.dataDestProgress.Add(index, destValue);
  254. isBarEnd = false;
  255. }
  256. else
  257. {
  258. isBarEnd = context.dataCurrProgress[index] == context.dataDestProgress[index];
  259. }
  260. return context.dataCurrProgress[index];
  261. }
  262. internal void CheckProgress(double total, bool m_UnscaledTime)
  263. {
  264. if (!context.start || !context.init || context.pause) return;
  265. if (IsInDelay()) return;
  266. var duration = GetCurrAnimationDuration();
  267. var delta = (float)(total / duration * (m_UnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime));
  268. if (reverse)
  269. {
  270. context.currProgress -= delta;
  271. if (context.currProgress <= context.destProgress)
  272. {
  273. context.currProgress = context.destProgress;
  274. End();
  275. }
  276. }
  277. else
  278. {
  279. context.currProgress += delta;
  280. if (context.currProgress >= context.destProgress)
  281. {
  282. context.currProgress = context.destProgress;
  283. End();
  284. }
  285. }
  286. }
  287. internal float CheckItemProgress(int dataIndex, float destProgress, ref bool isEnd, float startProgress, bool m_UnscaledTime)
  288. {
  289. if (m_Reverse)
  290. {
  291. var temp = startProgress;
  292. startProgress = destProgress;
  293. destProgress = temp;
  294. }
  295. var currHig = GetDataCurrProgress(dataIndex, startProgress, destProgress, ref isEnd);
  296. if (IsFinish())
  297. {
  298. return destProgress;
  299. }
  300. else if (IsInDelay() || IsInIndexDelay(dataIndex))
  301. {
  302. return startProgress;
  303. }
  304. else if (context.pause)
  305. {
  306. return currHig;
  307. }
  308. else
  309. {
  310. var duration = GetCurrAnimationDuration(dataIndex);
  311. var delta = (destProgress - startProgress) / duration * (m_UnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime);
  312. currHig += delta;
  313. if (reverse)
  314. {
  315. if ((destProgress > 0 && currHig <= 0) || (destProgress < 0 && currHig >= 0))
  316. {
  317. currHig = 0;
  318. isEnd = true;
  319. }
  320. }
  321. else
  322. {
  323. if ((destProgress - startProgress > 0 && currHig > destProgress) ||
  324. (destProgress - startProgress < 0 && currHig < destProgress))
  325. {
  326. currHig = destProgress;
  327. isEnd = true;
  328. }
  329. }
  330. SetDataCurrProgress(dataIndex, currHig);
  331. return currHig;
  332. }
  333. }
  334. internal void CheckSymbol(float dest, bool m_UnscaledTime)
  335. {
  336. if (!context.start || !context.init || context.pause) return;
  337. if (IsInDelay())
  338. return;
  339. var duration = GetCurrAnimationDuration();
  340. var delta = dest / duration * (m_UnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime);
  341. if (reverse)
  342. {
  343. context.sizeProgress -= delta;
  344. if (context.sizeProgress < 0)
  345. context.sizeProgress = 0;
  346. }
  347. else
  348. {
  349. context.sizeProgress += delta;
  350. if (context.sizeProgress > dest)
  351. context.sizeProgress = dest;
  352. }
  353. }
  354. }
  355. /// <summary>
  356. /// Fade in animation.
  357. /// ||淡入动画。
  358. /// </summary>
  359. [Since("v3.8.0")]
  360. [System.Serializable]
  361. public class AnimationFadeIn : AnimationInfo
  362. {
  363. }
  364. /// <summary>
  365. /// Fade out animation.
  366. /// ||淡出动画。
  367. /// </summary>
  368. [Since("v3.8.0")]
  369. [System.Serializable]
  370. public class AnimationFadeOut : AnimationInfo
  371. {
  372. }
  373. /// <summary>
  374. /// Data change animation.
  375. /// ||数据变更动画。
  376. /// </summary>
  377. [Since("v3.8.0")]
  378. [System.Serializable]
  379. public class AnimationChange : AnimationInfo
  380. {
  381. }
  382. /// <summary>
  383. /// Data addition animation.
  384. /// ||数据新增动画。
  385. /// </summary>
  386. [Since("v3.8.0")]
  387. [System.Serializable]
  388. public class AnimationAddition : AnimationInfo
  389. {
  390. }
  391. /// <summary>
  392. /// Data hiding animation.
  393. /// ||数据隐藏动画。
  394. /// </summary>
  395. [Since("v3.8.0")]
  396. [System.Serializable]
  397. public class AnimationHiding : AnimationInfo
  398. {
  399. }
  400. /// <summary>
  401. /// Interactive animation of charts.
  402. /// ||交互动画。
  403. /// </summary>
  404. [Since("v3.8.0")]
  405. [System.Serializable]
  406. public class AnimationInteraction : AnimationInfo
  407. {
  408. [SerializeField][Since("v3.8.0")] private MLValue m_Width = new MLValue(1.1f);
  409. [SerializeField][Since("v3.8.0")] private MLValue m_Radius = new MLValue(1.1f);
  410. [SerializeField][Since("v3.8.0")] private MLValue m_Offset = new MLValue(MLValue.Type.Absolute, 5f);
  411. /// <summary>
  412. /// the mlvalue of width.
  413. /// ||宽度的多样式数值。
  414. /// </summary>
  415. public MLValue width { get { return m_Width; } set { m_Width = value; } }
  416. /// <summary>
  417. /// the mlvalue of radius.
  418. /// ||半径的多样式数值。
  419. /// </summary>
  420. public MLValue radius { get { return m_Radius; } set { m_Radius = value; } }
  421. /// <summary>
  422. /// the mlvalue of offset. Such as the offset of the pie chart when the sector is selected.
  423. /// ||交互的多样式数值。如饼图的扇形选中时的偏移。
  424. /// </summary>
  425. public MLValue offset { get { return m_Offset; } set { m_Offset = value; } }
  426. public float GetRadius(float radius)
  427. {
  428. return m_Radius.GetValue(radius);
  429. }
  430. public float GetWidth(float width)
  431. {
  432. return m_Width.GetValue(width);
  433. }
  434. public float GetOffset(float total)
  435. {
  436. return m_Offset.GetValue(total);
  437. }
  438. public float GetOffset()
  439. {
  440. return m_Offset.value;
  441. }
  442. }
  443. }