animation.js 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /**
  2. * wuxing-sandbox-helpers/animation.js
  3. * 五角星填充动画控制器
  4. */
  5. /**
  6. * FillAnimator - 管理 ease-out cubic 填充动画
  7. * @param {Function} getCurrentTs - 返回当前 5 维插值数组 [0~1]
  8. * @param {Function} onFrame - 每帧回调,参数为插值后的 ts 数组
  9. * @param {Function} [onComplete] - 动画完成回调
  10. */
  11. export function FillAnimator(getCurrentTs, onFrame, onComplete) {
  12. this._getCurrentTs = getCurrentTs
  13. this._onFrame = onFrame
  14. this._onComplete = onComplete || function() {}
  15. this._timer = null
  16. }
  17. /**
  18. * 启动动画
  19. * @param {Array<number>} targetTs - 目标 5 维值 (0~1)
  20. * @param {number} [duration=600] - 动画时长 ms
  21. */
  22. FillAnimator.prototype.start = function(targetTs, duration) {
  23. this.cancel()
  24. var dur = duration || 600
  25. var startTime = Date.now()
  26. var startTs = this._getCurrentTs()
  27. var self = this
  28. function step() {
  29. var elapsed = Date.now() - startTime
  30. var progress = Math.min(elapsed / dur, 1)
  31. // ease-out cubic
  32. var eased = 1 - Math.pow(1 - progress, 3)
  33. var interpolated = []
  34. for (var i = 0; i < 5; i++) {
  35. interpolated.push(startTs[i] + (targetTs[i] - startTs[i]) * eased)
  36. }
  37. self._onFrame(interpolated)
  38. if (progress < 1) {
  39. self._timer = setTimeout(step, 16)
  40. } else {
  41. self._timer = null
  42. self._onComplete()
  43. }
  44. }
  45. step()
  46. }
  47. /**
  48. * 取消动画,清理 timer
  49. */
  50. FillAnimator.prototype.cancel = function() {
  51. if (this._timer) {
  52. clearTimeout(this._timer)
  53. this._timer = null
  54. }
  55. }