@revrag-ai/embed-react-native
Version:
A powerful React Native library for integrating AI-powered voice agents into mobile applications. Features real-time voice communication, intelligent speech processing, customizable UI components, and comprehensive event handling for building conversation
181 lines (171 loc) • 5.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.usePopupAnimatedStyles = exports.useButtonAnimations = exports.useButtonAnimatedStyles = exports.useBreathingAnimation = exports.useAnimationValues = exports.createPanGesture = exports.Animated = void 0;
var _react = require("react");
var _reactNativeGestureHandler = require("react-native-gesture-handler");
var _reanimatedHelper = require("../utils/reanimated.helper.js");
var _EmbedButtonHelpers = require("./EmbedButton.helpers.js");
/**
* @file EmbedButton.animations.ts
* @description Animation logic and hooks for the EmbedButton component
*/
// Get reanimated API with fallbacks
const {
useSharedValue,
useAnimatedStyle,
withTiming,
withSpring,
withRepeat,
withSequence,
runOnJS,
Easing,
Animated,
isAvailable: isReanimatedAvailable
} = (0, _reanimatedHelper.getReanimatedAPI)();
// Show warning if reanimated is not available
exports.Animated = Animated;
if (!isReanimatedAvailable) {
(0, _reanimatedHelper.showReanimatedSetupError)();
}
// Export the Animated component for use in the main component
// ==================== ANIMATION VALUES HOOK ====================
/**
* Hook to initialize and manage all animation shared values
*/
const useAnimationValues = () => {
const isPressed = useSharedValue(false);
const offset = useSharedValue({
x: 0,
y: 0
});
const start = useSharedValue({
x: 0,
y: 0
});
const menuAnimation = useSharedValue(0);
const buttonWidth = useSharedValue(_EmbedButtonHelpers.BUTTON_DIMENSIONS.WIDTH);
const buttonScale = useSharedValue(1);
return {
isPressed,
offset,
start,
menuAnimation,
buttonWidth,
buttonScale
};
};
// ==================== BUTTON ANIMATIONS ====================
/**
* Hook to handle button expand/collapse animations
*/
exports.useAnimationValues = useAnimationValues;
const useButtonAnimations = (isOpen, menuAnimation, buttonWidth) => {
(0, _react.useEffect)(() => {
menuAnimation.value = withTiming(isOpen ? 0.8 : 0, {
duration: 300
});
buttonWidth.value = withTiming(isOpen ? _EmbedButtonHelpers.BUTTON_DIMENSIONS.EXPANDED_WIDTH : _EmbedButtonHelpers.BUTTON_DIMENSIONS.WIDTH);
}, [isOpen, menuAnimation, buttonWidth]);
};
// ==================== BREATHING ANIMATION ====================
/**
* Hook to handle breathing animation when auto-popup is shown
*/
exports.useButtonAnimations = useButtonAnimations;
const useBreathingAnimation = (isOpen, isAutoOpen, buttonScale) => {
(0, _react.useEffect)(() => {
if (!isOpen && isAutoOpen) {
// Start breathing animation
buttonScale.value = withRepeat(withSequence(withTiming(1.1, {
duration: 1500,
easing: Easing.inOut(Easing.ease)
}), withTiming(1, {
duration: 1500,
easing: Easing.inOut(Easing.ease)
})), -1,
// Infinite repeat
false);
} else {
// Reset animation
buttonScale.value = withTiming(1, {
duration: 300
});
}
}, [buttonScale, isAutoOpen, isOpen]);
};
// ==================== ANIMATED STYLES ====================
/**
* Hook to create animated styles for the button
*/
exports.useBreathingAnimation = useBreathingAnimation;
const useButtonAnimatedStyles = (isOpen, offset, buttonWidth, isPressed, buttonScale) => {
return useAnimatedStyle(() => {
const maxX = (0, _EmbedButtonHelpers.calculateMaxX)(isOpen);
const clampedX = (0, _EmbedButtonHelpers.clamp)(offset.value.x, -maxX, 0);
return {
width: buttonWidth.value,
height: _EmbedButtonHelpers.BUTTON_DIMENSIONS.HEIGHT,
transform: [{
translateX: clampedX
}, {
translateY: offset.value.y
}, {
scale: withSpring(isPressed.value ? 0.95 : buttonScale.value)
}],
justifyContent: isOpen ? 'space-between' : 'flex-start',
overflow: 'hidden'
};
});
};
/**
* Hook to create animated styles for the popup text
*/
exports.useButtonAnimatedStyles = useButtonAnimatedStyles;
const usePopupAnimatedStyles = (offset, isPressed) => {
return useAnimatedStyle(() => {
const maxX = _EmbedButtonHelpers.SCREEN_WIDTH;
const clampedX = (0, _EmbedButtonHelpers.clamp)(offset.value.x, -maxX, 0);
return {
transform: [{
translateX: clampedX
}, {
translateY: offset.value.y
}, {
scale: withSpring(isPressed.value ? 1 : 1)
}]
};
});
};
// ==================== GESTURE HANDLER ====================
/**
* Create pan gesture for drag functionality
*/
exports.usePopupAnimatedStyles = usePopupAnimatedStyles;
const createPanGesture = (isPressed, offset, start, isOpen, setIsAutoOpen) => {
return _reactNativeGestureHandler.Gesture.Pan().onBegin(() => {
isPressed.value = true;
if (setIsAutoOpen) {
runOnJS(setIsAutoOpen)(false);
}
}).onUpdate(e => {
const maxX = (0, _EmbedButtonHelpers.calculateMaxX)(isOpen);
const maxY = (0, _EmbedButtonHelpers.calculateMaxY)();
const newX = (0, _EmbedButtonHelpers.clamp)(e.translationX + start.value.x, -maxX, 0);
const newY = (0, _EmbedButtonHelpers.clamp)(e.translationY + start.value.y, -maxY, 0);
offset.value = {
x: newX,
y: newY
};
}).onEnd(() => {
start.value = {
x: offset.value.x,
y: offset.value.y
};
}).onFinalize(() => {
isPressed.value = false;
});
};
exports.createPanGesture = createPanGesture;
//# sourceMappingURL=EmbedButton.animations.js.map