Skip to content

Commit

Permalink
[camera] Support toggling autoFocus on and off (expo#28650)
Browse files Browse the repository at this point in the history
  • Loading branch information
alanjhughes authored May 7, 2024
1 parent e036192 commit 26c9f49
Show file tree
Hide file tree
Showing 19 changed files with 140 additions and 7 deletions.
18 changes: 18 additions & 0 deletions apps/native-component-list/src/screens/Camera/CameraScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
FlashMode,
PermissionStatus,
Camera,
FocusMode,
} from 'expo-camera';
import * as FileSystem from 'expo-file-system';
import React from 'react';
Expand Down Expand Up @@ -45,6 +46,7 @@ interface State {
mute: boolean;
torchEnabled: boolean;
cornerPoints?: BarcodePoint[];
autoFocus: FocusMode;
barcodeData: string;
newPhotos: boolean;
permissionsGranted: boolean;
Expand Down Expand Up @@ -72,6 +74,7 @@ export default class CameraScreen extends React.Component<object, State> {
cornerPoints: undefined,
mute: false,
barcodeData: '',
autoFocus: 'off',
newPhotos: false,
permissionsGranted: false,
micPermissionsGranted: false,
Expand Down Expand Up @@ -127,6 +130,11 @@ export default class CameraScreen extends React.Component<object, State> {
toggleBarcodeScanning = () =>
this.setState((state) => ({ barcodeScanning: !state.barcodeScanning }));

toggleFocus = () =>
this.setState((state) => ({
autoFocus: state.autoFocus === 'on' ? 'off' : 'on',
}));

collectPictureSizes = async () => {
const pictureSizes = (await this.camera?.current?.getAvailablePictureSizesAsync()) || [];
let pictureSizeId = 0;
Expand Down Expand Up @@ -248,6 +256,15 @@ export default class CameraScreen extends React.Component<object, State> {
color={this.state.torchEnabled ? 'white' : '#858585'}
/>
</TouchableOpacity>
<TouchableOpacity style={styles.toggleButton} onPress={this.toggleFocus}>
<Text
style={[
styles.autoFocusLabel,
{ color: this.state.autoFocus === 'on' ? 'white' : '#6b6b6b' },
]}>
AF
</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.toggleButton} onPress={this.toggleMoreOptions}>
<MaterialCommunityIcons name="dots-horizontal" size={32} color="white" />
</TouchableOpacity>
Expand Down Expand Up @@ -346,6 +363,7 @@ export default class CameraScreen extends React.Component<object, State> {
onCameraReady={this.collectPictureSizes}
responsiveOrientationWhenOrientationLocked
enableTorch={this.state.torchEnabled}
autofocus={this.state.autoFocus}
facing={this.state.facing}
animateShutter
pictureSize={this.state.pictureSize}
Expand Down
2 changes: 1 addition & 1 deletion docs/public/static/data/unversioned/expo-camera.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/public/static/data/v51.0.0/expo-camera.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions packages/expo-camera/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

### 🎉 New features

- Add `autoFocus` prop to allow setting the device focus mode. ([#28650](https://github.com/expo/expo/pull/28650) by [@alanjhughes](https://github.com/alanjhughes))

### 🐛 Bug fixes

### 💡 Others
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import expo.modules.camera.records.BarcodeType
import expo.modules.camera.records.CameraMode
import expo.modules.camera.records.CameraType
import expo.modules.camera.records.FlashMode
import expo.modules.camera.records.FocusMode
import expo.modules.camera.records.VideoQuality
import expo.modules.camera.tasks.ResolveTakenPicture
import expo.modules.core.errors.ModuleDestroyedException
Expand Down Expand Up @@ -182,6 +183,10 @@ class CameraViewModule : Module() {
}
}

Prop("autoFocus") { view, autoFocus: FocusMode? ->
view.autoFocus = autoFocus ?: FocusMode.OFF
}

OnViewDidUpdateProps { view ->
view.createCamera()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import androidx.camera.core.Camera
import androidx.camera.core.CameraInfo
import androidx.camera.core.CameraSelector
import androidx.camera.core.CameraState
import androidx.camera.core.DisplayOrientedMeteringPointFactory
import androidx.camera.core.FocusMeteringAction
import androidx.camera.core.ImageAnalysis
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
Expand Down Expand Up @@ -53,6 +55,7 @@ import expo.modules.camera.records.BarcodeType
import expo.modules.camera.records.CameraMode
import expo.modules.camera.records.CameraType
import expo.modules.camera.records.FlashMode
import expo.modules.camera.records.FocusMode
import expo.modules.camera.records.VideoQuality
import expo.modules.camera.tasks.ResolveTakenPicture
import expo.modules.camera.utils.FileSystemUtils
Expand Down Expand Up @@ -113,6 +116,18 @@ class ExpoCameraView(
shouldCreateCamera = true
}

var autoFocus: FocusMode = FocusMode.OFF
set(value) {
field = value
camera?.cameraControl?.let {
if (field == FocusMode.OFF) {
it.cancelFocusAndMetering()
} else {
startFocusMetering()
}
}
}

var videoQuality: VideoQuality = VideoQuality.VIDEO1080P
set(value) {
field = value
Expand Down Expand Up @@ -367,6 +382,20 @@ class ExpoCameraView(
.build()
}

private fun startFocusMetering() {
camera?.let {
val meteringPointFactory = DisplayOrientedMeteringPointFactory(
previewView.display,
it.cameraInfo,
previewView.width.toFloat(),
previewView.height.toFloat()
)
val action = FocusMeteringAction.Builder(meteringPointFactory.createPoint(1f, 1f), FocusMeteringAction.FLAG_AF)
.build()
it.cameraControl.startFocusAndMetering(action)
}
}

private fun observeCameraState(cameraInfo: CameraInfo) {
cameraInfo.cameraState.observe(currentActivity) {
when (it.type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ enum class CameraMode(val value: String) : Enumerable {
VIDEO("video")
}

enum class FocusMode(val value: String) : Enumerable {
ON("on"),
OFF("off")
}

data class BarcodeSettings(
@Field val barcodeTypes: List<BarcodeType>,
@Field val interval: Double?
Expand Down
14 changes: 14 additions & 0 deletions packages/expo-camera/build/Camera.types.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/expo-camera/build/Camera.types.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 26c9f49

Please sign in to comment.