I have a react native app in which a user either has to click a photo or select a photo. When I select clicking a photo camera opens. I used a imagepicker for that
But I would like to add some widget on camera view itself like WhatsApp shows the image slideshow list view whenever we select camera. How can we draw on the camera and ability to choose the image from the small horizontal list view slideshow that is displayed on the camera view itself.
I was trying to build the same camera along with image selection from thousands of images
import React, {Component} from 'react';
import {Platform, StyleSheet, View, StatusBar, TouchableOpacity, FlatList, Image, ImageBackground} from 'react-native';
import { PermissionsAndroid, CameraRoll } from 'react-native';
//const Contner = createAppContainer(Routes);
export default class App extends Component
{
constructor(props) {
super(props);
z=[];
for (let i=0; i<500; i++)
{
z[i]=i;
}
this.z = z;
this.all_images={};
this.state={"images":{"edges":[]}};
}
async requestPhotosPermission() {
try
{
const granted = await PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE)
if (granted === PermissionsAndroid.RESULTS.GRANTED)
{
this.getPhotos();
} else
{
console.log("Photos permission denied")
}
} catch (err)
{
console.warn(err)
}
}
loadPhotos(){
var self=this;
const fetchParams = {
first: 1000000000,
assetType: 'Photos',
};
console.log("hellos");
CameraRoll.getPhotos(fetchParams).then((data) =>
{
console.log("length is ", data["edges"].length);
for (let j=0; j<data["edges"].length; j++)
{
this.all_images[j] = data["edges"][j]["node"]["image"]["uri"];
}
self.setState({"images":data});
}).catch((e) =>
{
console.log(e);
});
}
componentWillMount(){
this.requestPhotosPermission().then(()=>{
this.loadPhotos()
});
};
onViewableItemsChanged = ({ viewableItems, changed }) => {
// console.log("Visible items are", viewableItems[0],"to",viewableItems[viewableItems.length-1]);
// console.log("Changed in this iteration", changed);
};
render(){
console.log("finders");
let self=this;
return (
<FlatList
horizontal={true}
data={this.z}
renderItem={({item}) => {
console.log("item is ", item,self.state.images.edges.length);
// console.log(self.state.images.edges[0]);
if (self.state.images.edges.length!==0)
{
return <ImageBackground source={{uri: self.state.images.edges[item].node.image.uri}}
style={{height: 100, width: 100, margin: 4}}/>
}else
return <View style={{height:100,width:100,margin:4,borderWidth:1,backgroundColor:'#4a7642'}}/>
}}
onViewableItemsChanged={this.onViewableItemsChanged }
style={{borderWidth:3,borderColor:'red',height:'30%'}}
viewabilityConfig={{itemVisiblePercentThreshold: 50}}/>);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center',
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
padding: 15,
paddingHorizontal: 20,
alignSelf: 'center',
margin: 20,
},
});
I would like this list view to overlay on the normal Camera Widget
Related
I'm a bit new to React Native programming, and I'm working on implementing an autoscroll feature for PDFs. For example, in some cases, I want to automatically scroll a PDF down x pages and then scroll at a desired speed. I followed this tutorial here here which works for just normal data, but when I used a object from react-native-pdf, it does not seem to scroll anymore. I'm wrapping the PDF object inside a ScrollView and can confirm that the scrolling code is being called. Can anyone suggest a solution or explain why this does not work with the PDF? Thanks so much!
I've also attached my code below if that helps. Currently, the PDF displays but is not autoscrolling at all.
import React from 'react';
import {StyleSheet, Dimensions, View, ScrollView} from 'react-native';
import Pdf from 'react-native-pdf';
export default class PDFScroll extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPosition: 0,
};
this.scrolling = this.scrolling.bind(this);
}
componentDidMount(){
this.activeInterval = setInterval(this.scrolling, 100);
}
componentWillUnmount(){
clearInterval(this.activeInterval);
}
scrolling() {
position = this.state.currentPosition + 50;
this.pdf.scrollTo({ x: position, animated: true });
// After position passes this value, snaps back to beginning
let maxOffset = 2000;
// Set animation to repeat at end of scroll
if (this.state.currentPosition > maxOffset) {
this.pdf.scrollTo({ x: 0, animated: false })
this.setState({ currentPosition: 0 });
}
else {
this.setState({ currentPosition: position });
}
}
render() {
const source = {
uri: 'http://samples.leanpub.com/thereactnativebook-sample.pdf',
cache: true,
};
return (
<View style={styles.container}>
<ScrollView
style={styles.scrollview}
horizontal={false}
bounces={true}
ref={(ref) => this.pdf = ref}
>
{
<Pdf
source={source}
onLoadComplete={(numberOfPages, filePath) => {
console.log(`number of pages: ${numberOfPages}`);
}}
onPageChanged={(page, numberOfPages) => {
console.log(`current page: ${page}`);
}}
onError={error => {
console.log(error);
}}
onPressLink={uri => {
console.log(`Link presse: ${uri}`);
}}
style={styles.pdf}
/>
}
</ScrollView>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'flex-start',
alignItems: 'center',
marginTop: 25,
},
pdf: {
flex: 1,
width: Dimensions.get('window').width,
height: Dimensions.get('window').height,
},
});
I have tried to implement the component expand to full screen in react native by using Layout animation in react-native but it was not good to look. Can any one help me in getting it?
changeLayout = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({ expanded: !this.state.expanded });
};
I expect to expand the component on click to full screen and again collapse it on click.
Set the initial value you want through the animation, obtain the screen width and height, and create a click function to execute.
This is an example that I made. Click this link if you want to run it yourself.
import React from 'react';
import { Animated, Text, View,Dimensions,Button } from 'react-native';
const screenwidth = Dimensions.get('screen').width
const screenheight = Dimensions.get('screen').height
class FadeInView extends React.Component {
state = {
fadeAnim: new Animated.Value(50),
fadeAnim2: new Animated.Value(50),
}
componentDidMount() {
}
animatebutton() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: screenheight,
duration: 10000, // Make it take a while
}
).start();
Animated.timing( // Animate over time
this.state.fadeAnim2, // The animated value to drive
{
toValue: screenwidth,
duration: 10000, // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim,fadeAnim2 } = this.state;
return (
<Animated.View // Special animatable View
style={{
...this.props.style,
height: fadeAnim,
width : fadeAnim2
}}
>
{this.props.children}
</Animated.View>
);
}
}
// You can then use your `FadeInView` in place of a `View` in your components:
export default class App extends React.Component {
constructor(props){
super(props);
this.state={
}
}
animatebutton(){
this.fade.animatebutton();
}
render() {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center'}} >
<FadeInView style={{backgroundColor: 'powderblue'}} ref={ani => this.fade = ani}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
<Button title="go animate" onPress={() => this.animatebutton()}/>
</View>
)
}
}
OR
You can use LayoutAnimation that you want to use. Look at my example.
import React, {Component} from "react";
import {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
LayoutAnimation,
} from 'react-native';
class App extends Component {
constructor() {
super();
this.state = {
check: false,
}
}
onPresscheck() {
// Uncomment to animate the next state change.
LayoutAnimation.configureNext(LayoutAnimation.Presets.spring);
// Or use a Custom Layout Animation
// LayoutAnimation.configureNext(CustomLayoutAnimation);
this.setState({ check : !this.state.check});
}
render() {
var middleStyle = this.state.check === false ? {width: 20,height:20} : {width: "100%",height:"100%"};
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={() => this.onPresscheck()}>
<Text>pressbutton</Text>
</TouchableOpacity>
<View style={[middleStyle, {backgroundColor: 'seagreen'}]}/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
button: {
width:"100%",
height: 60,
backgroundColor: 'blue',
alignItems: 'center',
justifyContent: 'center',
margin: 8,
},
});
export default App;
Please refer to this blog :
https://dev-yakuza.github.io/en/react-native/react-native-animatable/
Also, try using this library. Use any animation type you want and render them.
Happy coding :)
I want to achieve the WhatsApp stories like effect, where the number of progress bars on top are equal to the number of stories.
I'm using react-native-progress/bar library to achieve this effect, but I'm finding a way that how can I run second progress bar when first ends.
Actually progress of Progress.bar changes with the change of state.
What is an efficient way to do this by using a single state?
Here is code:
import React, { Component } from 'react';
import { StyleSheet, TouchableOpacity, View } from 'react-native';
import * as Progress from 'react-native-progress';
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
image: {
width: 300,
height: 200,
},
});
export default class Example extends Component {
componentDidMount() {
this.animate();
}
constructor(props) {
super(props);
this.state = {
progress: 0
};
}
animate() {
let progress = 0;
this.setState({ progress });
let myInterval = setInterval(() => {
if (progress > 1) {
progress = 1;
clearInterval(myInterval);
} else {
progress += 0.01;
}
this.setState({ progress });
}, 20)
}
render() {
return (
<View style={styles.container}>
<View style={{flexDirection:'row'}} >
<Progress.Bar
key={'0'}
style={styles.progress}
progress={this.state.progress}
indeterminate={false}
/>
<Progress.Bar
key={'1'}
style={styles.progress}
progress={this.state.progress}
indeterminate={false}
/>
</View>
</View>
);
}
}
I want to open the device camera from my app when user click on the button and when user click on back button it should react to my application from device camera. I am able to open camera and take photo by running react native project. But I want to do it how camera works in what's app. That is clicking on button -> opening camera -> send button .
I am an beginner in react native .I tried many ways but I am not getting how it can be done.
Can anybody assist me to do this.
My App.js code is,
'use strict';
import React, { Component } from 'react';
import {
AppRegistry,
Dimensions,
StyleSheet,
Text,
TouchableHighlight,
View
} from 'react-native';
import Camera from 'react-native-camera';
class BadInstagramCloneApp extends Component {
render() {
return (
<View style={styles.container}>
<Camera
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>
</View>
);
}
takePicture() {
const options = {};
//options.location = ...
this.camera.capture({metadata: options})
.then((data) => console.log(data))
.catch(err => console.error(err));
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center'
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
color: '#000',
padding: 10,
margin: 40
}
});
AppRegistry.registerComponent('BadInstagramCloneApp', () => BadInstagramCloneApp);
You can use the state to show/hide the camera view/component.
Please check the following code:
...
class BadInstagramCloneApp extends Component {
constructor(props) {
super(props);
this.state = {
isCameraVisiable: false
}
}
showCameraView = () => {
this.setState({ isCameraVisible: true });
}
render() {
const { isCameraVisible } = this.state;
return (
<View style={styles.container}>
{!isCameraVisible &&<Button title="Show me Camera" onPress={this.showCameraView} />}
{isCameraVisible &&
<Camera
ref={(cam) => {
this.camera = cam;
}}
style={styles.preview}
aspect={Camera.constants.Aspect.fill}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
</Camera>}
</View>
);
}
takePicture() {
const options = {};
//options.location = ...
this.camera.capture({metadata: options})
.then((data) => {
console.log(data);
this.setState({ isCameraVisible: false });
}
.catch(err => console.error(err));
}
}
...
You can use https://github.com/ivpusic/react-native-image-crop-picker for this. This component helps you to take photo and also the photo if required. Follow the documentation correctly and here is the code for camera selection option
ImagePicker.openCamera({
cropping: true,
width: 500,
height: 500,
cropperCircleOverlay: true,
compressImageMaxWidth: 640,
compressImageMaxHeight: 480,
freeStyleCropEnabled: true,
}).then(image => {
this.setState({imageModalVisible: false})
})
.catch(e => {
console.log(e), this.setState({imageModalVisible: false})
});
Correction of best answer because of deprecation of Camera to RNCamera plus missing closing bracket ")" right before the .catch and like a spelling mistake with the declaration of state:
But basically there's 2 routes, whether you're using expo or react native. You gotta have Pods/Ruby/Cocoapods or manually link and all that if you're using traditional React Native, but just go with expo-camera if you got an expo set up and don't listen to this.
This is a React-Native with Pods/Ruby/CocoaPods solution, whereas going with expo-camera might be much faster and better if you're not set up like this.
import React, { Component } from 'react';
import {
Text,
View,
StyleSheet,
Button,
TouchableOpacity
} from 'react-native';
import { RNCamera } from 'react-native-camera';
export default class Camera2 extends Component {
constructor(props) {
super(props);
this.state = {
isCameraVisible: false
}
}
showCameraView = () => {
this.setState({ isCameraVisible: true });
}
takePicture = async () => {
try {
const data = await this.camera.takePictureAsync();
console.log('Path to image: ' + data.uri);
} catch (err) {
// console.log('err: ', err);
}
};
render() {
const { isCameraVisible } = this.state;
return (
<View style={styles.container}>
{!isCameraVisible &&<Button title="Show me Camera" onPress={this.showCameraView} />}
{isCameraVisible &&
<RNCamera
ref={cam => {
this.camera = cam;
}}
style={styles.preview}
>
<View style={styles.captureContainer}>
<TouchableOpacity style={styles.capture} onPress={this.takePicture}>
<Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
<Text>Take Photo</Text>
</TouchableOpacity>
</View>
</RNCamera>}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
},
preview: {
flex: 1,
justifyContent: 'flex-end',
alignItems: 'center'
},
capture: {
flex: 0,
backgroundColor: '#fff',
borderRadius: 5,
color: '#000',
padding: 10,
margin: 40
}
});
I want to add a View to cover my entire app.
details: Whenever AppState changes (to inactive or background), lock screen should appear to hide app contents and user should enter passcode to unlock it.
However, in IOS, dialogs from "Alert, ActionSheetIOS, Share" are on the top of everything.
As a result, my LockedView cannot cover these.
Is there a way to create cover these dialogs?
Below is the simple example code for reproducing my case.
(App.js)
import React, {Component} from "react"
import {
Alert,
AppState,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native"
export default class extends Component {
constructor (props) {
super(props)
AppState.addEventListener("change", this._handleAppStateChange)
this.state = {
isLocked: false
}
}
componentWillUnmount() {
this.unsubscribe()
AppState.removeEventListener("change", this._handleAppStateChange)
}
_handleAppStateChange = (nextAppState) => {
const isLocked = nextAppState !== "active"
this.setState({isLocked})
}
onPressAlert () {
Alert.alert("alert")
}
renderContent () {
return (
<View style={styles.content}>
<Text>UNLOCKED</Text>
<TouchableOpacity onPress={this.onPressAlert}>
<Text>Alert</Text>
</TouchableOpacity>
</View>
)
}
renderLockedView (isLocked) {
return isLocked ?
<View style={styles.locked}><Text>LOCKED</Text></View> : null
}
render() {
const {isLocked} = this.state
return (
<View style={styles.container}>
{this.renderContent()}
{this.renderLockedView(isLocked)}
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
content: {
flex: 1,
backgroundColor: "green",
justifyContent: "center",
alignItems: "center",
},
locked: {
position: "absolute",
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: "red",
justifyContent: "center",
alignItems: "center",
},
})
With this code, app can cover contents(green) with lockedView(red) but alert.
I want to position lockedView on the top of alert.