Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
duration,
toValue: new A.Value(0),
easing: easing || Easing.inOut(Easing.ease),
};
return A.block([
// stop opposite clock before running our animation
// to set last (previous) position as a current one
oppositeClock
? A.cond(
A.clockRunning(oppositeClock),
A.stopClock(oppositeClock),
)
: 0,
// run our animation clock
A.cond(
A.clockRunning(clock),
// do nothing if our clock is already running
0,
// otherwise pre set all the values
[
// If the clock isn't running we reset all the animation params and start the clock
A.set(state.finished, 0),
A.set(state.time, 0),
A.set(state.position, value),
A.set(state.frameTime, 0),
A.set(config.toValue, dest),
A.startClock(clock),
],
),
// we run the step here that is going to update position
A.timing(clock, state, config),
() =>
// when the active state changes
Animated.cond(Animated.neq(lastIsActive, tabIsActive), [
Animated.set(lastIsActive, tabIsActive),
Animated.cond(
tabIsActive,
[
// the tab just became active so we might need to adjust the scroll offset to avoid unwanted
// white space before allowing the scroll offset to affect the header position
Animated.cond(
Animated.greaterThan(Animated.multiply(-1, headerOffsetY), scrollOffsetY),
Animated.call([headerOffsetY], ([y]) => {
if (!flatListRef.current) {
throw new Error(
"Please make sure that tab content is wrapped with a StickyTabPageFlatList or a StickyTabPageScrollView"
)
}
flatListRef.current.getNode().scrollToOffset({ offset: -y, animated: false })
lockHeaderPosition.setValue(0)
}),
Animated.set(lockHeaderPosition, 0)
const nearTheTop = Animated.lessOrEq(scrollOffsetY, headerHeight)
// this is the code which actually performs the update to headerOffsetY, according to which direction
// the scrolling is going
const updateHeaderOffset = Animated.cond(
Animated.greaterThan(scrollDiff, 0),
[
// y offset got bigger so scrolling down (content travels up the screen)
// move the header up (hide it) unconditionally
Animated.set(headerOffsetY, Animated.max(-headerHeight, Animated.sub(headerOffsetY, scrollDiff))),
],
[
// y offset got smaller so scrolling up (content travels down the screen)
// if velocity is high enough or we're already moving the header up or we're near the top of the scroll view
// then move the header down (show it)
Animated.cond(Animated.or(upwardVelocityBreached, headerIsNotFullyUp, nearTheTop), [
Animated.set(headerOffsetY, Animated.min(0, Animated.sub(headerOffsetY, scrollDiff))),
]),
]
)
// we don't want to manipulate the header position while bouncing at the top or the bottom of the scroll view
// cause it feels weeeird
const notBouncingAtTheTop = Animated.greaterThan(scrollOffsetY, 0)
const notBouncingAtTheBottom = Animated.lessThan(scrollOffsetY, Animated.sub(contentHeight, layoutHeight))
const updateHeaderOffsetWhenNotBouncingOrLocked = Animated.cond(
Animated.and(notBouncingAtTheTop, notBouncingAtTheBottom, Animated.not(lockHeaderPosition)),
updateHeaderOffset,
// deref scroll diff to prevent diff buildup when ignoring changes
scrollDiff
)
const forwardTiming = getProperAnimation(
config,
!stateValue
? forwardAnimationConfig
: backwardAnimationConfig,
);
const backwardTiming = getProperAnimation(
config,
!stateValue
? backwardAnimationConfig
: forwardAnimationConfig,
);
animatedBlock.push(
A.cond(
A.eq(animationState, ANIMATION_STATE.PLAY_FORWARD),
forwardTiming,
),
A.cond(
A.eq(animationState, ANIMATION_STATE.PLAY_BACKWARD),
backwardTiming,
),
);
}
const item = config.values[key];
const inputRange = [0, config.animation.duration];
const outputRange = [item.from, item.to];
// reverse input range
) => {
const state = {
finished: new A.Value(0),
position: new A.Value(0),
time: new A.Value(0),
velocity: new A.Value(0),
};
const config = {
...transformSpringConfigToAnimatedValues(props.spring),
toValue: dest,
};
return A.block([
// stops opposite (opposite direction) clock
A.cond(
A.clockRunning(oppositeClock),
A.stopClock(oppositeClock),
0,
),
A.cond(A.clockRunning(clock), 0, [
updateStateProc(
value,
dest,
state.finished,
state.position,
state.time,
state.velocity,
config.toValue,
),
A.startClock(clock),
]),
const splitProgressProc = Animated.proc((normalizedProgress, isFocused) =>
Animated.cond(
Animated.eq(isFocused, 1),
// Focused screen
Animated.cond(
Animated.greaterThan(normalizedProgress, 0.5),
Animated.multiply(2, Animated.sub(normalizedProgress, 0.5)),
0,
),
// Screen we are moving from
Animated.cond(
Animated.lessThan(normalizedProgress, 0.5),
Animated.multiply(normalizedProgress, 2),
1,
),
),
);
// this is the code which actually performs the update to headerOffsetY, according to which direction
// the scrolling is going
const updateHeaderOffset = Animated.cond(
Animated.greaterThan(scrollDiff, 0),
[
// y offset got bigger so scrolling down (content travels up the screen)
// move the header up (hide it) unconditionally
Animated.set(amountScrolledUpward, 0),
Animated.set(headerOffsetY, Animated.max(negative(headerHeight), Animated.sub(headerOffsetY, scrollDiff))),
],
[
// y offset got smaller so scrolling up (content travels down the screen)
// if velocity is high enough or we're already moving the header up or we're near the top of the scroll view
// then move the header down (show it)
Animated.set(amountScrolledUpward, Animated.add(amountScrolledUpward, Animated.abs(scrollDiff))),
Animated.cond(Animated.or(upwardScrollThresholdBreached, headerIsNotFullyUp, nearTheTop), [
Animated.set(headerOffsetY, Animated.min(0, Animated.sub(headerOffsetY, scrollDiff))),
]),
]
)
// we don't want to manipulate the header position while bouncing at the top or the bottom of the scroll view
// cause it feels weeeird
const notBouncingAtTheTop = Animated.greaterThan(scrollOffsetY, 0)
const notBouncingAtTheBottom = Animated.lessThan(scrollOffsetY, Animated.sub(contentHeight, layoutHeight))
const updateHeaderOffsetWhenNotBouncing = Animated.cond(
Animated.and(notBouncingAtTheTop, notBouncingAtTheBottom),
updateHeaderOffset,
[
Animated.cond(
notBouncingAtTheTop,
const delta = (a0: Animated.Node, a: Animated.Node) => {
const da = sub(a0, a);
return cond(
greaterThan(abs(da), PI),
cond(greaterThan(a0, 0), sub(2 * PI, da), sub(-2 * PI, da)),
da
);
};
const styles = StyleSheet.create({
return arr.map((_, i) => {
const isZooming = Animated.eq(index, i);
return { opacity: Animated.cond(isZooming, opacity, 0) };
});
};
() =>
Animated.cond(Animated.neq(epoch, lastEpoch), [
Animated.set(lastEpoch, epoch),
Animated.call([...vals], vs => {
const cb = readCallback.current
readCallback.current = null
result.current = null
cb(
keys.reduce(
(acc, k, i) => {
acc[k] = vs[i]
return acc
},
{} as any
)
)
}),
]),