skyouc
2024-12-21 c9c263dc43ad90f95f24a036cee9e6b47afb596c
uni_modules/uni-transition/components/uni-transition/createAnimation.js
New file
@@ -0,0 +1,128 @@
// const defaultOption = {
//    duration: 300,
//    timingFunction: 'linear',
//    delay: 0,
//    transformOrigin: '50% 50% 0'
// }
// #ifdef APP-NVUE
const nvueAnimation = uni.requireNativePlugin('animation')
// #endif
class MPAnimation {
   constructor(options, _this) {
      this.options = options
      this.animation = uni.createAnimation(options)
      this.currentStepAnimates = {}
      this.next = 0
      this.$ = _this
   }
   _nvuePushAnimates(type, args) {
      let aniObj = this.currentStepAnimates[this.next]
      let styles = {}
      if (!aniObj) {
         styles = {
            styles: {},
            config: {}
         }
      } else {
         styles = aniObj
      }
      if (animateTypes1.includes(type)) {
         if (!styles.styles.transform) {
            styles.styles.transform = ''
         }
         let unit = ''
         if(type === 'rotate'){
            unit = 'deg'
         }
         styles.styles.transform += `${type}(${args+unit}) `
      } else {
         styles.styles[type] = `${args}`
      }
      this.currentStepAnimates[this.next] = styles
   }
   _animateRun(styles = {}, config = {}) {
      let ref = this.$.$refs['ani'].ref
      if (!ref) return
      return new Promise((resolve, reject) => {
         nvueAnimation.transition(ref, {
            styles,
            ...config
         }, res => {
            resolve()
         })
      })
   }
   _nvueNextAnimate(animates, step = 0, fn) {
      let obj = animates[step]
      if (obj) {
         let {
            styles,
            config
         } = obj
         this._animateRun(styles, config).then(() => {
            step += 1
            this._nvueNextAnimate(animates, step, fn)
         })
      } else {
         this.currentStepAnimates = {}
         typeof fn === 'function' && fn()
         this.isEnd = true
      }
   }
   step(config = {}) {
      // #ifndef APP-NVUE
      this.animation.step(config)
      // #endif
      // #ifdef APP-NVUE
      this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
      this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
      this.next++
      // #endif
      return this
   }
   run(fn) {
      // #ifndef APP-NVUE
      this.$.animationData = this.animation.export()
      this.$.timer = setTimeout(() => {
         typeof fn === 'function' && fn()
      }, this.$.durationTime)
      // #endif
      // #ifdef APP-NVUE
      this.isEnd = false
      let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
      if(!ref) return
      this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
      this.next = 0
      // #endif
   }
}
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
   'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
   'translateZ'
]
const animateTypes2 = ['opacity', 'backgroundColor']
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
   MPAnimation.prototype[type] = function(...args) {
      // #ifndef APP-NVUE
      this.animation[type](...args)
      // #endif
      // #ifdef APP-NVUE
      this._nvuePushAnimates(type, args)
      // #endif
      return this
   }
})
export function createAnimation(option, _this) {
   if(!_this) return
   clearTimeout(_this.timer)
   return new MPAnimation(option, _this)
}