Open wzahedi opened 4 years ago
Same problem Doesn't work with Flatlist item
import React from 'react';
import { View, StyleSheet, Dimensions, FlatList, Image, Animated } from 'react-native';
import MaskedView from '@react-native-community/masked-view';
import Svg, { Rect } from 'react-native-svg';
import { LinearGradient } from 'expo-linear-gradient';
//
const { width, height } = Dimensions.get('window')
const ITEM_SIZE = width * 0.72
const BACKDROP_HEIGHT = height * 0.6
const AnimatedSvg = Animated.createAnimatedComponent(Svg)
const Backdrop = ({ movies, scrollX }) => {
return (
<View style={styles.backdrop}>
<FlatList
data={movies}
keyExtractor={item => item.key}
renderItem={({ item, index }) => {
if (!item.backdrop) {
return
}
const inputRange = [
(index - 2) * ITEM_SIZE,
(index - 1) * ITEM_SIZE
]
const translateX = scrollX.interpolate({
inputRange,
outputRange: [-width, 0]
})
return (
<MaskedView
style={StyleSheet.absoluteFill}
maskElement={
<AnimatedSvg
width={width}
height={height}
viewBox={`0 0 ${width} ${height}`}
style={{ transform: [{ translateY: translateX }]}}
>
<Rect
x="0"
y="0"
width={width}
height={height}
fill="red"
/>
</AnimatedSvg>
}
>
<Image
source={{ uri: item.backdrop }}
style={{
width,
height: 100,
resizeMode: 'cover'
}}
/>
</MaskedView>
)
}}
/>
<LinearGradient
colors= {[ 'transparent', 'red']}
style={{
width,
height: BACKDROP_HEIGHT,
position: 'absolute',
bottom: 0
}}
/>
</View>
);
};
const styles = StyleSheet.create({
backdrop: {
position: 'absolute',
top: 0,
width: width,
height: BACKDROP_HEIGHT,
},
})
export default Backdrop;
Any updates on this?
@j-rayhan For android,
Best way is use Animated.View
import React from "react";
import {
Dimensions,
FlatList,
Image,
StyleSheet,
View,
Animated,
} from "react-native";
import { LinearGradient } from "expo-linear-gradient";
import { BACKDROP_HEIGHT, ITEM_SIZE } from "../constants";
const { width, height } = Dimensions.get("window");
const BackDrop = ({ scrollX, movies }) => {
return (
<View style={{ height: BACKDROP_HEIGHT, width, position: "absolute" }}>
<FlatList
data={movies}
keyExtractor={(item) => item.key + "-backdrop"}
removeClippedSubviews={false}
contentContainerStyle={{ width, height: BACKDROP_HEIGHT }}
renderItem={({ item, index }) => {
if (!item.backdrop) {
return null;
}
const translateX = scrollX.interpolate({
inputRange: [(index - 2) * ITEM_SIZE, (index - 1) * ITEM_SIZE],
outputRange: [0, width],
// extrapolate:'clamp'
});
return (
<Animated.View
removeClippedSubviews={false}
style={{
position: "absolute",
width: translateX,
height,
overflow: "hidden",
}}>
<Image
source={{ uri: item.backdrop }}
style={{
width,
height: BACKDROP_HEIGHT,
position: "absolute",
}}
/>
</Animated.View>
);
}}
/>
<LinearGradient
colors={["rgba(0, 0, 0, 0)", "white"]}
style={{
height: BACKDROP_HEIGHT,
width,
position: "absolute",
bottom: 0,
}}
/>
</View>
);
};
export default BackDrop;
const styles = StyleSheet.create({
container: {
position: "absolute",
width,
height: BACKDROP_HEIGHT,
},
backdropImage: {
width,
height: BACKDROP_HEIGHT,
resizeMode: "cover",
},
absolute: { position: "absolute" },
gradient: {
width: width,
height: BACKDROP_HEIGHT,
position: "absolute",
bottom: 0,
},
});
and make sure u set useNativeDriver
to false
<Animated.FlatList
showsHorizontalScrollIndicator={false}
data={data}
keyExtractor={(item) => item.key}
horizontal
contentContainerStyle={{
alignItems: "center",
}}
snapToInterval={ITEM_SIZE} // maes the slide snap to one per scroll
decelerationRate={Platform.OS === "ios" ? 0 : 0.85} // makes the snap efective
renderToHardwareTextureAndroid
snapToAlignment="start"
bounces={false} // removes bounce on first slide
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { x: scrollX } } }],
{ useNativeDriver: Platform.OS === "ios" }
)} // making active bigger on scroll
scrollEventThrottle={16}
// .............................................. rest of code
I am trying to mask Flatlist elements using linear gradient as shown in the image below. The text on the "message bubbles" are not rendering. I was able to make the flatlist scrollable by going into MaskedView.js and making pointerEvents to "auto". I am using the Flatlist as the maskElement, and a LinearGradient (expo-linear-gradient) as the child. Let me know of any ideas please. Another option I am considering is using gl-react for this, however I want to see if I can simply fix the text not showing up using this library. Thanks!