index.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // @ts-nocheck
  2. // nvue 需要在节点上设置ref或在export里传入
  3. // const animation = createAnimation({
  4. // ref: this.$refs['xxx'],
  5. // duration: 0,
  6. // timingFunction: 'linear'
  7. // })
  8. // animation.opacity(1).translate(x, y).step({duration})
  9. // animation.export(ref)
  10. // 抹平nvue 与 uni.createAnimation的使用差距
  11. // 但是nvue动画太慢~~~无语
  12. // #ifdef APP-NVUE
  13. const nvueAnimation = uni.requireNativePlugin('animation')
  14. type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
  15. | 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
  16. interface Styles {
  17. [key : string] : any
  18. }
  19. interface StepConfig {
  20. duration?: number
  21. timingFunction?: string
  22. delay?: number
  23. needLayout?: boolean
  24. transformOrigin?: string
  25. }
  26. interface StepAnimate {
  27. styles?: Styles
  28. config?: StepConfig
  29. }
  30. interface StepAnimates {
  31. [key: number]: StepAnimate
  32. }
  33. interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
  34. ref?: string
  35. }
  36. type Callback = (time: number) => void
  37. const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
  38. 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
  39. 'translateZ'
  40. ]
  41. const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
  42. const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
  43. class LimeAnimation {
  44. ref : any
  45. context : any
  46. options : UniApp.CreateAnimationOptions
  47. // stack : any[] = []
  48. next : number = 0
  49. currentStepAnimates : StepAnimates = {}
  50. duration : number = 0
  51. constructor(options : CreateAnimationOptions) {
  52. const {ref} = options
  53. this.ref = ref
  54. this.options = options
  55. }
  56. addAnimate(type : AnimationTypes, args: (string | number)[]) {
  57. let aniObj = this.currentStepAnimates[this.next]
  58. let stepAnimate:StepAnimate = {}
  59. if (!aniObj) {
  60. stepAnimate = {styles: {}, config: {}}
  61. } else {
  62. stepAnimate = aniObj
  63. }
  64. if (animateTypes1.includes(type)) {
  65. if (!stepAnimate.styles.transform) {
  66. stepAnimate.styles.transform = ''
  67. }
  68. let unit = ''
  69. if (type === 'rotate') {
  70. unit = 'deg'
  71. }
  72. stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
  73. } else {
  74. stepAnimate.styles[type] = `${args.join(',')}`
  75. }
  76. this.currentStepAnimates[this.next] = stepAnimate
  77. }
  78. animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
  79. const el = ref || this.ref
  80. if (!el) return
  81. return new Promise((resolve) => {
  82. const time = +new Date()
  83. nvueAnimation.transition(el, {
  84. styles,
  85. ...config
  86. }, () => {
  87. resolve(+new Date() - time)
  88. })
  89. })
  90. }
  91. nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
  92. let obj = animates[step]
  93. if (obj) {
  94. let { styles, config } = obj
  95. // this.duration += config.duration
  96. this.animateRun(styles, config, ref).then((time: number) => {
  97. step += 1
  98. this.duration += time
  99. this.nextAnimate(animates, step, ref, cb)
  100. })
  101. } else {
  102. this.currentStepAnimates = {}
  103. cb && cb(this.duration)
  104. }
  105. }
  106. step(config:StepConfig = {}) {
  107. this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
  108. this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
  109. this.next++
  110. return this
  111. }
  112. export(ref: any, cb?: Callback) {
  113. ref = ref || this.ref
  114. if(!ref) return
  115. this.duration = 0
  116. this.next = 0
  117. this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
  118. return null
  119. }
  120. }
  121. animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
  122. LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
  123. this.addAnimate(type, args)
  124. return this
  125. }
  126. })
  127. // #endif
  128. export function createAnimation(options : CreateAnimationOptions) {
  129. // #ifndef APP-NVUE
  130. // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
  131. return uni.createAnimation({ ...options })
  132. // #endif
  133. // #ifdef APP-NVUE
  134. return new LimeAnimation(options)
  135. // #endif
  136. }