Sådan oprettes en kameraapp med Expo og React Native

Hvis du ikke er fortrolig med expo, er det en klient, der hjælper dig med at opbygge React Native-apps med mindre build-kompleksitet. Det hjælper dig også med at håndtere stresset ved installation og opsætning af dit miljø til at køre React Native.

I denne vejledning bygger vi en simpel kameraapp, hvor brugeren kan tage billeder, se eksempler på deres billeder, bruge flashtilstand og skifte mellem det forreste og det bageste kamera.

Forudsætninger

Expo kræver ikke meget for at starte opbygningen af ​​din første React Native-app. Du kan lære mere om installation af expo og expo-cli her i dokumenterne.

Bemærk: i denne vejledning bruger jeg macOS og iOS. Du kan også bruge Android, der er ikke meget forskel, når du bruger expo på dette tidspunkt.

Du kan installere expo og expo-cli globalt ved at køre følgende kommando:

npm install --global expo-cli

Expo kræver Nodejs for at køre. Du kan køre den nyeste version på det officielle websted her.

Kom godt i gang

Når du har installeret Expo og Nodejs, kan du starte bootstrapping af et nyt Expo-projekt med kommandoen nedenfor:

expo init expo-camera-app

Sådan installeres pakkerne og kører appen

Expo giver os en klientapp, hvor vi kan køre og se eksemplet på den app, vi bygger. Den er tilgængelig i både App Store og Google Play til download.

Dette er app-grænsefladen.

Sådan initieres et expo-projekt

Gå til appmappen, og kør appen.

cd expo-camera-app 

Du bliver bedt om et par spørgsmål for at vælge standardskabelonen til appen. I denne vejledning vælger vi blot en tom (TypeScript) -indstilling, men igen er du fri til at vælge, hvad der passer til dig.

Kør appen

Efter bootstrapping af projektet kan vi køre appen med expo run

Dette åbner et vindue i din browser, hvor du kan se logfilerne. Det genererer også en QR-kode, som du kan scanne for at køre appen på din enhed.

Det gode ved expo er, at du ikke behøver at installere og konfigurere simulatorerne til at køre appen. Det giver dig stadig mulighed for at køre expo på simulatoren, men du skal selv installere og konfigurere simulatoren.

Tilbage til vores app. Forudsat at du med succes har kørt appen på enheden, vil dette være standardskærmen:

Åbn app-biblioteket i din foretrukne kodeditor. Jeg bruger VS-kode.

Den App.tsxvil se sådan ud:

import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View} from 'react-native' export default function App() { return (  Open up App.tsx to start working on your app!   ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } }) 

Sådan oprettes brugergrænsefladen

Efter at have kørt projektet, er det nu tid til at begynde at oprette noget brugergrænseflade.

Installer expo-kamera

Det næste trin er at installere expo-kamera, som dette:

expo install expo-camera

Vi opretter en simpel brugergrænseflade, der giver brugeren mulighed for at starte processen med at bruge kameraet.

import {StatusBar} from 'expo-status-bar' import React from 'react' import {StyleSheet, Text, View, TouchableOpacity} from 'react-native' export default function App() { return (     Take picture      ) } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#fff', alignItems: 'center', justifyContent: 'center' } }) 

Det er et simpelt brugergrænseflade: vi importerer TouchableOpacitytil knappen og laver en simpel styling. Hvis du spekulerer på, hvordan styling fungerer i React Native, kan du tjekke mine to artikler her:

  • Styling i React Native
  • Afmystificering af Flexbox i React Native

Nu skal vi bruge en useStatekrog til at styre tilstanden og vise kameravisningen, når brugeren trykker på knappen tage billedet .

   Take picture  
 const [startCamera,setStartCamera] = React.useState(false) const __startCamera = ()=>{ }

Der er to vigtige ting, vi skal gøre, når brugeren trykker på knappen:

  • Bed tilladelse om at få adgang til kameraet. I mobiludvikling er adgang til mange native API'er og mobilfunktioner ofte begrænset af brugerens tilladelser og privatlivets fred. Det er bare noget, du skal vænne dig til, når du udvikler mobilapps.
  • Skift tilstand, og præsenter kameraet.

Lad os importere kameramodulet fra expo-cameramed denne kommando:

import {Camera} from 'expo-camera'

Og tilføj kameravisningen som denne:

  { camera = r }} >

Vi kan bruge reftil at få adgang til kameraets metoder:

let camera: Camera

