UNPKG

react-native-ripple-button-reanimated

Version:

React Native Button with ripple effect. It works for android and ios.

102 lines (95 loc) 3.2 kB
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } import * as React from 'react'; import { StyleSheet, View } from 'react-native'; import { State, TapGestureHandler } from 'react-native-gesture-handler'; import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated'; import { hexToRgbA } from './hexToRgba'; function RippleButton({ children, color, borderRadius, onPress = () => {}, rippleScale = 1, duration = 250, overflow = false, rippleColor = '#000', rippleOpacity = 0.5 }) { const [radius, setRadius] = React.useState(-1); const child = React.Children.only(children); const scale = useSharedValue(0); const positionX = useSharedValue(0); const positionY = useSharedValue(0); const state = useSharedValue(State.UNDETERMINED); const isFinished = useSharedValue(false); const uas = useAnimatedStyle(() => ({ top: positionY.value - radius, left: positionX.value - radius, transform: [{ scale: scale.value }] }), [radius]); return /*#__PURE__*/React.createElement(TapGestureHandler, { maxDurationMs: 9999999999, onHandlerStateChange: event => { state.value = event.nativeEvent.state; positionX.value = event.nativeEvent.x; positionY.value = event.nativeEvent.y; scale.value = event.nativeEvent.state !== State.FAILED ? withTiming(rippleScale, { duration, easing: Easing.bezier(0, 0, 0.8, 0.4) }, finised => { if (finised) { isFinished.value = true; scale.value = withTiming(0, { duration: 0 }); } if (state.value === State.BEGAN && finised) { scale.value = withTiming(1, { duration: 0 }); } }) : 0; if (event.nativeEvent.state === State.BEGAN) { isFinished.value = false; } if (event.nativeEvent.state === State.END) { if (isFinished.value) { scale.value = withTiming(0, { duration: 0 }); } onPress(); } } }, /*#__PURE__*/React.createElement(Animated.View, _extends({}, child.props, { style: child.props.style }), /*#__PURE__*/React.createElement(View, { style: { ...StyleSheet.absoluteFillObject, borderRadius, backgroundColor: color, overflow: !overflow ? 'hidden' : undefined }, onLayout: ({ nativeEvent: { layout: { width, height } } }) => { setRadius(Math.sqrt(width ** 2 + height ** 2)); } }, radius !== -1 && /*#__PURE__*/React.createElement(Animated.View, { style: [uas, { position: 'absolute', width: radius * 2, height: radius * 2, borderRadius: radius, backgroundColor: hexToRgbA(rippleColor, rippleOpacity) }] })), child.props.children)); } export default RippleButton; //# sourceMappingURL=RippleButton.js.map