so i want to create an object, a message boxes that will be rendered on the screen in a relative position in the container.
i know to use position: 'relative' or 'absolute' and use the top and left values, but i want in addition to get the specific coordinates from the container component.
each instance of message box i want to render in a specific location retrieved from the container.
in general i cant find something in react native that fit my needs... im trying to make an app with managing objects on the screen in absolute position, all the algorithm where to render and how to move will be managed by me, but i cant find a good way to do that in react native seems like all the styles are better suit for relative and rendering obejcts by order design, someone has any tips?
enter code here:
export default class Message extends Component {
constructor(props) {
super(props)
};
render() {
var position = StyleSheet.create({top: this.props.top,
left: this.props.left});
var absoluteCircle = StyleSheet.flatten([styles.circle,
position]);
return (
<View style={absoluteCircle}>
<Text style={styles.circleText}>{this.props.bubbleText}
</Text>
</View>
);
}
}
Related
I was wondering how I would go about dragging/sliding left to reveal the timestamp on react native. I am using a flatlist in react-native and I have the timestamp data but I am unsure of how to render the timestamps on slight drag. Anyone have detailed ideas on how to do this. I have included images of current implementation and iMessage slide/drag. This feature is also on Instagram (ios version at least). I should add that I'm not trying to do a drag and drop feature more like just a solution review what is not currently in the view from a slide/drag
Current App
Current iMessage
This is the eventual solution i came up with all credit from #Abe and reading the gesture-handler documentation referenced above. I
import Animated, { useAnimatedStyle, useSharedValue, withSpring } from 'react-native-reanimated'
const translateX = useSharedValue(0)
const startX = useRef(0)
My flatlist renders elements like this now
<Animated.View
className="mx-2 flex-1 flex-row"
style={sty}
onTouchStart={(e) => {
startX.current = e.nativeEvent.pageX
}}
onTouchMove={(e) => {
const delta = startX.current - e.nativeEvent.pageX
if (delta > 0) {
translateX.value = -delta / 2
}
}}
onTouchEnd={() => {
translateX.value = withSpring(0)
}}>
...
</Animated.View>
The most common way to handle this is with a PanGestureHandler from react-native-gesture-handler and an Animated.View from react-native-reanimated.
Wrap your component in one, and make the View that you want to move into an Animated.View. (The component that the PanGestureHandler wraps also should be an Animated.View.) Create a shared value (from Reanimated) that represents the x offset of the component. Then create a handler method that responds to the drag gesture and changes the shared value. You may want to add some limits, like not scrolling past a certain offset in either direction. Then, use the shared value in an animated style (something like left: offsetX,) that you apply to your Animated.View.
Since you're using this inside a scrollable list, make sure to set the activeOffsetX prop to something like [-5, 5]. This means that if the user is only trying to scroll up and down, your gesture handler won't steal that touch.
The example in the gesture-handler docs should help.
I am trying to create an E-commerce Store and I'm a beginner in React.JS. What I want is for 5 images to come together on top of eachother when the user scrolls. (so they should move TranslateX on scroll). Previously, on Vanilla Javascript I would have added a window.addEventListener('scroll') and then set a value like value = window.scrollY and then I would have selected the image I wanted to move and simply translateX or Y based on that value.
However, I'm not sure how to do this in React. Where can I set the window event listener? Is there a state needed, or useEffect?
I'm attaching an image so you can clearly see what I am trying to do:
What I have in react is the "Scroll" component which contains 2 divs
-1 div on the left 2/3 flex size containing all the images that should come together
-1 div on the right 1/3 flex size containing the text and the button
inside the left div I have 5 images, and in CSS i've used position absolute to position them on top of eachother (they are all PNGs so they have transparent background).
How would I go about implementing this on my website?
HUGE thanks in advance!
You can save the scrollY in a useState, which you then use to transofrm your images. The window listeners can be loaded inside a useEffect.
It (could) look like this:
const [scrollY, setScrollY] = useState(0);
useEffect(() => {
const handleScroll = () => {
setScrollY(window.scrollY);
};
handleScroll();
window.addEventListener("scroll", handleScroll);
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
(You may have to add some ESLint rules if you use it)
I am having issues with react Plotly displaying correctly when a graph loaded in a hidden tab is selected. It seems this is a known issue where every tab but the default tab will not resize appropriately because it doesn't know the hidden graph's dimensions.
To get around this I would like to dynamically update the tab height to be equal to the height of the default tab. Something like this: Change div height when tab is selected.
The issue is, I am unable to select the tab height value on DOM load. I thought I could add a componentDidMount function with an evenlistener for window load like such:
constructor(props) {
super(props)
this.state = {
value: 0
};
this.handleLoad = this.handleLoad.bind(this);
}
componentDidMount() {
window.addEventListener('load', this.handleLoad);
}
handleLoad() {
console.log("firstTab height: " + $('#firstTab').offsetHeight)
}
This issue is, the console log is outputting firstTab height: undefined.
When i inspect the web page and put the command $('#firstTab').offsetHeight into the console I am able to come up with a height of 697 px.
I don't want to hardcode the tab pixel size. Can anyone guide me as to why I am failing to grab the element height on window load?
Try using clientHeight property.
componentDidMount() {
const height = document.getElementById('firstTab').clientHeight;
}
I think instead of using event listener, you can do something like this.
componentDidMount() {
const height = this.firstTab.clientHeight;
console.log(height) // => gives you height
}
render() {
return (
<div
id="firstTab"
ref={ (firsTabElement) => { this.divElement = firstTabElement } }
>
Tab Content
</div>
)
}
After the first render if you are not hiding or putting any condition to remove the firstTab from the DOM. It will be available to you in componentDidMount lifecycle.
This question already has answers here:
Image Alignment when using resizeMode = contain
(3 answers)
Closed 3 years ago.
I'm trying to create an image that fits snugly at the top of the screen of my device. Basically, a header image. At long last I've been able to scale the image to the width of the screen, but now that I have it, it always gives itself an extra top margin that I can't seem to get around. I've played around with flex properties but nothing seems to work! I was wondering if anyone had experienced an issue like this before. I'm a bit new to CSS and such so forgive me if my question is dumb.
Here is what appears (the margin is well above 25 pixels):
https://imgur.com/a/9Mzql
My code is as follows (simplified for you all):
import React, { Component } from 'react';
import {
View,
Image,
StyleSheet,
} from 'react-native';
export class Home extends Component {
static NavOption = {
title: 'Home',
};
render() {
return (
<View>
<View style={{flex: 1, justifyContent: 'flex-start'}}>
<Image
source={require('./pictures/my-image.png')}
style={styles.headerImage}
resizeMode='contain'
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
headerImage: {
maxWidth: '100%',
},
});
resizeMode='contain' actually centers and pads the image based on how it's resized. You will have to calculate and set the height dynamically.
Here is a good example of how that can be done:
Image Alignment when using resizeMode = contain
Gordon, not a dumb question. I am having the exact same issue. I did what ReyHaynes suggested (thanks!) but in my case, modified the example he linked to for my situation:
original example
The example expects a static maxWidth/maxHeight to return a set of dimensions for your image. Since i didn't know what those vars needed to be, here's how i modified his example to work for my situation:
import { Dimensions } from 'react-native';
then, change this...
var maxWidth = 110;
var maxHeight = 30;
to...
var maxWidth = Dimensions.get('window').width;
var maxHeight = height;
Finally, follow the original example and implement as he suggested.
I'm new to React Native (experiences iOS developer in Swift) and I can't seem to find anything online for how to move UI elements in response to touch events. (Or maybe I'm just really bad at searching stack overflow lol).
Eventually, I want to have a textbox in the center of the screen, and when the user begins to type (or taps on the box to start typing), the box will slide to the top of the screen. However I can't even find a simple tutorial for this. I know that I can have a const style that defines style/position aspects of the textbox, and I can create a second style and then on button tap I can change the textbox's style and re-render, but it seems overkill to make an entire second style, where only one attribute is changing.
Can someone provide sample React Native code, where there is a text label and a button on the screen, and when the user taps the button, the label moves from above the button to below the button?
Check out this example of moving an element on touch. I use a <TouchableWithoutFeedback> and onPressIn. When you touch it, it changes the x and y position of it:
https://snack.expo.io/#noitsnack/onpressin-twice
import React, { Component } from 'react';
import { Text, View, TouchableWithoutFeedback, Image, Dimensions } from 'react-native';
import IMAGE_EXPO from './assets/expo.symbol.white.png'
const IMAGE_SIZE = 100;
export default class App extends Component {
state = {
score: 0,
...getRandXY()
}
render() {
const { score, x, y } = this.state;
return (
<View style={{flex:1, backgroundColor:'steelblue' }}>
<Text style={{fontSize:72, textAlign:'center'}}>{score}</Text>
<TouchableWithoutFeedback onPressIn={this.addScore}>
<Image source={IMAGE_EXPO} style={{ width:IMAGE_SIZE, height:IMAGE_SIZE, left:x, top:y, position:'absolute' }} />
</TouchableWithoutFeedback>
</View>
)
}
addScore = e => {
this.setState(({ score }) => ({ score:score+1, ...getRandXY() }));
}
}
function getRandXY() {
return {
x: getRandInt(0, Dimensions.get('window').width - IMAGE_SIZE),
y: getRandInt(0, Dimensions.get('window').height - IMAGE_SIZE)
}
}
function getRandInt(min, max)
{
return Math.floor(Math.random()*(max-min+1)+min);
}
Once you get this movement down you can move to the Animation API to get teh sliding effect.