Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion dist/components/Camera/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export interface CameraProps {
videoReadyCallback?(): void;
}
export declare type CameraType = React.ForwardRefExoticComponent<CameraProps & React.RefAttributes<unknown>> & {
takePhoto(): string;
takePhoto(type?: 'base64url' | 'imgData'): string | ImageData;
switchCamera(): FacingMode;
getNumberOfCameras(): number;
toggleTorch(): boolean;
torchSupported: boolean;
};
286 changes: 230 additions & 56 deletions dist/index.cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,43 @@ See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */

function __awaiter(thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}

function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}

function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
return cooked;
Expand All @@ -43,6 +80,7 @@ var Cam = styled.video(templateObject_4 || (templateObject_4 = __makeTemplateObj
});
var Canvas = styled.canvas(templateObject_5 || (templateObject_5 = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
var templateObject_1, templateObject_2, templateObject_3, templateObject_4, templateObject_5;
//# sourceMappingURL=styles.js.map

var Camera = React__default.forwardRef(function (_a, ref) {
var _b = _a.facingMode, facingMode = _b === void 0 ? 'user' : _b, _c = _a.aspectRatio, aspectRatio = _c === void 0 ? 'cover' : _c, _d = _a.numberOfCamerasCallback, numberOfCamerasCallback = _d === void 0 ? function () { return null; } : _d, _e = _a.videoSourceDeviceId, videoSourceDeviceId = _e === void 0 ? undefined : _e, _f = _a.errorMessages, errorMessages = _f === void 0 ? {
Expand All @@ -53,18 +91,57 @@ var Camera = React__default.forwardRef(function (_a, ref) {
} : _f, _g = _a.videoReadyCallback, videoReadyCallback = _g === void 0 ? function () { return null; } : _g;
var player = React.useRef(null);
var canvas = React.useRef(null);
var context = React.useRef(null);
var container = React.useRef(null);
var _h = React.useState(0), numberOfCameras = _h[0], setNumberOfCameras = _h[1];
var _j = React.useState(null), stream = _j[0], setStream = _j[1];
var _k = React.useState(facingMode), currentFacingMode = _k[0], setFacingMode = _k[1];
var _l = React.useState(false), notSupported = _l[0], setNotSupported = _l[1];
var _m = React.useState(false), permissionDenied = _m[0], setPermissionDenied = _m[1];
var _o = React.useState(false), torchSupported = _o[0], setTorchSupported = _o[1];
var _p = React.useState(false), torch = _p[0], setTorch = _p[1];
var mounted = React.useRef(false);
React.useEffect(function () {
mounted.current = true;
return function () {
mounted.current = false;
};
}, []);
React.useEffect(function () {
numberOfCamerasCallback(numberOfCameras);
}, [numberOfCameras]);
var switchTorch = function (on) {
if (on === void 0) { on = false; }
return __awaiter(void 0, void 0, void 0, function () {
var supportedConstraints, track, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!(stream && (navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) && !!mounted.current)) return [3 /*break*/, 4];
supportedConstraints = navigator.mediaDevices.getSupportedConstraints();
track = stream.getTracks()[0];
if (!(supportedConstraints && 'torch' in supportedConstraints && track)) return [3 /*break*/, 4];
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, track.applyConstraints({ advanced: [{ torch: on }] })];
case 2:
_b.sent();
return [2 /*return*/, true];
case 3:
_a = _b.sent();
return [2 /*return*/, false];
case 4: return [2 /*return*/, false];
}
});
});
};
React.useEffect(function () {
switchTorch(torch);
}, [torch]);
React.useImperativeHandle(ref, function () { return ({
takePhoto: function () {
var _a, _b, _c, _d;
takePhoto: function (type) {
var _a, _b, _c, _d, _e;
if (numberOfCameras < 1) {
throw new Error(errorMessages.noCameraAccessible);
}
Expand All @@ -75,7 +152,7 @@ var Camera = React__default.forwardRef(function (_a, ref) {
var canvasWidth = ((_c = container === null || container === void 0 ? void 0 : container.current) === null || _c === void 0 ? void 0 : _c.offsetWidth) || 1280;
var canvasHeight = ((_d = container === null || container === void 0 ? void 0 : container.current) === null || _d === void 0 ? void 0 : _d.offsetHeight) || 1280;
var canvasAR = canvasWidth / canvasHeight;
var sX = void 0, sY = void 0, sW = void 0, sH = void 0;
var sX = void 0, sY = void 0, sW = void 0, sH = void 0, imgData = void 0;
if (playerAR > canvasAR) {
sH = playerHeight;
sW = playerHeight * canvasAR;
Expand All @@ -90,11 +167,20 @@ var Camera = React__default.forwardRef(function (_a, ref) {
}
canvas.current.width = sW;
canvas.current.height = sH;
var context = canvas.current.getContext('2d');
if (context && (player === null || player === void 0 ? void 0 : player.current)) {
context.drawImage(player.current, sX, sY, sW, sH, 0, 0, sW, sH);
if (!context.current) {
context.current = canvas.current.getContext('2d', { willReadFrequently: true });
}
if (context.current && (player === null || player === void 0 ? void 0 : player.current)) {
context.current.drawImage(player.current, sX, sY, sW, sH, 0, 0, sW, sH);
}
switch (type) {
case 'imgData':
imgData = (_e = context.current) === null || _e === void 0 ? void 0 : _e.getImageData(0, 0, sW, sH);
break;
default: /* base64url */
imgData = canvas.current.toDataURL('image/jpeg');
break;
}
var imgData = canvas.current.toDataURL('image/jpeg');
return imgData;
}
else {
Expand All @@ -115,11 +201,18 @@ var Camera = React__default.forwardRef(function (_a, ref) {
getNumberOfCameras: function () {
return numberOfCameras;
},
toggleTorch: function () {
var torchVal = !torch;
setTorch(torchVal);
return torchVal;
},
torchSupported: torchSupported,
}); });
React.useEffect(function () {
initCameraStream(stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied);
initCameraStream(stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied, !!mounted.current);
}, [currentFacingMode, videoSourceDeviceId]);
React.useEffect(function () {
switchTorch(false).then(function (success) { return setTorchSupported(success); });
if (stream && player && player.current) {
player.current.srcObject = stream;
}
Expand All @@ -141,57 +234,137 @@ var Camera = React__default.forwardRef(function (_a, ref) {
React__default.createElement(Canvas, { ref: canvas }))));
});
Camera.displayName = 'Camera';
var initCameraStream = function (stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied) {
var shouldSwitchToCamera = function (currentFacingMode) { return __awaiter(void 0, void 0, void 0, function () {
var cameras;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
cameras = [];
if (!(currentFacingMode === 'environment')) return [3 /*break*/, 2];
return [4 /*yield*/, navigator.mediaDevices.enumerateDevices().then(function (devices) {
var videoDevices = devices.filter(function (i) { return i.kind == 'videoinput'; });
videoDevices.forEach(function (device) {
var capabilities = device.getCapabilities();
if (capabilities.facingMode && capabilities.facingMode.indexOf('environment') >= 0 && capabilities.deviceId) {
cameras.push(capabilities.deviceId);
}
});
})];
case 1:
_a.sent();
_a.label = 2;
case 2:
if (cameras.length > 1) {
return [2 /*return*/, cameras.pop()];
}
return [2 /*return*/, undefined];
}
});
}); };
var initCameraStream = function (stream, setStream, currentFacingMode, videoSourceDeviceId, setNumberOfCameras, setNotSupported, setPermissionDenied, isMounted) { return __awaiter(void 0, void 0, void 0, function () {
var cameraDeviceId, switchToCamera, constraints, getWebcam;
var _a;
// stop any active streams in the window
if (stream) {
stream.getTracks().forEach(function (track) {
track.stop();
});
}
var constraints = {
audio: false,
video: {
deviceId: videoSourceDeviceId ? { exact: videoSourceDeviceId } : undefined,
facingMode: currentFacingMode,
width: { ideal: 1920 },
height: { ideal: 1920 },
},
};
if ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) {
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
setStream(handleSuccess(stream, setNumberOfCameras));
})
.catch(function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
var getWebcam = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (getWebcam) {
getWebcam(constraints, function (stream) {
setStream(handleSuccess(stream, setNumberOfCameras));
}, function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
// stop any active streams in the window
if (stream) {
stream.getTracks().forEach(function (track) {
track.stop();
});
}
return [4 /*yield*/, shouldSwitchToCamera(currentFacingMode)];
case 1:
switchToCamera = _b.sent();
if (switchToCamera) {
cameraDeviceId = switchToCamera;
}
else {
cameraDeviceId = videoSourceDeviceId ? { exact: videoSourceDeviceId } : undefined;
}
constraints = {
audio: false,
video: {
deviceId: cameraDeviceId,
facingMode: currentFacingMode,
},
};
if ((_a = navigator === null || navigator === void 0 ? void 0 : navigator.mediaDevices) === null || _a === void 0 ? void 0 : _a.getUserMedia) {
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) { return __awaiter(void 0, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!isMounted) return [3 /*break*/, 2];
_a = setStream;
return [4 /*yield*/, handleSuccess(stream, setNumberOfCameras)];
case 1:
_a.apply(void 0, [_b.sent()]);
_b.label = 2;
case 2: return [2 /*return*/];
}
});
}); })
.catch(function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
getWebcam = navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia;
if (getWebcam) {
getWebcam(constraints, function (stream) { return __awaiter(void 0, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!isMounted) return [3 /*break*/, 2];
_a = setStream;
return [4 /*yield*/, handleSuccess(stream, setNumberOfCameras)];
case 1:
_a.apply(void 0, [_b.sent()]);
_b.label = 2;
case 2: return [2 /*return*/];
}
});
}); }, function (err) {
handleError(err, setNotSupported, setPermissionDenied);
});
}
else {
setNotSupported(true);
}
}
return [2 /*return*/];
}
else {
setNotSupported(true);
});
}); };
var handleSuccess = function (stream, setNumberOfCameras) { return __awaiter(void 0, void 0, void 0, function () {
var tr, cp;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
tr = stream.getVideoTracks()[0];
cp = tr.getCapabilities();
return [4 /*yield*/, tr.applyConstraints({
width: (_a = cp.width) === null || _a === void 0 ? void 0 : _a.max,
height: (_b = cp.height) === null || _b === void 0 ? void 0 : _b.max,
})];
case 1:
_c.sent();
navigator.mediaDevices
.enumerateDevices()
.then(function (r) { return setNumberOfCameras(r.filter(function (i) { return i.kind === 'videoinput'; }).length); });
return [2 /*return*/, stream];
}
}
};
var handleSuccess = function (stream, setNumberOfCameras) {
navigator.mediaDevices
.enumerateDevices()
.then(function (r) { return setNumberOfCameras(r.filter(function (i) { return i.kind === 'videoinput'; }).length); });
return stream;
};
});
}); };
var handleError = function (error, setNotSupported, setPermissionDenied) {
console.error(error);
//https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
Expand All @@ -202,5 +375,6 @@ var handleError = function (error, setNotSupported, setPermissionDenied) {
setNotSupported(true);
}
};
//# sourceMappingURL=Camera.js.map

exports.Camera = Camera;
Loading