npm install --global expo-cliExpo requer Nodejs para funcionar. Você pode executar a versão mais recente no site oficial aqui.
Começando
Depois de instalar o Expo e o Nodejs, você pode iniciar a inicialização de um novo projeto Expo com o comando abaixo:
expo init expo-camera-appComo instalar os pacotes e executar o aplicativo
A Expo nos fornece um aplicativo cliente onde podemos executar e ver uma prévia do aplicativo que estamos construindo. Está disponível em ambos Loja de aplicativos e Google Play baixar.
Esta é a interface do aplicativo.
Como iniciar um projeto expo
Vá para o diretório do aplicativo e execute o aplicativo.
cd expo-camera-app
Serão feitas algumas perguntas para selecionar o modelo padrão para o aplicativo. Neste tutorial, simplesmente selecionamos uma opção em branco (TypeScript), mas, novamente, você é livre para escolher o que é certo para você.
Execute o aplicativo
Depois de inicializar o projeto, podemos executar o aplicativo com expo run
Isso abrirá uma janela em seu navegador onde você pode ver os logs. Ele também irá gerar um código QR que você pode escanear para executar o aplicativo em seu dispositivo.
O bom do expo é que você não precisa instalar e configurar os simuladores para executar o aplicativo. Ele ainda oferece a opção de executar o expo no simulador, mas você deve instalar e configurar o simulador sozinho.
De volta ao nosso aplicativo. Supondo que você tenha executado com êxito o aplicativo no dispositivo, esta será a tela padrão:
Abra o diretório do aplicativo em seu editor de código favorito. estou a usar Código VS.
o App.tsx será parecido com isto:
import {StatusBar} from 'expo-status-bar'
import React from 'react'
import {StyleSheet, Text, View} from 'react-native'
export default function App() {
return (
<View style={styles.container}>
<Text>Open up App.tsx to start working on your app!</Text>
<StatusBar style="auto" />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
Como criar a IU
Depois de ter o projeto em execução, agora é hora de começar a criar alguma IU.
Instalar expo-camera
A próxima etapa é instalar câmera de exposição, como isso:
expo install expo-cameraVamos criar uma interface de usuário simples que permitirá ao usuário iniciar o processo de uso da câmera.
import {StatusBar} from 'expo-status-bar'
import React from 'react'
import {StyleSheet, Text, View, TouchableOpacity} from 'react-native'
export default function App() {
return (
<View style={styles.container}>
<View
style={{
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center'
}}
>
<TouchableOpacity
style={{
width: 130,
borderRadius: 4,
backgroundColor: '#14274e',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 40
}}
>
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center'
}}
>
Take picture
</Text>
</TouchableOpacity>
</View>
<StatusBar style="auto" />
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
É uma IU simples: importamos TouchableOpacity para o botão e faça um estilo simples. Se você está se perguntando como o estilo funciona no React Native, você pode verificar meus dois artigos aqui:
Agora temos que usar um useState gancho para gerenciar o estado e exibir a visão da câmera quando o usuário pressiona o tire uma foto botão.
<TouchableOpacity
onPress={__startCamera}
style={{
width: 130,
borderRadius: 4,
backgroundColor: '#14274e',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 40
}}
>
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center'
}}
>
Take picture
</Text>
</TouchableOpacity> const [startCamera,setStartCamera] = React.useState(false)
const __startCamera = ()=>{
}Há duas coisas importantes que devemos fazer quando o usuário pressiona o botão:
- Peça permissão para acessar a câmera. No desenvolvimento móvel, o acesso a muitas APIs nativas e recursos móveis é frequentemente restrito pelas permissões e privacidade do usuário. É apenas algo com o qual você precisa se acostumar ao desenvolver aplicativos móveis.
- Mude o estado e apresente a câmera.
Vamos importar o módulo da câmera de expo-camera com este comando:
import {Camera} from 'expo-camera'E adicione a visão da câmera, assim:
<Camera
style={{flex: 1,width:"100%"}}
ref={(r) => {
camera = r
}}
></Camera>Podemos usar ref para acessar os métodos da câmera:
let camera: CameraQuando o take picture botão é pressionado o __startCamera função será chamada:
const __startCamera = async () => {
const {status} = await Camera.requestPermissionsAsync()
if(status === 'granted'){
// do something
}else{
Alert.alert("Access denied")
}A função pedirá permissão primeiro. Se o usuário conceder acesso à câmera, podemos prosseguir e abrir a câmera. Caso contrário, mostramos um alerta simples.
Adicione o componente da câmera
Vamos exibir a câmera quando o usuário conceder acesso à câmera do dispositivo.
const __startCamera = async () => {
const {status} = await Camera.requestPermissionsAsync()
if (status === 'granted') {
// start the camera
setStartCamera(true)
} else {
Alert.alert('Access denied')
}
}Temos que fazer algumas mudanças na IU e adicionar uma renderização condicional. Exibimos a câmera apenas quando o usuário solicita, caso contrário exibimos a tela padrão.
{startCamera ? (
<Camera
style={{flex: 1,width:"100%"}}
ref={(r) => {
camera = r
}}
></Camera>
) : (
<View
style={{
flex: 1,
backgroundColor: '#fff',
justifyContent: 'center',
alignItems: 'center'
}}
>
<TouchableOpacity
onPress={__startCamera}
style={{
width: 130,
borderRadius: 4,
backgroundColor: '#14274e',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
height: 40
}}
>
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center'
}}
>
Take picture
</Text>
</TouchableOpacity>
</View>
)}Legal, agora precisamos adicionar um botão para que possamos tirar a foto real.
Adicione o botão de captura
Este é um simples View dentro da visão da câmera que tem uma posição absoluta. Por isso, certificamo-nos de que está sempre na parte superior da câmera.
<View
style={{
position: 'absolute',
bottom: 0,
flexDirection: 'row',
flex: 1,
width: '100%',
padding: 20,
justifyContent: 'space-between'
}}
>
<View
style={{
alignSelf: 'center',
flex: 1,
alignItems: 'center'
}}
>
<TouchableOpacity
onPress={__takePicture}
style={{
width: 70,
height: 70,
bottom: 0,
borderRadius: 50,
backgroundColor: '#fff'
}}
/>
</View>
</View>Como tirar uma foto
O aplicativo deve tirar uma foto quando o botão de captura é pressionado. Essa função será semelhante a esta:
const __takePicture = async () => {
if (!camera) return
const photo = await camera.takePictureAsync()
}Primeiro, verificamos se temos acesso ao Camera componente usando ref:
if (!camera) return
// if the camera is undefined or null, we stop the function executionEntão tiramos a foto chamando o takePictureAsync método. Ele retorna uma promessa e um objeto que contém os detalhes da imagem. O resultado será assim:
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,
}Estamos interessados apenas no URL da imagem uri. Depois de tirar uma foto, temos que mostrar a visualização da foto e ocultar a visão da câmera. Para fazer isso, usaremos dois ganchos para alterar o estado:
const [previewVisible, setPreviewVisible] = useState(false)
const [capturedImage, setCapturedImage] = useState<any>(null) const __takePicture = async () => {
if (!camera) return
const photo = await camera.takePictureAsync()
console.log(photo)
setPreviewVisible(true)
setCapturedImage(photo)
}-
setPreviewVisiblepara mostrar a prévia setCapturedImage(photo)para armazenar o resultado do objeto
Em seguida, exibimos a visualização assim:
{previewVisible && capturedImage ? (
<CameraPreview photo={capturedImage} />
) : (
<Camera
style={{flex: 1}}
ref={(r) => {
camera = r
}}
>
<View
style={{
flex: 1,
width: '100%',
backgroundColor: 'transparent',
flexDirection: 'row'
}}
>
<View
style={{
position: 'absolute',
bottom: 0,
flexDirection: 'row',
flex: 1,
width: '100%',
padding: 20,
justifyContent: 'space-between'
}}
>
<View
style={{
alignSelf: 'center',
flex: 1,
alignItems: 'center'
}}
>
<TouchableOpacity
onPress={__takePicture}
style={{
width: 70,
height: 70,
bottom: 0,
borderRadius: 50,
backgroundColor: '#fff'
}}
/>
</View>
</View>
</View>
</Camera>
)}o CameraPreview componente tem a seguinte aparência:
const CameraPreview = ({photo}: any) => {
console.log('sdsfds', photo)
return (
<View
style={{
backgroundColor: 'transparent',
flex: 1,
width: '100%',
height: '100%'
}}
>
<ImageBackground
source={{uri: photo && photo.uri}}
style={{
flex: 1
}}
/>
</View>
)
}E o resultado é o seguinte:
Como tirar uma foto novamente
Podemos adicionar alguns botões à visualização que permitirão ao usuário realizar mais ações. Por exemplo, eles podem tirar a foto novamente ou salvá-la.
Adicione o savePhoto e retakePicture adereços para o CameraPreview componente como este:
<CameraPreview photo={capturedImage} savePhoto={__savePhoto} retakePicture={__retakePicture} />Quando o Re-take for pressionado, teremos que ocultar a visualização, remover a imagem atual e mostrar a câmera novamente. Faça isso com o seguinte código:
const __retakePicture = () => {
setCapturedImage(null)
setPreviewVisible(false)
__startCamera()
}Como adicionar outras opções – câmera traseira, flash e mais
Expo-camra oferece muitas opções para personalizar a câmera, como FlashMode, definir o tipo de câmera (frente / trás), zoom e assim por diante.
Como adicionar FlashMode
Vamos adicionar uma opção para que o usuário possa ligar e desligar FlashMode:
Simplesmente criamos um pequeno botão para desligar / ligar o flash, como este:
<TouchableOpacity
onPress={__handleFlashMode}
style={{
position: 'absolute',
left: '5%',
top: '10%',
backgroundColor: flashMode === 'off' ? '#000' : '#fff',
borderRadius: '50%',
height: 25,
width: 25
}}
>
<Text
style={{
fontSize: 20
}}
>
⚡️
</Text>
</TouchableOpacity>E apenas mudamos o estado quando o botão é pressionado:
const [flashMode, setFlashMode] = React.useState('off')
const __handleFlashMode = () => {
if (flashMode === 'on') {
setFlashMode('off')
} else if (flashMode === 'off') {
setFlashMode('on')
} else {
setFlashMode('auto')
}
}E então adicionamos adereços FlashMode:
<Camera
flashMode={flashMode}
style={{flex: 1}}
ref={(r) => {
camera = r
}}
></Camera>Como acessar a câmera frontal e traseira
Vamos adicionar um botão que alterna entre a câmera traseira e frontal.
Podemos obter o tipo de câmera padrão diretamente do módulo da câmera como abaixo:
const [cameraType, setCameraType] = React.useState(Camera.Constants.Type.back)Adicionar type adereços como este:
<Camera
type={cameraType}
flashMode={flashMode}
style={{flex: 1}}
ref={(r) => {
camera = r
}}
></Camera>E adicione o botão de troca:
<TouchableOpacity
onPress={__switchCamera}
style={{
marginTop: 20,
borderRadius: '50%',
height: 25,
width: 25
}}
>
<Text
style={{
fontSize: 20
}}
>
{cameraType === 'front' ? '🤳' : '📷'}
</Text>
</TouchableOpacity>E mudar a função:
const __switchCamera = () => {
if (cameraType === 'back') {
setCameraType('front')
} else {
setCameraType('back')
}
}Aqui está o resultado:
Você pode encontrar o código-fonte completo em GitHub.
Empacotando
Em geral, Expo é uma ferramenta incrível que pode economizar muito tempo. Ele ajuda você a começar a construir diretamente e evita o trabalho de configuração do ambiente.
Às vezes, você pode querer construir uma extensão nativa e lidar com o uso de recursos nativos de sua própria maneira. Neste caso, eu recomendo usar o reagir nativo CLI para que você possa modificar e brincar com o código nativo facilmente.
Olá, meu nome é Said Hayani. eu criei subscribi.io para ajudar criadores, blogueiros e influenciadores a aumentar seu público por meio do boletim informativo.
Junte-se ao meu Lista de correio se você estiver interessado em ler mais sobre React Native.