capacitor-community/camera-preview

Image is unfocusing after tapping overlay elements

Closed this issue · 8 comments

Is there a way to prevent the camera from focusing when I tap on an element on the screen? Or is there a way to programmatically set the focus to a point on the screen?

This is my config:

x: 0,
y: 0,
width: window.screen.width,
enableHighResolution: true,
height: window.screen.height,
toBack: true,
storeToFile: false,
disableAudio: true,
enableZoom: true

Hi @pedrumgolriz there isn't a setting to prevent this, which is an oversight. For now, can you try using CSS pointer-events to stop people interacting with the camera?

Thank you @pbowyer

I have successfully created a set focusPoint method in Android:

@PluginMethod
    public void focusPoint(PluginCall call){
        if (this.hasCamera(call) == false) {
            call.reject("Camera is not running");
            return;
        }
        Logger.debug("x:"+call.getInt("x"));
        Logger.debug("y:"+call.getInt("y"));
        fragment.setFocusArea(call.getInt("x"), call.getInt("y"), new Camera.AutoFocusCallback() {
                                                        public void onAutoFocus(boolean success, Camera camera) {
                                                            if (success) {
                                                                Logger.debug("onTouch:" + " setFocusArea() succeeded");
                                                            } else {
                                                                Logger.debug("onTouch:" + " setFocusArea() did not suceed");
                                                            }
                                                        }
                                                    });
    }

But I am unable to get it working in iOS. I know this is probably irrelevant to this ticket, but if you can point me in the right direction that would be awesome. I have the following code but keep getting the error " CameraPreview does not respond to method call "focusPoint" using selector "focusPoint:""

In CameraController.swift:

func focusPoint(x: Int, y: Int) throws{
        guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
        do {
            try device.lockForConfiguration()
            let focusMode = AVCaptureDevice.FocusMode.autoFocus
            if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(focusMode) {
                device.focusPointOfInterest = CGPoint(x: CGFloat(x ?? 0), y: CGFloat(y ?? 0))
            }
            device.unlockForConfiguration()
        } catch {
            debugPrint(error)
        }
    }

In Plugin.swift:

@objc func focusPoint(_ call: CAPPluginCall) throws{
        do {
            try self.cameraController.focusPoint(x: call.getInt("x") ?? 0, y: call.getInt("y") ?? 0)
            call.resolve()
        } catch {
            call.reject("failed to set focus")
        }
    }

And in Plugin.m:
CAP_PLUGIN_METHOD(focusPoint, CAPPluginReturnPromise);

Ah figured it out, removed "throws" in Plugin.swift so it shows as:

@objc func focusPoint(_ call: CAPPluginCall){
        guard let x = call.getInt("x") else{
            call.reject("failed to set focuspoint, x is missing")
            return
        }
        
        guard let y = call.getInt("y") else{
            call.reject("failed to set focuspoint, x is missing")
            return
        }
        do {
            try self.cameraController.focusPoint(x: x, y: y)
            call.resolve()
        } catch {
            call.reject("failed to set focus")
        }
    }

I changed it a bit in CameraController as well for better results:

func focusPoint(x: Int, y: Int) throws{
        guard let device = self.currentCameraPosition == .rear ? rearCamera : frontCamera else { return }
        do {
            try device.lockForConfiguration()
            let focusMode = AVCaptureDevice.FocusMode.continuousAutoFocus
            if device.isFocusPointOfInterestSupported && device.isFocusModeSupported(focusMode) {
                device.focusMode = AVCaptureDevice.FocusMode.locked;
                device.focusPointOfInterest = CGPoint(x: CGFloat(x), y: CGFloat(y))
                device.focusMode = AVCaptureDevice.FocusMode.continuousAutoFocus;
            }
            device.unlockForConfiguration()
        } catch {
            debugPrint(error)
        }
    }

In definitions.ts in case anyone is wondering:
export interface CameraPreviewXY { x?: number, y?: number }
focusPoint(options: CameraPreviewXY): void;

Hello @pedrumgolriz Can you please create a merge request to add this code please ?
I need to be able to focus taping on the screen.

Btw how do you add this code to your local project ? with android studio ? or do you use your own repo for this plugin, and then install your own plugin in your capacitor project ?

@pbowyer what do you think about this code ?
There is no way right now to tap to focus on android:(

@nicolidin My issue here was that the tap to focus was still happening when clicking on items on the screen (buttons, etc..). The methods above would set focus programmatically rather than tapping on a point on the screen. I just overwrote the classes from the node module (from what I remember). I no longer use camera-preview as the picture quality wasn't good enough for my needs

Okay, thanks @pedrumgolriz. Not handling that kind of issue is not a big deal at all because it is about the web component that has to handle the z-index and thus, not call focusPoint() when clicking on an element that is on top of the camera div. So, I think @pbowyer, we can create an MR and merge it to finally make this feature available to everyone!"

Created PR for y'all, please test when you have the time