Why is React Native Native Event pageX and pageY appearing inaccurate? - react-native

I'm making a simple drag and drop ReactNative component in my application where the component can be dragged from one location to another. I'm trying to figure out why my component is not responding correctly to changes in its position.
Even after setting the X and Y location to be pageX and pageY, it shifts downward first and slightly to the right. What is causing this slight change to happen?
Here's the code:
class Item extends React.Component
{
...
pressItem = (evt) => {
this.setState({shouldRotate: true});
if (evt.nativeEvent) {
let newX = evt.nativeEvent.pageX;
let newY = evt.nativeEvent.pageY;
this.state.x = newX;
this.state.y = newY;
}
};
...
render()
{
return (
<View onStartShouldSetResponder={() => true}
onResponderRelease={this.releaseItem}
onResponderMove={this.pressItem}
style={[
styles.item,
{top: this.state.y,position: 'absolute',
left: this.state.x,
}]}>
<Animated.Image source={this.props.imageURL}
resizeMode='contain'
style={{width: "100%", height: "100%",
transform: [{rotate: this.state.spin}]}}/>
</View>
)
}
}

Related

React native, view got cut off when rendered in flat list

So, I'm currently working on the react native project, I trying to add a tooltip component which once user tap the item in Flatlist. it will triggered this tooltip that have several options. The problem is now it got cut off even I set the 'position' to be 'absolute' with x,y position.
Is there anyway I can overcome this problem? I tried with the zIndex as well, but still not work out.
Here is the tooltip component that I implemented.
export function Tooltip({
children,
x,
y,
height,
width,
isVisible = false,
component,
}: TooltipProps) {
const [myWidth, setW] = useState(0)
const [myHeight, setH] = useState(0)
function onLayout({
nativeEvent: {
layout: {width, height},
},
}: LayoutChangeEvent) {
setW(width)
setH(height)
}
return (
<View>
{children}
{isVisible && (
<View
onLayout={onLayout}
style={{
elevation: 5,
borderWidth: 1,
backgroundColor: 'white',
position: 'absolute',
top: (height - componentHeight * 2) / 2 + y,
left: (width - componentWidth) / 2 + x,
}}>
{component}
</View>
)}
</View>
)
}
Here is the image in the app, (I need to blur out items there, sorry for inconvenience)
Tty to make parent view is SafeAreaView.
return(<SafeAreaView><YourComponent/></SafeAreaView>)
May be that can help.

Navigation using images nested inside Touchable Opacity

Background:
I've designed a custom footer for my app in React Native, I've set some images to act as icons. I'm trying to have them redirect to other pages of the app upon touch.
What I have tried
I've been trying to use the same images nested within TouchableOpacity components to have them redirect to other pages using react navigation.
This is my code:
export class Footer extends React.Component {
render (){
return (
<View style = { styles.footStyle } >
<TouchableOpacity onPress={ () => navigation.push('Home')} >
<Image
style = { styles.iconStyle }
source = {require('./img/home.png')}/>
</TouchableOpacity>
<TouchableOpacity onPress={ () => navigation.push('Favoritos')} >
<Image
style = { styles.iconStyle }
source = {require('./img/heart.png')}/>
</TouchableOpacity>
<TouchableOpacity onPress={ () => navigation.push('Search')} >
<Image
style = { styles.iconStyle }
source = {require('./img/search.png')}/>
</TouchableOpacity>
<TouchableOpacity onPress={ () => navigation.push('Notifications')} >
<Image
style = { styles.iconStyle }
source = {require('./img/bell.png')}/>
</TouchableOpacity>
<TouchableOpacity onPress={ () => navigation.push('Help')} >
<Image
style = { styles.iconStyle }
source = {require('./img/circle.png')}/>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
footStyle: {
paddingBottom: 0,
paddingRight: 10,
backgroundColor: '#ffffff',
flex: 0.4,
flexDirection: 'row',
borderTopWidth: 1,
borderTopColor: '#000000'
},
iconStyle: {
flex: 0.2,
height: undefined,
width: undefined
}
})
Problem
When I try and run the app in expo, the images are not rendering at all. I get my blank footer without any content. I've tried touching the footer to see if the images weren't rendering but the "button" actually worked, that didn't work.
Question
How exactly can I nest an image within a TouchableOpacity component? Is it even possible to use this method with React Navigation?
Thanks a lot!
For an Image component to work you should provide a height and width in style.
Here you are setting it as undefined
Try something like
iconStyle: {
flex: 0.2,
height: 100,
width: 100
}
Also on the navigation, you will have to pass the navigation prop to the Footer. As its a class you should access it as this.props.navigation.navigate()
As your code for integrating the Footer is not here, its hard to comment on how to pass the prop to the footer.

How to animate header to show based on scrolling in react native?

So Ideally, When i scroll down, I want the header to disappear(slide down) and when I scroll up I want it to show (slide up). Idc where im at in the page. I just want the animation to fire when those 2 events occur. I see some apps have this but I can't think of how to replicate it. please help me set a basis for this
You can use Animated.FlatList or Animated.ScrollView to make the scroll view, and attach a callback to listen onScroll event when it is changed. Then, using interpolation to map value between y-axis and opacity.
searchBarOpacityAnim is a component's state. By using Animated.event, the state will be updated when a callback is called. Also, don't forget to set useNativeDriver to be true. I've attached the link to document below about why you have to set it.
<Animated.FlatList
...
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: searchBarOpacityAnim } } }],
{ useNativeDriver: true },
)}
...
/>
Then, use Animated.View wraps your component which you want to animate it. Use .interpolate to map value between the state and component's opacity like the example below...
<Animated.View
style={{
opacity: searchBarOpacityAnim.interpolate({
inputRange: [213, 215],
outputRange: [0, 1],
}),
}}
>
<SearchBar />
</Animated.View>
You can read more information about useNativeDriver, .interpolate, and Animated.event here.
https://facebook.github.io/react-native/docs/animated#using-the-native-driver
https://facebook.github.io/react-native/docs/animations#interpolation
https://facebook.github.io/react-native/docs/animated#handling-gestures-and-other-events
You can use Animated from 'react-native'
here an example changing the Topbar height:
import { Animated } from 'react-native';
define maxHeight and minHeight topbar
const HEADER_MAX_HEIGHT = 120;
const HEADER_MIN_HEIGHT = 48;
initialize a variable with the scrollY value
constructor(props) {
super(props);
this.state = {
scrollY: new Animated.Value(
Platform.OS === 'ios' ? -HEADER_MAX_HEIGHT : 0,
),
};
}
on render you can interpolate a value acording the scrollY Value
render() {
const { scrollY } = this.state;
// this will set a height for topbar
const headerHeight = scrollY.interpolate({
inputRange: [0, HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT],
outputRange: [HEADER_MAX_HEIGHT, HEADER_MIN_HEIGHT],
extrapolate: 'clamp',
});
// obs: the inputRange is the scrollY value, (starts on 0)
// and can go until (HEADER_MAX_HEIGHT - HEADER_MIN_HEIGHT)
// outputRange is the height that will set on topbar
// obs: you must add a onScroll function on a scrollView like below:
return (
<View>
<Animated.View style={{
position: 'absolute',
top: 0,
left: 0,
right: 0,
backgroundColor: '#2e4265',
height: headerHeight,
zIndex: 1,
flexDirection: 'row',
justifyContent: 'flex-start',
}}>
<Text>{title}</Text>
</Animated.View>
<ScrollView
style={{ flex: 1 }}
scrollEventThrottle={16}
onScroll={Animated.event(
[{ nativeEvent: { contentOffset: { y: this.state.scrollY } } }],
)}>
<View style={{ height: 1000 }} />
</ScrollView>
</View>
);
}