Når take pictureder trykkes på knappen, kaldes __startCamerafunktionen:

 const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if(status === 'granted'){ // do something }else{ Alert.alert("Access denied") }

Funktionen beder først om tilladelse. Hvis brugeren giver adgang til kameraet, kan vi fortsætte og åbne kameraet. Hvis ikke, viser vi en simpel advarsel.

Tilføj kamerakomponenten

Lad os vise kameraet, når brugeren giver adgang til enhedens kamera.

 const __startCamera = async () => { const {status} = await Camera.requestPermissionsAsync() if (status === 'granted') { // start the camera setStartCamera(true) } else { Alert.alert('Access denied') } }

Vi er nødt til at foretage nogle ændringer i brugergrænsefladen og tilføje en betinget gengivelse. Vi viser kun kameraet, når brugeren anmoder om det, ellers viser vi standardskærmen.

 {startCamera ? (  { camera = r }} > ) : (    Take picture    )}

Sejt, nu skal vi tilføje en knap, så vi kan tage det faktiske billede.

Tilføj optageknappen

This is a simple View inside the camera view that has an absolute position. So we make sure that it is always on the top of the camera.

How to take a picture

The app should take a picture when capture button is pressed. That function will look like the below:

 const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() }

First, we check that we have access to the Camera component using ref:

 if (!camera) return // if the camera is undefined or null, we stop the function execution

Then we take the picture by calling the takePictureAsync method. It returns a promise and an object that contains the picture's details. The result will look like this:

Object { "height": 4224, "uri": "file:///var/mobile/Containers/Data/Application/E6740A15-93AF-4120-BF11-6E8B74AFBF93/Library/Caches/ExponentExperienceData/%2540anonymous%252Fcamera-app-ee0fa3c8-1bb1-4d62-9863-33bf26341c55/Camera/19F0C5DD-7CA6-4043-8D89-AF65A1055C7E.jpg", "width": 1952, }

We are only interested in the Picture URL uri. After we take a picture, we have to show the photo preview and hide the camera view. To do that we will use two hooks to change the state:

 const [previewVisible, setPreviewVisible] = useState(false) const [capturedImage, setCapturedImage] = useState(null)
 const __takePicture = async () => { if (!camera) return const photo = await camera.takePictureAsync() console.log(photo) setPreviewVisible(true) setCapturedImage(photo) }
  • setPreviewVisible to show the preview
  • setCapturedImage(photo) to store the object result

Then we display the preview like this:

 {previewVisible && capturedImage ? (  ) : (  { camera = r }} >         )}

The CameraPreview component looks like this:

const CameraPreview = ({photo}: any) => { console.log('sdsfds', photo) return (    ) }

And the result looks like this:

How to re-take a picture

We can add some buttons to the preview that will allow the user to perform more actions. For example, they could re-take the photo or save it.

Add the savePhoto and retakePicture props to the CameraPreview component like this:

When the Re-take button is pressed, we will have to hide the preview, remove the current picture, and show the camera again. Do that with the following code:

 const __retakePicture = () => { setCapturedImage(null) setPreviewVisible(false) __startCamera() }

How to add other options – back camera, flash, and more

expo-camra offers many options for customizing the camera, like FlashMode, setting the Camera type (front/back), zooming, and so on.

How to add FlashMode

Let's add an option so the user can turn FlashMode on and off:

We simply create a small button to switch off/on the flash, like this:

   ⚡️  

And we just change the state when the button is pressed:

 const [flashMode, setFlashMode] = React.useState('off') const __handleFlashMode = () => { if (flashMode === 'on') { setFlashMode('off') } else if (flashMode === 'off') { setFlashMode('on') } else { setFlashMode('auto') } }

And then we add FlashMode props:

  { camera = r }} >

How to access the front and the back camera

We will add a button that switches between the back and front camera.

We can get the default camera type directly from the camera module like below:

 const [cameraType, setCameraType] = React.useState(Camera.Constants.Type.back)

Add type props like this:

  { camera = r }} >

And add the switch button:

  {cameraType === 'front' ? '?' : '?'}  

And switch function:

 const __switchCamera = () => { if (cameraType === 'back') { setCameraType('front') } else { setCameraType('back') } }

Here is the result:

You can find the full source code on GitHub.

Wrapping up

In general, Expo is an amazing tool that can save you a lot of time. It helps you start building directly and saves you the pain of environment setup.

Nogle gange vil du måske opbygge en indbygget udvidelse og håndtere brug af indfødte funktioner på din egen måde. I dette tilfælde vil jeg anbefale at bruge den reaktive native CLI, så du nemt kan ændre og spille med native kode.

Hej, mit navn er Said Hayani. Jeg oprettede subscribi.io for at hjælpe skabere, bloggere og influencere med at få deres publikum til at vokse gennem nyhedsbrevet.

Deltag i min mailingliste, hvis du er interesseret i at læse mere om React Native.