react-native-gesture-handler#TapGestureHandler JavaScript Examples
The following examples show how to use
react-native-gesture-handler#TapGestureHandler.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PatternLock.js From react-native-pattern-lock with MIT License | 4 votes |
export function PatternLock(props) { const [isError, setIsError] = useState(false); const canTouch = useSharedValue(true); const patternPoints = useSharedValue(); const selectedIndexes = useSharedValue([]); const endPoint = useSharedValue(); const containerLayout = useSharedValue({ width: 0, height: 0, min: 0 }); const R = useDerivedValue( () => (containerLayout.value.min / props.rowCount - props.patternMargin * 2) / 2 ); const cvc = useAnimatedStyle(() => ({ flexDirection: "row", flexWrap: "wrap", marginBottom: `${ Math.max( 0, containerLayout.value.height / containerLayout.value.width - 1.25 ) * 50 }%`, width: containerLayout.value.min, height: containerLayout.value.min, })); const msgX = useSharedValue(0); const msgColor = { color: isError ? props.errorColor : props.activeColor }; const msgStyle = useAnimatedStyle(() => { return { transform: [{ translateX: msgX.value }] }; }); const onContainerLayout = ({ nativeEvent: { layout: { x, y, width, height }, }, }) => (containerLayout.value = { width, height, min: Math.min(width, height), }); const onPatternLayout = ({ nativeEvent: { layout } }) => { const points = []; for (let i = 0; i < props.rowCount; i++) { for (let j = 0; j < props.columnCount; j++) { points.push({ x: layout.x + (layout.width / props.columnCount) * (j + 0.5), y: layout.y + (layout.height / props.rowCount) * (i + 0.5), }); } } patternPoints.value = points; }; const onEndJS = (res) => { if (props.onCheck) { canTouch.value = false; if (!props.onCheck(res)) { setIsError(true); const closeError = () => setIsError(false); runOnUI(() => { cancelAnimation(msgX); //修复iOS上原地spring不动的问题。 msgX.value = withSpring( msgX.value === 0 ? 0.1 : 0, { stiffness: 2000, damping: 10, mass: 1, velocity: 2000, }, (finished) => { runOnJS(closeError)(); canTouch.value = true; selectedIndexes.value = []; } ); })(); } else { setIsError(false); setTimeout(() => { selectedIndexes.value = []; canTouch.value = true; }, 1000); } } }; const panHandler = useAnimatedGestureHandler({ onStart: (evt) => { if ( canTouch.value && patternPoints.value && selectedIndexes.value.length === 0 ) { const selected = []; patternPoints.value.every((p, idx) => { if ( (p.x - evt.x) * (p.x - evt.x) + (p.y - evt.y) * (p.y - evt.y) < R.value * R.value ) { selected.push(idx); return false; } return true; }); selectedIndexes.value = selected; } }, onActive: (evt) => { if ( canTouch.value && patternPoints.value && selectedIndexes.value.length > 0 ) { patternPoints.value.every((p, idx) => { if ( (p.x - evt.x) * (p.x - evt.x) + (p.y - evt.y) * (p.y - evt.y) < R.value * R.value ) { if (selectedIndexes.value.indexOf(idx) < 0) { selectedIndexes.value = [...selectedIndexes.value, idx]; } return false; } return true; }); endPoint.value = { x: evt.x, y: evt.y }; } }, onEnd: (evt) => { if (!canTouch.value) return; endPoint.value = null; if (selectedIndexes.value.length > 0) runOnJS(onEndJS)(selectedIndexes.value.join("")); }, }); const animatedProps = useAnimatedProps(() => { let d = ""; selectedIndexes.value.forEach((idx) => { d += !d ? " M" : " L"; d += ` ${patternPoints.value[idx].x},${patternPoints.value[idx].y}`; }); if (d && endPoint.value) d += ` L${endPoint.value.x},${endPoint.value.y}`; if (!d) d = "M-1,-1"; return { d }; }); return ( <PanGestureHandler onGestureEvent={panHandler}> <Animated.View style={styles.container} onLayout={onContainerLayout}> <TapGestureHandler onGestureEvent={panHandler}> <Animated.View style={styles.container}> <View style={styles.msgc}> <Animated.Text style={[msgColor, msgStyle]}> {props.message} </Animated.Text> </View> <Animated.View style={cvc} onLayout={onPatternLayout}> {Array(props.rowCount * props.columnCount) .fill(0) .map((_, idx) => { const patternColor = useDerivedValue(() => { if (selectedIndexes.value.findIndex((v) => v === idx) < 0) { return props.inactiveColor; } else if (isError) { return props.errorColor; } else { return props.activeColor; } }); const outer = useAnimatedStyle(() => { return { borderWidth: 2, width: 2 * R.value, height: 2 * R.value, alignItems: "center", justifyContent: "center", borderColor: patternColor.value, borderRadius: 2 * R.value, margin: props.patternMargin, }; }); const inner = useAnimatedStyle(() => { return { width: R.value * 0.8, height: R.value * 0.8, borderRadius: R.value * 0.8, backgroundColor: patternColor.value, }; }); return ( <Animated.View key={idx} style={outer}> <Animated.View style={inner} /> </Animated.View> ); })} </Animated.View> <Svg style={styles.svg} width="100%" height="100%"> <AnimatedPath fill="none" strokeWidth={3} animatedProps={animatedProps} stroke={isError ? props.errorColor : props.activeColor} /> </Svg> </Animated.View> </TapGestureHandler> </Animated.View> </PanGestureHandler> ); }