Skip to content

Instantly share code, notes, and snippets.

@brunolemos
Created September 21, 2018 20:38
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brunolemos/664be3050a1481301d9e67285a7e433b to your computer and use it in GitHub Desktop.
Save brunolemos/664be3050a1481301d9e67285a7e433b to your computer and use it in GitHub Desktop.
Touchable component with Scale effect, common on iOS 12 (works on mobile and web)
// Demo: https://snack.expo.io/@brunolemos/touch-button-scale-effect
import React from 'react'
import { Animated, StyleProp, TouchableWithoutFeedback, TouchableWithoutFeedbackProps, ViewStyle } from 'react-native'
import { styleMerge } from 'shared/src/utils'
export interface TouchableScaleProps extends TouchableWithoutFeedbackProps {
containerStyle?: StyleProp<ViewStyle>
}
export class TouchableScale extends React.PureComponent<TouchableScaleProps> {
animatedValue = new Animated.Value(1)
handlePressIn: TouchableWithoutFeedbackProps['onPressIn'] = e => {
Animated.spring(this.animatedValue, {
toValue: 0.95,
speed: 30,
useNativeDriver: true,
}).start()
if (this.props.onPressIn) this.props.onPressIn(e)
}
handlePressOut: TouchableWithoutFeedbackProps['onPressOut'] = e => {
Animated.spring(this.animatedValue, {
toValue: 1,
friction: 100,
tension: 20,
useNativeDriver: true,
}).start()
if (this.props.onPressOut) this.props.onPressOut(e)
}
render() {
const { children, containerStyle, ...props } = this.props
delete props.onPressIn
delete props.onPressOut
const animatedStyle = {
transform: [{ scale: this.animatedValue }],
}
return (
<TouchableWithoutFeedback {...props} onPressIn={this.handlePressIn} onPressOut={this.handlePressOut}>
<Animated.View style={styleMerge(containerStyle, animatedStyle)}>{children}</Animated.View>
</TouchableWithoutFeedback>
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment