From 33bd0c473758b6fedc0b48b3f0f28beb2f64b22c Mon Sep 17 00:00:00 2001 From: Benjamin Toueg Date: Tue, 6 Dec 2016 01:58:17 +0100 Subject: [PATCH] Android pinch to zoom (#498) * Android pinch-to-zoom feature. * Missing import. --- .../RCTCamera/RCTCameraViewFinder.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java index 332935e..069cd80 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java @@ -7,6 +7,7 @@ package com.lwansbrough.RCTCamera; import android.content.Context; import android.graphics.SurfaceTexture; import android.hardware.Camera; +import android.view.MotionEvent; import android.view.TextureView; import android.os.AsyncTask; @@ -34,6 +35,7 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText private boolean _isStarting; private boolean _isStopping; private Camera _camera; + private float mFingerSpacing; // concurrency lock for barcode scanner to avoid flooding the runtime public static volatile boolean barcodeScannerTaskLock = false; @@ -317,4 +319,71 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText } } } + + @Override + public boolean onTouchEvent(MotionEvent event) { + // Get the pointer ID + Camera.Parameters params = _camera.getParameters(); + int action = event.getAction(); + + + if (event.getPointerCount() > 1) { + // handle multi-touch events + if (action == MotionEvent.ACTION_POINTER_DOWN) { + mFingerSpacing = getFingerSpacing(event); + } else if (action == MotionEvent.ACTION_MOVE && params.isZoomSupported()) { + _camera.cancelAutoFocus(); + handleZoom(event, params); + } + } else { + // handle single touch events + if (action == MotionEvent.ACTION_UP) { + handleFocus(event, params); + } + } + return true; + } + + private void handleZoom(MotionEvent event, Camera.Parameters params) { + int maxZoom = params.getMaxZoom(); + int zoom = params.getZoom(); + float newDist = getFingerSpacing(event); + if (newDist > mFingerSpacing) { + //zoom in + if (zoom < maxZoom) + zoom++; + } else if (newDist < mFingerSpacing) { + //zoom out + if (zoom > 0) + zoom--; + } + mFingerSpacing = newDist; + params.setZoom(zoom); + _camera.setParameters(params); + } + + public void handleFocus(MotionEvent event, Camera.Parameters params) { + int pointerId = event.getPointerId(0); + int pointerIndex = event.findPointerIndex(pointerId); + // Get the pointer's current position + float x = event.getX(pointerIndex); + float y = event.getY(pointerIndex); + + List supportedFocusModes = params.getSupportedFocusModes(); + if (supportedFocusModes != null && supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { + _camera.autoFocus(new Camera.AutoFocusCallback() { + @Override + public void onAutoFocus(boolean b, Camera camera) { + // currently set to auto-focus on single touch + } + }); + } + } + + /** Determine the space between the first two fingers */ + private float getFingerSpacing(MotionEvent event) { + float x = event.getX(0) - event.getX(1); + float y = event.getY(0) - event.getY(1); + return (float) Math.sqrt(x * x + y * y); + } }