I am using react-native-maps, Right now i am able to update location of driver and update the polyline. What i want to achieve is like Uber, i want to animate the car to new coordinate and also rotate it with respective to the heading.
Right now i am able to update the polyline, but without animation, I did some research and i got to know that we use Animated Markers for this, but couldn't find a documentation for this implementation.
my render method:
renderContent() {
if (this.state.loading) {
return (
<Loading />
);
} else if (this.state.error) {
return (
<Card>
<Heading> No directions available </Heading>
<Button>
<Text> Retry </Text>
<Icon name='refresh' />
</Button>
</Card>
);
}
if (this.props.liveLocation.origin !== null) {
const { origin, des, coords } = this.props.liveLocation;
return (
<MapView
provider='google'
style={{ height: '100%', width: '100%' }}
ref={ref => { this.map = ref; }}
initialRegion={{
latitude: Number(origin.lat),
longitude: Number(origin.lng),
longitudeDelta: 0.2,
latitudeDelta: 0.2
}}
onLayout={this.onLayout}
>
{origin != null && <MapView.Marker
coordinate={{ latitude: Number(origin.lat), longitude: Number(origin.lng) }}
>
<Icon name='directions-car' />
</MapView.Marker>}
{des != null && <MapView.Marker
coordinate={{ latitude: Number(des.lat), longitude: Number(des.lng) }}
>
<Icon name='place' />
</MapView.Marker>}
{coords.length > 1 &&
<MapView.Polyline
coordinates={coords}
strokeWidth={2}
strokeColor="black"
/>
}
</MapView>
);
}
}
origin has { lat, lng, heading, etc etc }
Related
Please help me out with this problem.
I can able to pick the image from my Local storage. In the Console also it is showing, But I cannot able to display it on the screen.
Here is my code.
import * as ImagePicker from "expo-image-picker";
import React, { useState } from "react";
import {
ActivityIndicator,
Button,
FlatList,
Image,
StyleSheet,
Text,
useWindowDimensions,
View
} from "react-native";
import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context";
export default function App() {
const [images, setImages] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const pickImages = async () => {
// No permissions request is necessary for launching the image library
setIsLoading(true);
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
// allowsEditing: true,
allowsMultipleSelection: true,
selectionLimit: 10,
aspect: [4, 3],
quality: 1,
});
setIsLoading(false);
console.log(result);
if (!result.canceled) {
setImages(result.uri ? [result.uri] : result.selected);
}
};
return (
<>
<FlatList
data={images}
renderItem={({ item }) => (
<Image
source={{ uri: item.uri }}
style={{ width: 100, height: 100 }}
/>
)}
keyExtractor={(item) => item.uri}
contentContainerStyle={{ marginVertical: 50, paddingBottom: 50 }}
ListHeaderComponent={
isLoading ? (
<View>
<Text
style={{ fontSize: 20, fontWeight: "bold", textAlign: "center" }}
>
Loading...
</Text>
<ActivityIndicator size={"large"} />
</View>
) : (
<Button title="Pick images" onPress={pickImages} />
)
}
/>
</>
);
}
I can able to pick the image from my Local storage. In Console also it is showing, But i cannot able to display it in screen.
Kindly help me out.
It looks like you're already passing the uri into the array. by doing [result.uri] and then in the image you're doing it again item.uri. trying just doing the item.
You can see in the example above that the bars are on top of the text. I am currently solving for this by adjusting the opacity of the bars, but I would really like to just have the text sit on top of the bars.
I have tried using props in the Bar/tick components, as well as using the style attributes, but neither have worked.
Here is my code:
import { FaLock } from "react-icons/fa";
import {
BarChart,
Bar,
Cell,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
Label,
} from "recharts";
export const MonthlyResults = ({ data }) => {
const CustomTick = (props) => {
const { x, y, payload } = props;
return (
<text
x={x + 20}
y={y + 5}
fontWeight={900}
fill="blue"
z={100}
style={{ fontSize: "1.5rem", zIndex: 100 }}
>
{payload.value.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();
})}{" "}
({data[payload.index].count})
</text>
);
};
return (
<div className="min-h-fit w-full justify-center bg-gray-200 rounded-md">
<h1 className="text-center text-2xl my-4 font-semibold">
Top 50 Restaurants in NYC
</h1>
<div className="h-[2000px] w-full">
<ResponsiveContainer>
<BarChart
data={data}
layout="vertical"
margin={{ top: 0, right: 0, left: -61, bottom: 0 }}
barCategoryGap="1"
>
<XAxis type="number" hide domain={[0, "dataMax"]} />
<YAxis
yAxisId={0}
type="category"
dataKey="name"
tick={<CustomTick />}
style={{
fontSize: "1rem",
fontWeight: "bold",
}}
/>
<Tooltip content={() => null} />
<Bar
dataKey="count"
onClick={(e) => {
console.log(e);
}}
style={{ zIndex: 50 }}
z={50}
>
{data.map((entry, index) => (
<Cell
cursor="pointer"
key={`cell-${index}`}
fill="rgba(112, 207, 250, 1)"
/>
))}
</Bar>
</BarChart>
</ResponsiveContainer>
</div>
</div>
);
};
A stack navigator that lives on a bottom tab contains 2 screens. One screen implements the react-native-camera and the other a modal. I'm trying to make the modal transparent but it fails (it has a white background). That's happening because of the useIsFocused hook that mounts and unmounts my camera component. Do you have any suggestions on how I can solve the issue?
function Scanner(){
return(
<Scan.Navigator headerMode='none' mode='modal'
screenOptions={{
cardStyle: { backgroundColor: 'transparent'},
cardOverlayEnabled: true,
}}
>
<Scan.Screen name='Camera' component={Camera}/>
<Scan.Screen name='ValidationModal' component= {Validation} />
</Scan.Navigator>
)
}
Camera = ({navigation}) => {
const [flash, setFlash] = React.useState(false)
const isFocused = useIsFocused();
const flashOn = ()=> {
setFlash(prevFlash => !prevFlash)
}
barcodeRecognized = ({ barcodes }) => {
barcodes.forEach(barcode => {
const kappa = JSON.parse(barcode.data)
navigation.navigate('ValidationMdal')
})
};
if(isFocused){
return(
<RNCamera
ref={ref => {
this.camera = ref;
}}
type={RNCamera.Constants.Type.back}
captureAudio={false}
flashMode={flash?RNCamera.Constants.FlashMode.torch:RNCamera.Constants.FlashMode.off}
androidCameraPermissionOptions={{
title: 'Permission to use camera',
message: 'We need your permission to use your camera',
buttonPositive: 'Ok',
buttonNegative: 'Cancel',
}}
style={{ flex: 1,width: '100%'}}
onGoogleVisionBarcodesDetected={this.barcodeRecognized}>
<TouchableHighlight style={{position:'absolute', top:10, right:10, borderRadius:50, zIndex:100, backgroundColor:'rgba(255,255,255,0.7)'}} onPress={flashOn} >
<Image source={flash?require("../../images/_Active.png"):require("../../images/_Idle.png")} />
</TouchableHighlight>
</RNCamera>
)
}else if(!isFocused){
return null
}
}
Validation = ({navigation}) =>{
return(
<View style={styles.container}>
<Image style={{flex:1}} source={require('../../green-tick.png')} resizeMode={'contain'} />
<TouchableHighlight style={} title='Dismiss' onPress={()=>navigation.goBack()}>
<Text>OK</Text>
</TouchableHighlight>
</View>
)
}
I am trying my react native app on android and iOS using the release mode. unfortunately, there is an animation that doesn't trigger in release mode which works perfectly on debug mode.
i have tried to use the 'useNativeDriver: true' which improved the animation on android but didn't fix the issue
for ref:
"react-native": "0.56.0"
my Drawer.js
toggle = () => {
Animated.timing(this.x_translate, {
toValue: this.state.drawerOpen ? 0 : 1,
duration: this.state.animationDuration,
useNativeDriver: true
}).start();
this.setState({ drawerOpen: !this.state.drawerOpen })
}
render() {
const menu_moveX = this.x_translate.interpolate({
inputRange: [0, 1],
outputRange: [-this.state.width, 0]
});
return (
<Animated.View style={[this.props.style, styles.drawer, {
transform: [
{
translateX: menu_moveX
}
]
}]}>
<ImageBackground
source={require('../images/background.png')}
style={{ width: '100%', height: '100%', alignItems: 'center' }}
>
<View style={styles.blank}></View>
<AutoHeightImage source={require('../images/image.png')} width={0.7 * this.state.width} />
<LineDashboard navigate={this.props.navigate} items={[this.menu[0], this.menu[1]]} sizeIcon={30} />
<LineDashboard navigate={this.props.navigate} items={[this.menu[2], this.menu[3]]} sizeIcon={30} />
<LineDashboard navigate={this.props.navigate} items={[this.menu[4], this.menu[5]]} sizeIcon={30} />
</ImageBackground>
</Animated.View>
)
}
my dashboard.js
componentDidMount() {
this.props.navigation.setParams({
handleThis: () => {
console.log(this.drawer);
this.setState({ loaded: true })
this.drawer.toggle();
}
});
}
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
headerTitle: 'Home Page',
headerLeft: (
<TouchableOpacity
onPress={() => {
params.handleThis();
}}
style={{ marginLeft: 20 }}
>
<Icon name="menu" size={25} color="black" />
</TouchableOpacity>
),
headerRight: (
<TouchableOpacity
onPress={() => {
console.log(navigation);
// navigation.goBack(null)
navigation.navigate('Login');
}}
style={{ marginRight: 20 }}
>
<Text style={{ color: 'red' }}>Log Out</Text>
</TouchableOpacity>
)
}
}
render() {
const { navigate } = this.props.navigation;
return (
<View style={styles.page}>
<ScrollView>
<View style={styles.pageContainer}>
<View style={{ height: 30 }} />
<AutoHeightImage source={require('../images/patient_primary_logo_white.png')} width={0.7 * width} />
<View style={styles.separator} />
<DashboardNotificationTile title={'Your Notifications'} onPress={() => navigate('Notifications')}>
<Text>You have 2 new notifications</Text>
<Text>Please click to see more</Text>
</DashboardNotificationTile>
<DashboardTile title={'Your Visits'}>
<Text>You have 1 upcoming visit</Text>
<SimpleButton onPress={() => navigate('ToBook')} title='View All Visits' width={'100%'} style={{ marginTop: 16 }} color={'green'}/>
</DashboardTile>
<DashboardTile title={'Your Expense Claims'}>
<Text>You have 2 open expense claims</Text>
<SimpleButton onPress={() => navigate('Open')} title='View All Expense Claims' width={'100%'} style={{ marginTop: 16 }} />
</DashboardTile>
</View>
</ScrollView>
<DrawerDashboard navigate={navigate} onRef={(ref) => this.drawer = ref} style={this.state.loaded ? { opacity: 1 } : { opacity: 0 }} />
</View >
)
}
in Dashboard.js, i have a headerLeft that should trigger the function handleThis() which doesn't seems to be doing. however, when pressed, the TouchableOpacity component stay 'selected' rather than coming back to its original state.
any suggestion?
thanks
EDIT:
the issue occurs at any time when the debugger is not on. sorry i just discovered it right now. The animation works perfectly if the remote JS debugger is launched.
So, i thought the issue may be the processing time, as the app is working slower when the debugger is on, maybe my handleThis() function was not loaded...
So, I moved the setParams() from the ComponentDidMount to WillMount.
didn't worked :\
Any suggestion?
I have cobbled together a working version of a Microsoft Excel like "freeze pains" view. The column header scrolls with the content horizontally and the row headers scroll with the content vertically but each is "stuck" in position when the other is scrolled.
You can try the working version here.
It's not optimal as it stutters if you stop a flicked scroll or just swipe around a lot.
The approach uses a couple techniques but the one causing the issue is the synced scroll view.
As outlined here, I've tried setting useNativeDriver: true, which necessitates changing
ScrollView to Animated.ScrollView and
ref={ref => (this.instance = ref)} to ref={ref => (this.instance = ref._component)}
but then the synced goes completely haywire.
I'd love ideas on a more optimal approach. How can this be improved?
import React from 'react';
import { ScrollView, Animated, Text, View } from 'react-native';
export default class SyncScrollTest extends React.Component {
constructor() {
super();
this.scrollPosition = new Animated.Value(0);
this.scrollEvent = Animated.event(
[{ nativeEvent: { contentOffset: { y: this.scrollPosition } } }],
{ useNativeDriver: false },
);
}
render() {
return (
<View style={{ flex: 1 }}>
<View style={{ flexDirection: 'row' }}>
<ScrollViewVerticallySynced
style={{ width: 50, marginTop: 60 }}
name="C1"
color="#F2AFAD"
onScroll={this.scrollEvent}
scrollPosition={this.scrollPosition}
/>
<ScrollView horizontal bounces={false}>
<View style={{ width: 600 }}>
<View style={{ height: 60, justifyContent: 'center', backgroundColor: '#B8D2EC' }}>
<Text>
I am Column Header!! I am Column Header!! I am Column Header!! I am Column
Header!! I am Column Header!! I am Column Header!! I am Column Header!!
</Text>
</View>
<ScrollViewVerticallySynced
style={{ width: 600 }}
name="C2"
color="#D9E4AA"
onScroll={this.scrollEvent}
scrollPosition={this.scrollPosition}
/>
</View>
</ScrollView>
</View>
</View>
);
}
}
class ScrollViewVerticallySynced extends React.Component {
componentDidMount() {
this.listener = this.props.scrollPosition.addListener((position) => {
this.instance.scrollTo({
y: position.value,
animated: false,
});
});
}
render() {
const { name, color, style, onScroll } = this.props;
return (
<ScrollView
key={name}
ref={ref => (this.instance = ref)}
style={style}
scrollEventThrottle={1}
onScroll={onScroll}
bounces={false}
showsVerticalScrollIndicator={false}
>
{someRows(name, 25, color)}
</ScrollView>
);
}
}
const someRows = (name, rowCount, color) =>
Array.from(Array(rowCount).keys()).map(index =>
(<View
key={`${name}-${index}`}
style={{
height: 50,
backgroundColor: index % 2 === 0 ? color : 'white',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text>
{name} R{index + 1}
</Text>
</View>),
);
```
I've changed your example, instead of using listeners and Animated Event I use the scrollTo method from ScrollView to synchronize the scrolling. I think that listeners are the cause of lag between the rows when you are scrolling.
You can test the changes here.
import React from 'react';
import { ScrollView, Text, View } from 'react-native';
import { Constants } from 'expo'
export default class SyncScrollTest extends React.Component {
constructor() {
super();
this.c1IsScrolling = false;
this.c2IsScrolling = false;
}
render() {
return (
<View style={{ flex: 1, marginTop: Constants.statusBarHeight }}>
<View style={{ flexDirection: 'row' }}>
<ScrollViewVerticallySynced
style={{ width: 50, marginTop: 60 }}
refe= {ref => (this.c2View = ref)}
name="C1"
color="#F2AFAD"
onScroll={e => {
if (!this.c1IsScrolling) {
this.c2IsScrolling = true;
var scrollY = e.nativeEvent.contentOffset.y;
this.c1View.scrollTo({ y: scrollY });
}
this.c1IsScrolling = false;
}}
/>
<ScrollView horizontal bounces={false}>
<View style={{ width: 400 }}>
<View style={{ height: 60, justifyContent: 'center', backgroundColor: '#B8D2EC' }}>
<Text>
I am Column Header!! I am Column Header!! I am Column Header!! I am Column
Header!! I am Column Header!! I am Column Header!! I am Column Header!!
</Text>
</View>
<ScrollViewVerticallySynced
style={{ width: 400 }}
refe= {ref => (this.c1View = ref)}
name="C2"
color="#D9E4AA"
onScroll= {e => {
if (!this.c2IsScrolling) {
this.c1IsScrolling = true;
var scrollY = e.nativeEvent.contentOffset.y;
this.c2View.scrollTo({ y: scrollY });
}
this.c2IsScrolling = false;
}}
/>
</View>
</ScrollView>
</View>
</View>
);
}
}
class ScrollViewVerticallySynced extends React.Component {
render() {
const { name, color, style, onScroll, refe } = this.props;
return (
<ScrollView
key={name}
ref={refe}
style={style}
scrollEventThrottle={1}
onScroll={onScroll}
bounces={false}
showsVerticalScrollIndicator={false}
>
{someRows(name, 25, color)}
</ScrollView>
);
}
}
const someRows = (name, rowCount, color) =>
Array.from(Array(rowCount).keys()).map(index =>
(<View
key={`${name}-${index}`}
style={{
height: 50,
backgroundColor: index % 2 === 0 ? color : 'white',
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}
>
<Text>
{name} R{index + 1}
</Text>
</View>),
);
You can find another example here