function converPx (value) {
|
if (/^-?\d+[ur]px$/i.test(value)) {
|
return value.replace(/(^-?\d+)[ur]px$/i, (text, num) => {
|
return `${uni.upx2px(parseFloat(num))}px`
|
})
|
// eslint-disable-next-line no-useless-escape
|
} else if (/^-?[\d\.]+$/.test(value)) {
|
return `${value}px`
|
}
|
return value || ''
|
}
|
|
function converType (type) {
|
return type.replace(/[A-Z]/g, text => {
|
return `-${text.toLowerCase()}`
|
}).replace('webkit', '-webkit')
|
}
|
|
function getStyle (action) {
|
const animateTypes1 = ['matrix', 'matrix3d', 'scale', 'scale3d', 'rotate3d', 'skew', 'translate', 'translate3d']
|
const animateTypes2 = ['scaleX', 'scaleY', 'scaleZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'skewX', 'skewY', 'translateX', 'translateY', 'translateZ']
|
const animateTypes3 = ['opacity', 'background-color']
|
const animateTypes4 = ['width', 'height', 'left', 'right', 'top', 'bottom']
|
const animates = action.animates
|
const option = action.option
|
const transition = option.transition
|
const style = {}
|
const transform = []
|
animates.forEach(animate => {
|
let type = animate.type
|
let args = [...animate.args]
|
if (animateTypes1.concat(animateTypes2).includes(type)) {
|
if (type.startsWith('rotate') || type.startsWith('skew')) {
|
args = args.map(value => parseFloat(value) + 'deg')
|
} else if (type.startsWith('translate')) {
|
args = args.map(converPx)
|
}
|
if (animateTypes2.indexOf(type) >= 0) {
|
args.length = 1
|
}
|
transform.push(`${type}(${args.join(',')})`)
|
} else if (animateTypes3.concat(animateTypes4).includes(args[0])) {
|
type = args[0]
|
const value = args[1]
|
style[type] = animateTypes4.includes(type) ? converPx(value) : value
|
}
|
})
|
style.transform = style.webkitTransform = transform.join(' ')
|
style.transition = style.webkitTransition = Object.keys(style).map(type => `${converType(type)} ${transition.duration}ms ${transition.timingFunction} ${transition.delay}ms`).join(',')
|
style.transformOrigin = style.webkitTransformOrigin = option.transformOrigin
|
return style
|
}
|
|
export function startAnimation (context) {
|
const animation = context.animation
|
if (!animation || !animation.actions || !animation.actions.length) {
|
return
|
}
|
let index = 0
|
const actions = animation.actions
|
const length = animation.actions.length
|
function animate () {
|
const action = actions[index]
|
const transition = action.option.transition
|
const style = getStyle(action)
|
Object.keys(style).forEach(key => {
|
context.$el.style[key] = style[key]
|
})
|
|
index += 1
|
if (index < length) {
|
setTimeout(animate, transition.duration + transition.delay)
|
}
|
}
|
|
setTimeout(() => {
|
animate()
|
}, 0)
|
}
|
|
export default {
|
props: ['animation'],
|
watch: {
|
animation () {
|
startAnimation(this)
|
}
|
},
|
mounted () {
|
startAnimation(this)
|
}
|
}
|