Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const propName = {
const behaviorExp = /^(allow-discrete|normal)$/
const defaultValueExp = /^(inherit|initial|revert|revert-layer|unset)$/
const timingFunctionExp = /^(step-start|step-end|steps)/
const transitionKeys = ['transition', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction', 'transitionDelay'] as const
// cubic-bezier 参数解析
function getBezierParams (str: string) {
// ease 0.25, 0.1, 0.25, 1.0
Expand Down Expand Up @@ -94,6 +95,7 @@ function parseTransitionSingleProp (vals: string[], property: string) {
}
}).filter(item => item !== undefined)
}

// transition 解析
function parseTransitionStyle (originalStyle: ExtendedViewStyle) {
let transitionData: AnimationDataType[] = []
Expand Down Expand Up @@ -144,7 +146,7 @@ function parseTransitionStyle (originalStyle: ExtendedViewStyle) {
const transitionMap = transitionData.reduce((acc, cur) => {
// hasOwn(transitionSupportedProperty, dash2hump(val)) || val === Transform
const { property = '', duration = 0, delay = 0, easing = Easing.inOut(Easing.ease) } = cur
if ((hasOwn(transitionSupportedProperty, dash2hump(property)) || property === 'transform') && duration > 0) {
if ((hasOwn(transitionSupportedProperty, dash2hump(property)) || property === 'transform') && duration >= 0) {
acc[property] = {
duration,
delay,
Expand All @@ -162,19 +164,17 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
const { style: originalStyle = {}, transitionend } = props
// style变更标识(首次render不执行),初始值为0,首次渲染后为1
const animationDeps = useRef(0)
// 记录上次style map
// const lastStyleRef = useRef({} as {[propName: keyof ExtendedViewStyle]: number|string})
// ** 从 style 中获取动画数据
const transitionMap = useMemo(() => {
return parseTransitionStyle(originalStyle)
}, [])
// 记录上次 transition 相关属性,用于判断是否需要重新解析
const lastTransitionStyleRef = useRef<Partial<ExtendedViewStyle>>({})
// ** style prop sharedValue interpolateOutput: SharedValue<InterpolateOutput>
const { shareValMap, animatedKeys, animatedStyleKeys } = useMemo(() => {
const { shareValMap, animatedKeys, animatedStyleKeys, transitionMap } = useMemo(() => {
// 记录需要执行动画的 propName
const animatedKeys = [] as string[]
// 有动画样式的 style key(useAnimatedStyle使用)
const animatedStyleKeys = [] as (string|string[])[]
const transforms = [] as string[]
// ** 从 style 中获取动画数据
const transitionMap = parseTransitionStyle(originalStyle)
const shareValMap = Object.keys(transitionMap).reduce((valMap, property) => {
// const { property } = transition || {}
if (property === 'transform') {
Expand All @@ -199,9 +199,11 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
return {
shareValMap,
animatedKeys,
animatedStyleKeys
animatedStyleKeys,
transitionMap
}
}, [])
const transitionMapRef = useRef(transitionMap)
const runOnJSCallbackRef = useRef({})
const runOnJSCallback = useRunOnJSCallback(runOnJSCallbackRef)
// 根据 animation action 创建&驱动动画
Expand Down Expand Up @@ -234,7 +236,7 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
shareValMap[key].value = toVal
} else {
// console.log(`key=${key} oldVal=${shareValMap[key].value} newVal=${toVal}`)
const { delay = 0, duration, easing } = transitionMap[isTransformKey ? 'transform' : key]
const { delay = 0, duration = 0, easing = Easing.inOut(Easing.ease) } = transitionMapRef.current[isTransformKey ? 'transform' : key] || {}
// console.log('animationOptions=', { delay, duration, easing })
let callback
if (transitionend && (!isTransformKey || !transformTransitionendDone)) {
Expand Down Expand Up @@ -269,6 +271,23 @@ export default function useTransitionHooks<T, P> (props: AnimationHooksPropsType
animationDeps.current = 1
return
}
// 仅当 transition 相关属性变化时才重新解析
const prevStyle = lastTransitionStyleRef.current
const hasTransitionChanged = transitionKeys.some(key => prevStyle[key] !== originalStyle[key])
const currentTransitionMap = hasTransitionChanged
// 从当前 style 解析最新 timing
? parseTransitionStyle(originalStyle)
: transitionMapRef.current
if (hasTransitionChanged) {
lastTransitionStyleRef.current = {
transition: originalStyle.transition,
transitionDuration: originalStyle.transitionDuration,
transitionProperty: originalStyle.transitionProperty,
transitionTimingFunction: originalStyle.transitionTimingFunction,
transitionDelay: originalStyle.transitionDelay
}
transitionMapRef.current = currentTransitionMap
}
createAnimation()
}, [originalStyle])
// ** 清空动画
Expand Down
Loading