How can I animate a component from one View to lower the DOM?

I'm writing a PlayingCard game. I want to animate a card from the Handfan to the cardTable. As soon as the card leavs the Fan View it disappears. How can I animate it smoothly to the middle of the Display what would be higher up in the DOM?
I though maybe it works with react-native-portal?
This is the card:
return (
<View style={styles.outerContainer}>
<Animated.View style={[styles.playerHandContainer, { width: containerAnimValue.x, //+ widthOffset,
height: containerAnimValue.y }]}>
{cards.map((card, idx) => {
const { suit, number } = card
const { x, y, angle } = coords[idx]
const originalIndex = originalCards.indexOf(JSON.stringify(card))
// const styleObject = { left: x + leftOffset, top: y, transform: [{ rotate: Math.round(angle) + 'deg' }]}
const translationAnimValue = translationAnimationValues[originalIndex]
angle, number, originalIndex')
const styleObject = { left: translationAnimValue.x, top: translationAnimValue.y,
transform: [{ rotate: spins[originalIndex] }]}
// the list is necessary because it doesn't give you the same results if you put the object directy in the jsx curlies
return <AnimatedClassCard onPress={() => this.cardOnPress(card, cards, idx, coords, width, height)}
card={{ suit, number }} key={originalIndex} style={[styles.playerCards, styleObject]}
renderCard={renderCard}/>
}
)
}
</Animated.View>
</View>
the card should just move out of the handfan container to the main container without disappearing.

How to modify Scrollview height dynamically in react native

I have a scroll view with a full-length screen. With one flag I need to show button at the bottom.
Am using Animated.View for showing button at Bottom.
When button visible am unable to change scroll view height.
If I try to manage with marginBottom it is showing unwanted white before getting a button with animation.
Here I need to do either change scroll view height dynamically or transparent unwanted white background.
Below is code snippet:
const modalY = new Animated.Value(Dimensions.get('window').height);
openModal = () => {
Animated.timing(modalY, {
duration: 500,
toValue: Dimensions.get('window').height - 60
}).start();
}
closeModal = () => {
Animated.timing(modalY, {
duration: 300,
toValue: Dimensions.get('window').height
}).start();
}
showButton = () => {
const animationView = <Animated.View style={[ {width: Dimensions.get('window').width,position: 'absolute'}, { transform: [{translateY: modalY}] }]}>
<TouchableHighlight with title height 60/>
</Animated.View>;
return (
animationView
);
};
const marBottom = buttonTitle ? 60 : 0;
here buttonTitle is flag
<View>
<ScrollView contentContainerStyle={{ paddingTop: top }} style={{marginBottom:marBottom}}>
<View style={ [styles.itemscontainer]}>
{ this.myItems()}
</View>
</ScrollView>
{ this.showButton() }
{(buttonTitle) ? this.openModal() : this.closeModal()}
</View>