vue.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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. import { CreateAnimationOptions } from './type'
  13. // #ifdef APP-NVUE
  14. const nvueAnimation = uni.requireNativePlugin('animation')
  15. type AnimationTypes = 'matrix' | 'matrix3d' | 'rotate' | 'rotate3d' | 'rotateX' | 'rotateY' | 'rotateZ' | 'scale' | 'scale3d' | 'scaleX' | 'scaleY' | 'scaleZ' | 'skew' | 'skewX' | 'skewY' | 'translate' | 'translate3d' | 'translateX' | 'translateY' | 'translateZ'
  16. | 'opacity' | 'backgroundColor' | 'width' | 'height' | 'left' | 'right' | 'top' | 'bottom'
  17. interface Styles {
  18. [key : string] : any
  19. }
  20. interface StepConfig {
  21. duration?: number
  22. timingFunction?: string
  23. delay?: number
  24. needLayout?: boolean
  25. transformOrigin?: string
  26. }
  27. interface StepAnimate {
  28. styles?: Styles
  29. config?: StepConfig
  30. }
  31. interface StepAnimates {
  32. [key: number]: StepAnimate
  33. }
  34. // export interface CreateAnimationOptions extends UniApp.CreateAnimationOptions {
  35. // ref?: string
  36. // }
  37. type Callback = (time: number) => void
  38. const animateTypes1 : AnimationTypes[] = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
  39. 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
  40. 'translateZ'
  41. ]
  42. const animateTypes2 : AnimationTypes[] = ['opacity', 'backgroundColor']
  43. const animateTypes3 : AnimationTypes[] = ['width', 'height', 'left', 'right', 'top', 'bottom']
  44. class LimeAnimation {
  45. ref : any
  46. context : any
  47. options : UniApp.CreateAnimationOptions
  48. // stack : any[] = []
  49. next : number = 0
  50. currentStepAnimates : StepAnimates = {}
  51. duration : number = 0
  52. constructor(options : CreateAnimationOptions) {
  53. const {ref} = options
  54. this.ref = ref
  55. this.options = options
  56. }
  57. addAnimate(type : AnimationTypes, args: (string | number)[]) {
  58. let aniObj = this.currentStepAnimates[this.next]
  59. let stepAnimate:StepAnimate = {}
  60. if (!aniObj) {
  61. stepAnimate = {styles: {}, config: {}}
  62. } else {
  63. stepAnimate = aniObj
  64. }
  65. if (animateTypes1.includes(type)) {
  66. if (!stepAnimate.styles.transform) {
  67. stepAnimate.styles.transform = ''
  68. }
  69. let unit = ''
  70. if (type === 'rotate') {
  71. unit = 'deg'
  72. }
  73. stepAnimate.styles.transform += `${type}(${args.map((v: number) => v + unit).join(',')}) `
  74. } else {
  75. stepAnimate.styles[type] = `${args.join(',')}`
  76. }
  77. this.currentStepAnimates[this.next] = stepAnimate
  78. }
  79. animateRun(styles: Styles = {}, config:StepConfig = {}, ref: any) {
  80. const el = ref || this.ref
  81. if (!el) return
  82. return new Promise((resolve) => {
  83. const time = +new Date()
  84. nvueAnimation.transition(el, {
  85. styles,
  86. ...config
  87. }, () => {
  88. resolve(+new Date() - time)
  89. })
  90. })
  91. }
  92. nextAnimate(animates: StepAnimates, step: number = 0, ref: any, cb: Callback) {
  93. let obj = animates[step]
  94. if (obj) {
  95. let { styles, config } = obj
  96. // this.duration += config.duration
  97. this.animateRun(styles, config, ref).then((time: number) => {
  98. step += 1
  99. this.duration += time
  100. this.nextAnimate(animates, step, ref, cb)
  101. })
  102. } else {
  103. this.currentStepAnimates = {}
  104. cb && cb(this.duration)
  105. }
  106. }
  107. step(config:StepConfig = {}) {
  108. this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
  109. this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
  110. this.next++
  111. return this
  112. }
  113. export(ref: any, cb?: Callback) {
  114. ref = ref || this.ref
  115. if(!ref) return
  116. this.duration = 0
  117. this.next = 0
  118. this.nextAnimate(this.currentStepAnimates, 0, ref, cb)
  119. return null
  120. }
  121. }
  122. animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
  123. LimeAnimation.prototype[type] = function(...args: (string | number)[]) {
  124. this.addAnimate(type, args)
  125. return this
  126. }
  127. })
  128. // #endif
  129. export function createAnimation(options : CreateAnimationOptions) {
  130. // #ifndef APP-NVUE
  131. return uni.createAnimation({ ...options })
  132. // #endif
  133. // #ifdef APP-NVUE
  134. return new LimeAnimation(options)
  135. // #endif
  136. }