Reputation: 834
I would like to make part of a Touchable
traslucid, i.e, to be able to see the background behind it.
A possible hack is to use MaskedView
and draw my background again, inside the Touchable
, as the children
prop to MaskedView
. However, this only works for a limited number of scenarios. Here it is working:
However, as soon as I add some margin, for example, things get out of phase:
A couple clarifications, just in case:
Here is a MWE, using a view instead of an image, so that I don't need to bundle the png
file:
import React from 'react';
import {
View,
TouchableOpacity,
} from 'react-native';
import MaskedView from '@react-native-community/masked-view';
import LinearGradient from 'react-native-linear-gradient';
export default function () {
return (
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}}
colors={['red', 'blue', 'green']}
style={
{flex: 1,
alignItems: 'stretch',
justifyContent: 'center'}
}>
<TouchableOpacity>
<View style={
{height: 100,
alignItems: 'stretch',
justifyContent: 'center',
backgroundColor: 'white',
borderRadius: 30,
//marginLeft: 50, // -> if you uncomment this line, the translucid effect is ruined
}
}>
<MaskedView
style={{height: '100%', backgroundColor: 'yellow',
alignItems: 'stretch', justifyContent: 'center',
}}
maskElement={
<View style={{flex: 1, backgroundColor: 'transparent',
alignItems: 'center', justifyContent: 'center',
}}>
<View style={{width: 300, height: '100%', backgroundColor: 'black'}}/>
</View>
}
>
<LinearGradient start={{x: 0, y: 0}} end={{x: 1, y: 0}}
colors={['red', 'blue', 'green']}
style={{height: '100%'}}
/>
</MaskedView>
</View>
</TouchableOpacity>
</LinearGradient>
);
}
Upvotes: 0
Views: 1473
Reputation: 2574
Here's an expo snack to illustrate my comment: https://snack.expo.io/SkCNR7Iqr
The idea is, rather than rendering and then hiding content, just don't render anything there in the first place. This will render the white ends within the bounds of the button. The wrapper uses overflow: 'hidden'
to ensure that the Touchable effect will only appear within the bounded borderRadius
(more noticeable with TouchableHighlight), and it will ensure that the white ends and any other content in it will stay within the bounded borderRadius
.
import * as React from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native'
import { LinearGradient } from 'expo-linear-gradient'
export default class App extends React.Component {
render() {
return (
<LinearGradient
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 0 }}
colors={['red', 'blue', 'green']}
style={styles.gradient}>
<View style={styles.wrapper}>
<TouchableOpacity style={styles.touch}>
<View style={styles.end} />
<View style={styles.content} />
<View style={styles.end} />
</TouchableOpacity>
</View>
</LinearGradient>
);
}
}
const styles = StyleSheet.create({
gradient: {
flex: 1,
justifyContent: 'center'
},
wrapper: {
height: 100,
borderRadius: 30,
overflow: 'hidden',
marginLeft: 50,
flexDirection: 'row',
},
touch: {
flexDirection: 'row',
flex: 1,
},
end: {
width: 50,
backgroundColor: 'white',
height: '100%',
},
content: {
flex: 1,
}
});
Upvotes: 1