expo-camera
Version:
A React component that renders a preview for the device's either front or back camera. Camera's parameters like zoom, auto focus, white balance and flash mode are adjustable. With expo-camera, one can also take photos and record videos that are saved to t
84 lines • 2.83 kB
JavaScript
import * as React from 'react';
import * as WebBarcodeScanner from './WebBarcodeScanner';
function mapToViewCoordinates(result, videoWidth, viewHeight, height, width, isMirrored) {
const scaleX = width / videoWidth;
const scaleY = viewHeight / height;
const mapPoint = (p) => {
const x = isMirrored ? width - p.x * scaleX : p.x * scaleX;
const y = p.y * scaleY;
return { x, y };
};
const origin = mapPoint(result.bounds.origin);
const size = {
width: result.bounds.size.width * scaleX,
height: result.bounds.size.height * scaleY,
};
if (isMirrored) {
origin.x -= size.width;
}
return {
...result,
bounds: { origin, size },
cornerPoints: result.cornerPoints.map(mapPoint),
};
}
export function useWebBarcodeScanner(video, { isEnabled, barcodeTypes, interval, isMirrored = false, onScanned, onError, }) {
const isRunning = React.useRef(false);
const timeout = React.useRef(undefined);
async function scanAsync() {
if (!isRunning.current || !onScanned) {
stop();
return;
}
try {
const videoEl = video.current;
if (!videoEl || videoEl.readyState !== videoEl.HAVE_ENOUGH_DATA) {
return;
}
const { videoWidth, videoHeight } = videoEl;
if (!videoWidth || !videoHeight) {
return;
}
const bitmap = await createImageBitmap(videoEl);
const results = await WebBarcodeScanner.detect(bitmap, barcodeTypes);
bitmap.close();
const viewWidth = videoEl.clientWidth || videoWidth;
const viewHeight = videoEl.clientHeight || videoHeight;
for (const raw of results) {
const nativeEvent = mapToViewCoordinates(raw, videoWidth, videoHeight, viewWidth, viewHeight, isMirrored);
onScanned({ nativeEvent });
}
}
catch (error) {
if (onError) {
onError({ nativeEvent: error });
}
}
finally {
if (interval === 0) {
stop();
return;
}
const intervalToUse = !interval || interval < 0 ? 16 : interval;
timeout.current = setTimeout(() => {
scanAsync();
}, intervalToUse);
}
}
function stop() {
isRunning.current = false;
clearTimeout(timeout.current);
}
React.useEffect(() => {
if (isEnabled) {
isRunning.current = true;
scanAsync();
}
return () => {
if (isEnabled) {
stop();
}
};
}, [isEnabled]);
}
//# sourceMappingURL=useWebBarcodeScanner.js.map