DOT Web Face Auto Capture
v6.2.0
Introduction
DOT Web Face Auto Capture is set of Non-ui component and Ui component web components to capture image of user’s face.
Non-ui component is a web component that renders the video stream from an available phone or web camera to automatically capture an image of a user’s face with the required quality.
Ui component is a web component that renders an overlay over video stream. Overlay includes a placeholder, camera control buttons and instructions to guide the user to position their face correctly.
Supported Browsers
DOT Web Face Auto Capture was tested with:
Chrome on desktop (Windows, Mac and Linux) and mobile (Android, iPhone)
Firefox on desktop (Windows, Mac and Linux) and mobile (Android)****
Edge on Windows
Safari on Mac, iPad and iPhone
WebView on Android*
SafariVC on iPad and iPhone**
WKWebView on iPad and iPhone***
Known issues:
* Some older Android phones can experience issues with camera stream initialization using WebRTC. Our web components will work on most of them, but camera stream could be slow and laggy. This issue is caused by device and can be experienced in any website using WebRTC in Android WebView.
** Components are tested with SafariVC on devices iPhone 7 and newer with iOS 15 or iPadOS 15 or newer. Older devices or iOS versions are not officially supported and might experience issues.
*** In order to run DOT Web Face Auto Capture in WKWebView on iPhone or iPad, allowsInlineMediaPlayback
and mediaTypesRequiringUserActionForPlayback
properties on WKWebViewConfiguration
must be set to true
.
**** Some older and/or low-end Android phones can experience issues with camera stream initialization using WebRTC when using Firefox browser. Our web components might display The webcam is already in use by another application
error. This issue is caused by the Firefox’s implementation of initialization of camera and can be experienced in any website using WebRTC in Firefox on Android. It is recommended to use other supported browsers in those cases.
Privacy and security
This component can only be used in secure contexts due to MediaDevices
API used for handling camera access. A secure context is, in short, a page loaded using HTTPS or the file:///
URL scheme, or a page loaded from localhost
. Before accessing any camera, the component must always get the user’s permission. Browsers may offer a once-per-domain permission feature, but they must ask at least the first time, and the user has to specifically grant ongoing permission if they choose to do so. Browsers are required to display an indicator that shows that a camera or microphone is in use. More details can be found on MDN docs.
Non-ui component
Requirements
Minimum required camera resolution for appropriate results is 720x720. Anything less is insufficient.
Initialization
DOT Web Face Auto Capture can be installed via NPM, yarn or pnpm
npm install @innovatrics/dot-face-auto-capture
To manually integrate the DOT Web Face Auto Capture, download latest version from the Github repository. Then add following line to dependencies in your package.json:
"dependencies": {
"@innovatrics/dot-face-auto-capture": "file:innovatrics-dot-face-auto-capture-[VERSION].tgz"
},
where [VERSION]
is the DOT Web Face Auto Capture version integrated. This installs dot-face-auto-capture
as an external module that can then be used (just like any other module in the code). For example, one could do import '@innovatrics/dot-face-auto-capture';
in the app.
Usage
Face auto capture component is a web component which uses custom HTML <x-dot-face-auto-capture/>
tag.
Properties cameraOptions
needs to be passed into component after <x-dot-face-auto-capture/>
tag was rendered.
import type {
FaceCameraProps,
HTMLFaceCaptureElement,
FaceCallback
} from "@innovatrics/dot-face-auto-capture";
import { useEffect } from "react";
import "@innovatrics/dot-face-auto-capture";
const FaceCamera = (props: FaceCameraProps) => {
useEffect(() => {
const faceAutoCaptureHTMLElement = document.getElementById(
"x-dot-face-auto-capture"
) as HTMLFaceCaptureElement | null;
if (faceAutoCaptureHTMLElement) {
faceAutoCaptureHTMLElement.cameraOptions = props;
}
});
return <x-dot-face-auto-capture id="x-dot-face-auto-capture" />;
};
const Page = () => {
const handleFacePhotoTaken: FaceCallback = ({ image, data }, content) => {
// ...
};
const handleError = (error: Error) => {
alert(error);
};
return (
<FaceCamera
cameraFacing="user"
onPhotoTaken={handleFacePhotoTaken}
onError={handleError}
sessionToken="1111-222-333-4444"
/>
);
};
Alternatively, you can use useRef
and useLayoutEffect
to render a web component with its props.
import type {
FaceCameraProps,
HTMLFaceCaptureElement,
} from '@innovatrics/dot-face-auto-capture';
import { useLayoutEffect, useRef } from 'react';
import '@innovatrics/dot-face-auto-capture';
const FaceCamera = (props: FaceCameraProps) => {
const ref = useRef<HTMLFaceCaptureElement | null>(null);
useLayoutEffect(() => {
const element = ref.current;
if (element) {
element.cameraOptions = props;
}
}, [props]);
return <x-dot-face-auto-capture id="x-dot-face-auto-capture" ref={ref} />;
};
iOS - Requesting DeviceMotion Permissions
To utilize the device motion sensor and provide instructions for device_pitched
instruction on iOS , it’s necessary to invoke the DeviceMotionEvent.requestPermission()
method and acquire user consent. This requirement is set by Apple and isn’t specific to the DOT Web Face Auto Capture. The method returns a promise that yields a string – either "granted" or "denied". If the user has already granted permission, the promise will resolve instantly.
Unfortunately DeviceMotionEvent.requestPermission()
could only be called on a "user gesture" event, such as a button click. Requesting permission without a user gesture event isn’t feasible. Given that, DOT Web Face Auto Capture doesn’t produce any suitable user gesture event, the method must be invoked from the parent component when a user gesture event takes place. For example, when user clicks a button "Continue to take selfie". Below is a TypeScript example illustrating the process:
type DeviceMotionEventWithPermissions = {
requestPermission: () => Promise<PermissionState>;
} & DeviceMotionEvent;
try {
const { requestPermission } = DeviceMotionEvent as unknown as DeviceMotionEventWithPermissions;
if (typeof requestPermission === "function") {
const response = await requestPermission();
if (response === "granted") {
// permissions granted
} else {
// permissions denied
}
}
} catch (error) {
// handle error in standard way
}
Without this permission, the device_pitched
instruction will not be available but the component will still work. Further information on this can be found in this article.
TypeScript
Declaration file is bundled inside package. To use with TypeScript, import types from @innovatrics/dot-face-auto-capture
.
import type { FaceCallback, FaceCameraProps } from "@innovatrics/dot-face-auto-capture";
Hosting WASM files
During the initialization phase of the component, the component loads the required WASM binary files via HTTP fetch request. Please note that we do not provide any hosting for WASM files. That’s why it is essential that the customer provides the component with all WASM files from our distribution.
To do so, please copy wasm
directory from our distribution into your distribution every time you update to new version of the component. If you are using package manager, you can find wasm
directory in node_modules/@innovatrics/dot-face-auto-capture/wasm
.
@innovatrics/
|__ dot-face-auto-capture/
|__ wasm/ <-- copy this directory
|-- sam.wasm
|-- sam_simd.wasm
|-- dot_embedded_bg.wasm
...
|-- package.json
|-- README.md
...
By default, the component will try to fetch the desired wasm file from <PROJECT_ORIGIN>/wasm/<NAME_OF_DESIRED_FILE>.wasm
. This can be changed using wasmDirectoryPath
property. For example, if wasmDirectoryPath=/my-directory
property is provided, the component will try to fetch the desired wasm file from <PROJECT_ORIGIN>/my-directory/<NAME_OF_DESIRED_FILE>.wasm
. Please, do not provide absolute path to single wasm file, but only to the directory containing all wasm files. For more information, check out our samples on Github where you can find real examples of how to host wasm files in various technologies such as React, Angular, Vue, etc.
Troubleshooting
If you are having difficulties with hosting wasm files, check your browser console in dev tools. You should see an error message with more details about the problem. It’s also a good idea to look at the network tab in the developer tools and check that the wasm file has been loaded correctly. Please pay close attention to the actual response of the wasm load request, as an HTTP 200 status does not necessarily mean that the wasm file was loaded correctly. If you see application/wasm
in response type, then wasm file was loaded correctly. If you see e.g. text/html
in response type, then wasm file was not loaded correctly.
Licensing
In order to support wide adoption of the components, a free mode was developed in addition to the premium mode used by licensed customers.
Free mode
Components run in the free mode by default. This mode does not impose any feature limits, it just displays an watermark overlay over the component, to indicate not-licensed deployment. The overlay looks as on the image below:
Premium
To run components in premium mode, dot_embedded_bg.wasm
and valid license files are needed.
To initialize WASM binary file please follow a steps in Hosting WASM files.
To use your license file you need to copy it to project public directory as <PROJECT_ORIGIN>/iengine.lic
.
By default, the component will try to fetch the desired license file from <PROJECT_ORIGIN>/iengine.lic
or <PROJECT_ORIGIN>/license.lic
*. This can be changed using licensePath
property. For example if licensePath=/my-license.lic
property is provided, the component will try to fetch the license file from <PROJECT_ORIGIN>/my-license.lic
.
* Please note that fetching license from <PROJECT_ORIGIN>/license.lic
by default is deprecated and will be removed in future versions. Please use <PROJECT_ORIGIN>/iengine.lic
instead.
If one of the following steps fails, then component will run in [Freemium] mode:
WASM binary file not found
license file not found
license is not valid
In order to obtain the license, please contact your Innovatrics’ representative.
Properties
(Optional)
['user']
string cameraFacing
– Defines which camera to acquire from the browser’s getUserMedia API'user'
– The video source is facing toward the user; this is the selfie or front-facing camera on a smartphone'environment'
– The video source is facing away from the user, thereby viewing their environment; this is the back camera on a smartphone
function onPhotoTaken
– Callback on successful image capture(image, data) ⇒ void
- (see Callback parameters)
function onError
– Callback in the case that an error occurred (see Handling errors)(e: Error) ⇒ void
(Optional)
string wasmDirectoryPath
- Path to the location, where the directory with all wasm binary files are hosted(Optional)
string licensePath
- Path to the license file(Optional)
string sessionToken
– Unique identifier of the session(Optional)
object thresholds
- Detection configuration(Optional)
[0.4]
number faceConfidence
- Detection confidence threshold(Optional)
[0.3]
number sharpnessThreshold
- Low sharpness threshold(Optional)
[0.2]
number brightnessLowThreshold
- Low brightness threshold(Optional)
[0.85]
number brightnessHighThreshold
- High brightness threshold(optional)
[0.05]
number outOfBoundsThreshold
- Face out of bounds threshold(Optional)
[0.16]
number minFaceSizeRatio
- Minimum face size ratio relative to shorter side of the camera resolution(Optional)
[0.2]
number maxFaceSizeRatio
- Maximum face size ratio relative to shorter side of the camera resolution(Optional)
[30]
number devicePitchAngleThreshold
- Maximum and minimum device pitch angle in degrees
(Optional)
HTMLElement styleTarget
- Provide an alternate DOM node to inject styles. DOM node has to exist inside DOM before auto-capture component is initialized. This is useful when rendering components in a shadow DOM. By default, the styles are injected into the<head>
element of the document. See [style-target] example for more details.(Optional)
['AUTO_CAPTURE']
captureMode
- Defines a strategy for how a detection captures the desired image'AUTO_CAPTURE'
- It is a standard way of how a detection captures an image. See Auto capture'WAIT_FOR_REQUEST'
- Detection waits for request to capture an image. See Wait for request
Callback parameters
object data
Blob image
– Returned image on successful capture injpeg
formatobject data
object detection
- Object contains all detection parameters and its values. Present if image was taken using auto capture (not manual capture).object imageResolution
- Width and height of the captured image.
Uint8Array content
- output for DOT Digital Identity Service
Multi capture
Face auto capture component allows you to capture an unlimited number of faces without the need to reinitialize the webcam and detector.
Component calls onPhotoTaken
callback on every captured face photo. When onPhotoTaken
is called, detection is paused. Camera stream and face detector stay initialized.
Component is in waiting state. You should implement a custom UI for waiting state (e.g. overlay over our component). We provide a default UI, but it is not customizable.
Capture mode
Defines a strategy for how a detection captures the desired image.
Auto capture
It is an automated process that attempts to capture multiple valid images and selects the best one from them. If the component captures at least two valid images, it enters a phase called candidate selection. Once this phase is complete, the best image is selected and returned by the component using the onPhotoTaken
callback.
Wait for request
It is a manual process that allows you to capture an image on request. In this mode, the component is ready and waiting for your command. More details about how to request an image can be found in Control Events. Once the component receives a request, it returns either the first image or the first valid image using the onPhotoTaken
callback.
Please note that in this mode, the candidate selection phase used in Auto capture is ignored.
Implement dispatch 'continue-detection' event
import { dispatchControlEvent, FaceCustomEvent, ControlEventInstruction } from "@innovatrics/dot-face-auto-capture/events";
const continueDetection = () => {
dispatchControlEvent(FaceCustomEvent.CONTROL, ControlEventInstruction.CONTINUE_DETECTION)
};
Without importing @innovatrics/dot-face-auto-capture/events
.
function continueDetection() {
document.dispatchEvent(
new CustomEvent("face-auto-capture:control", {
detail: { instruction: "continue-detection" },
}),
);
}
Handling errors
When an error occurs, we call onError
callback with one parameter of type Error
. We set name
property to AutoCaptureError
, and also message
with more details.
Component renders default UI for error state, but is not customizable, and integrator should implement own error handling.
Component uses the MediaDevices API that provides access to connected media input devices like cameras and microphones.
If the user denies permission to access or the webcam is not present, an error is thrown. We provide original error thrown by browser inside cause
property of the error object.
List of possible errors can be found on MDN docs.
Error example:
{
name: "AutoCaptureError",
message: "The webcam is already in use by another application",
cause: DOMException: Could not start video source // Original error thrown by browser MediaDevices API
}
Ui component
Requirements
Both components must be wrapped in parent div with position: relative
.
<div style={{position: "relative"}}>
<FaceUi />
<FaceCamera
cameraFacing="user"
onPhotoTaken={handlePhotoTaken}
onError={onError}
/>
</div>
Initialization
UI component can be installed via NPM, yarn or pnpm
npm install @innovatrics/dot-auto-capture-ui
To manually integrate UI component, download latest version from the Github repository. Add following line to dependencies in your package.json:
"dependencies": {
"@innovatrics/dot-auto-capture-ui": "file:innovatrics-dot-auto-capture-ui-[VERSION].tgz",
}
where [VERSION]
is the DOT Web Face Auto Capture version integrated. This installs dot-auto-capture-ui
as an external module that can be used (just like any other module in the code). For example, one could do import '@innovatrics/dot-auto-capture-ui';
in the app.
Usage
Face auto capture UI component is an web component which uses custom HTML <x-dot-face-auto-capture-ui />
tag.
Properties props
needs to be passed into component after <x-dot-face-auto-capture-ui />
tag was rendered.
import type { FaceUiProps, HTMLFaceUiElement } from "@innovatrics/dot-auto-capture-ui/face";
import { useEffect } from "react";
import "@innovatrics/dot-auto-capture-ui/face";
const FaceUi = (props: FaceUiProps) => {
useEffect(() => {
const uiElement = document.getElementById("x-dot-face-auto-capture-ui") as HTMLFaceUiElement | null;
if (uiElement) {
uiElement.props = props;
}
});
return <x-dot-face-auto-capture-ui id="x-dot-face-auto-capture-ui" />;
};
Alternatively, you can use useRef
and useLayoutEffect
to render a web component with its props.
import type { FaceUiProps, HTMLFaceUiElement } from "@innovatrics/dot-auto-capture-ui/face";
import { useLayoutEffect, useRef } from "react";
import "@innovatrics/dot-auto-capture-ui/face";
const FaceUi = (props: FaceUiProps) => {
const ref = useRef<HTMLFaceUiElement| null>(null);
useLayoutEffect(() => {
const element = ref.current;
if (element) {
element.props = props;
}
}, [props]);
return <x-dot-face-auto-capture-ui id="x-dot-face-auto-capture-ui" ref={ref} />;
};
TypeScript
Declaration files are bundled inside package. Just import types from @innovatrics/dot-auto-capture-ui/face
.
Properties
(Optional)
string placeholder
- One of the predefined placeholders in component that can be selected'circle-solid'
'ellipse-solid'
- Deprecated'man-solid'
- Deprecated'woman-solid'
- Deprecated'square-rounded-dash'
'square-rounded-solid'
'square-dash'
'square-solid'
Placeholders 'man-solid'
, 'woman solid'
and 'ellipse-solid'
are deprecated. Please use one of our alternative placeholders instead.
(Optional)
string backdropColor
- To customize the color of the default face placeholder backdrop. E.g.:'rgba(10, 10, 10, 0.5)'
Please note that the backdrop can only be used with the default face placeholder. If you prefer not to use the backdrop, you can set the backdropColor to 'none'
.
(Optional)
object instructions
- Modification of default messages for localization or customization(Optional)
['Stay still…']
string candidate_selection
- Shown when all validations are passed, i.e. the image is suitable for capture(Optional)
['Move back']
string face_too_close
- Shown when the face is too close to the camera(Optional)
['Move closer']
string face_too_far
- Shown when the face is too far from the camera(Optional)
['Center your face']
string face_centering
- Shown when the face is not centered in the placeholder(Optional)
['Position your face into the circle']
string face_not_present
- Shown when no face is detected(Optional)
['Position your face into the circle']
string left_eye_not_present
- Shown when left eye is not detected(Optional)
['Position your face into the circle']
string right_eye_not_present
- Shown when right eye is not detected(Optional)
['Position your face into the circle']
string mouth_not_present
- Shown when mouth is not detected(Optional)
['Turn face against light']
string sharpness_too_low
- Shown when the face in the image is not sharp enough(Optional)
['Turn face against light']
string brightness_too_low
- Shown when the image is too dark(Optional)
['Less light needed']
string brightness_too_high
- Shown when the image is too bright.(Optional)
['Hold your phone at eye level']
string device_pitched
- Shown when the device is pitched too much.
(Optional)
theme
- Modification of theme properties.(Optional)
colors
- To customize colors of following properties(Optional)
['white']
color placeholderColor
- Color of the placeholder lines(Optional)
['#00BFB2']
color placeholderColorSuccess
- Color of the placeholder lines when all validations are passed(Optional)
['white']
color instructionColor
- Instruction background color(Optional)
['#00BFB2']
color instructionColorSuccess
- Instruction background color when all validations are passed(Optional)
['black']
color instructionTextColor
- Instruction text color
(Optional)
font
- To customize font with following properties(Optional)
['Montserrat']
string family
- Font family. Please note that the chosen font must be installed and available in the styles of the web components for it to display correctly.(Optional)
[14]
number minimumSize
- Minimum font size, from which the actual font size is calculated relative to the component width/height(Optional)
['normal']
string style
- Font style(Optional)
[600]
string|number weight
- Font weight
(Optional)
appStateInstructions
- Modification of default messages for component state(Optional)
loading
- Component loading state(Optional)
['Loading. Please wait.']
string text
- Text shown while component is loading(Optional)
[true]
boolean visible
- Show/hide loading instruction while component is loading
(Optional)
waiting
- Component waiting state(Optional)
['Waiting for input']
string text
- Text shown while component is waiting(Optional)
[true]
boolean visible
- Show/hide waiting instruction while component is waiting
(Optional)
[false]
boolean
showDetectionLayer
- Show/hide detection layer on top of component(Optional)
[false]
boolean
showCameraButtons
- Show/hide camera buttons (switch camera and toggle mirror) on top of component(Optional)
HTMLElement styleTarget
- Provide an alternate DOM node to inject styles. DOM node has to exist inside DOM before auto-capture component is initialized. This is useful when rendering components in a shadow DOM. By default, the styles are injected into the<head>
element of the document. See [style-target] example for more details.
Example how to use UI properties:
<FaceUi
theme={{ colors: { placeholderColor: "green" }, font: { style: 'italic' } }}
placeholder="ellipse-solid"
instructions={{ candidate_selection: "Candidate selection" }}
appStateInstructions={{ loading: { text: "Component is loading", visible: true } }}
showDetectionLayer
showCameraButtons
/>
Example how to use backdropColor
prop for the default face placeholder backdrop:
<FaceUi
theme={{ colors: { placeholderColor: "green" }, font: { style: 'italic' } }}
backdropColor="rgba(10, 10, 10, 0.5)"
instructions={{ candidate_selection: "Candidate selection" }}
appStateInstructions={{ loading: { text: "Component is loading", visible: true } }}
showDetectionLayer
showCameraButtons
/>
Example how to import fonts (using head in main html file):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="" href="" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Title</title>
<!-- import font in the head -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat&display=swap" rel="stylesheet">
<!------->
</head>
</html>
Example how to use styleTarget
prop with Ui component when using Shadow DOM:
This approach also works for Non-ui component.
import type { FaceUiProps, FaceUiElement } from "@innovatrics/dot-auto-capture-ui/face";
import "@innovatrics/dot-auto-capture-ui/face";
import { useEffect } from "react";
const FacetUi = (props: FaceUiProps) => {
useEffect(() => {
const uiElement = document.getElementById(
"x-dot-face-auto-capture-ui"
) as HTMLFaceUiElement | null;
const styleNode = document.createElement('div');
uiElement?.shadowRoot?.append(styleNode);
if (uiElement) {
uiElement.props = {
...props,
styleTarget: styleNode,
};
}
});
return <x-dot-face-auto-capture-ui id="x-dot-face-auto-capture-ui" />;
};
HTML of example above will look like this:
<x-dot-face-auto-capture-ui id="x-dot-face-auto-capture-ui">
#shadow-root (open)
<div>
<style data-styled="active" data-styled-version="6.1.0">
/* CSS styles will be injected here*/
</style>
</div>
</x-dot-face-auto-capture-ui>
Custom Events - Optional
Communication between components is based on custom events. Ui
component is mostly listening to events dispatched by non-ui
component. In case of CONTROL
event, ui
component dispatches control events to control non-ui
component.
When using default [face-auto-capture-ui] component, only dispatch continue-detection
event has to be implemented to use Multi capture.
Type of Events
Currently all events being used are described in this section. These are sufficient to build custom UI layer.
enum FaceCustomEvent
- Event names dispatched by componentsCONTROL = 'face-auto-capture:control
- Events dispatched from 'ui' component to controlnon-ui
component. Described in Control Events section
CAMERA_PROPS_CHANGED = 'face-auto-capture:camera-props-changed'
- Notifies UI when camera properties has changedINSTRUCTION_CHANGED = 'face-auto-capture:instruction-changed'
- Notifies UI when instruction has changedSTATE_CHANGED = 'face-auto-capture:state-changed'
- Notifies UI when state ofnon-ui
component has changedDETECTED_FACE_CHANGED = 'face-auto-capture:detected-face-changed'
- Notifies UI when face is detected. Used in Detection Layer, has no effect ifshowDetectionLayer = false
VIDEO_ELEMENT_SIZE = 'face-auto-capture:video-element-size'
- Notifies UI when HTML video element size has changed
enum ComponentCustomEvent
- Event names dispatched by componentsREQUEST_CAPTURE - dot-custom-event:request-capture
- Event dispatched from outside of Non-ui component to request capture when component is running inWAIT_FOR_REQUEST
capture mode. Described in Control Events section
Usage
Import @innovatrics/dot-face-auto-capture/events
to use event types and and dispatch control events.
Listening to the Events
All event listeners are already implemented in default [face-auto-capture-ui] component. Skip this section if you are using default ui
component.
All FaceCustomEvent
events, except CONTROL
, are dispatched by Face Auto Capture non-ui
component. Ui
component listens to these events to make appropriate changes. See the example below how to register event listeners.
import type {
CameraPropsChangeEvent,
CameraStateChangeEvent,
VideoElementSizeChangeEvent,
FaceInstructionChangeEvent
DetectedFaceChangeEvent
} from "@innovatrics/dot-face-auto-capture/events";
import { FaceCustomEvent } from "@innovatrics/dot-face-auto-capture/events";
import type {
AppState,
FaceInstructionCode,
Resolution,
AutoCaptureError
} from "@innovatrics/dot-face-auto-capture";
import { useEffect, useState } from "react";
export const Events = () => {
const [instructionCode, setInstructionCode] = useState<FaceInstructionCode | undefined>();
const [cameraResolution, setCameraResolution] = useState<Resolution | undefined>();
const [isMirroring, setIsMirroring] = useState<boolean | undefined>();
const [appState, setAppState] = useState<AppState | undefined>();
const [error, setError] = useState<AutoCaptureError | undefined>();
const [videoElementSize, setVideoElementSize] = useState<DOMRect | undefined>();
const [detectedFaceCorners, setDetectedFaceCorners] = useState<DetectedFaceCorners | undefined>();
useEffect(() => {
const handleInstruction = (event: FaceInstructionChangeEvent) => {
setInstructionCode(event?.detail?.instructionCode);
};
const handleCameraProps = (event: CameraPropsChangeEvent) => {
setCameraResolution(event?.detail?.cameraResolution);
setIsMirroring(event?.detail?.isMirroring);
};
const handleAppState = (event: CameraStateChangeEvent) => {
setAppState(event?.detail?.appState);
const error = event?.detail?.error;
if (error) {
setError(error);
}
};
const handleVideoElementSize = (event: VideoElementSizeChangeEvent) => {
setVideoElementSize(event.detail?.size)
}
const handleDetectedFace = (event: DetectedFaceChangeEvent) => {
setDetectedFaceCorners(event?.detail?.detectedCorners)
}
document.addEventListener(FaceCustomEvent.INSTRUCTION_CHANGED, handleInstruction);
document.addEventListener(FaceCustomEvent.CAMERA_PROPS_CHANGED, handleCameraProps);
document.addEventListener(FaceCustomEvent.STATE_CHANGED, handleAppState);
document.addEventListener(FaceCustomEvent.VIDEO_ELEMENT_SIZE, handleVideoElementSize)
document.addEventListener(FaceCustomEvent.DETECTED_FACE_CHANGED, handleDetectedFace)
return () => {
document.removeEventListener(FaceCustomEvent.INSTRUCTION_CHANGED, handleInstruction);
document.removeEventListener(FaceCustomEvent.CAMERA_PROPS_CHANGED, handleCameraProps);
document.removeEventListener(FaceCustomEvent.STATE_CHANGED, handleAppState);
document.removeEventListener(FaceCustomEvent.VIDEO_ELEMENT_SIZE, handleVideoElementSize);
document.removeEventListener(FaceCustomEvent.DETECTED_FACE_CHANGED, handleDetectedFace)
};
}, [])
}
Without importing @innovatrics/dot-face-auto-capture/events
you can use values of FaceCustomEvent
directly.
const instructionChangeEvent = "face-auto-capture:instruction-changed";
function handleInstructionChange(event) {
console.log(event.detail.instructionCode)
}
document.addEventListener(instructionChangeEvent, handleInstructionChange);
/**
* remove event listener when you're done
*/
document.removeEventListener(instructionChangeEvent, handleInstructionChange);
Control Events
Control events are dispatched from outside of Non-ui component to control it.
FaceCustomEvent.CONTROL
Events are dispatched from Ui component to control Non-ui component.
enum ControlEventInstruction
CONTINUE_DETECTION = 'continue-detection'
- Controls Multi captureSWITCH_CAMERA = 'switch-camera'
- Notifies Face Auto Capture to use different cameraTOGGLE_MIRROR = 'toggle-mirror'
- Notifies Face Auto Capture to mirror video stream
import { dispatchControlEvent, FaceCustomEvent, ControlEventInstruction } from "@innovatrics/dot-face-auto-capture/events";
export const Dispatch = () => {
const continueDetection = () => {
dispatchControlEvent(FaceCustomEvent.CONTROL, ControlEventInstruction.CONTINUE_DETECTION)
}
const switchCamera = () => {
dispatchControlEvent(FaceCustomEvent.CONTROL, ControlEventInstruction.SWITCH_CAMERA)
}
const toggleMirror = () => {
dispatchControlEvent(FaceCustomEvent.CONTROL, ControlEventInstruction.TOGGLE_MIRROR)
}
return (
<div>
<button onClick={continueDetection}>Continue detection</button>
<button onClick={switchCamera}>Switch camera</button>
<button onClick={toggleMirror}>Mirror camera</button>
</div>
)
}
Without importing @innovatrics/dot-face-auto-capture/events
you can use values of FaceCustomEvent
and ControlEventInstruction
directly.
const continueDetection = () => {
document.dispatchEvent(
new CustomEvent("face-auto-capture:control", {
detail: { instruction: "continue-detection" },
}),
);
}
ComponentCustomEvent.REQUEST_CAPTURE
enum RequestCaptureInstruction
FIRST_FRAME = 'first-frame'
- Notifies Face Auto Capture to capture the very first image right after capturing this event. Validation and detection results are not evaluated in the processFIRST_VALID_FRAME = 'first-valid-frame'
- Notifies Face Auto Capture to capture the very first valid image right after capturing this event. Validation and detection results are evaluated in the process
import { dispatchCaptureEvent, ComponentCustomEvent, RequestCaptureInstruction } from "@innovatrics/dot-face-auto-capture/events";
export const Dispatch = () => {
const captureAnyImage = () => {
dispatchCaptureEvent(ComponentCustomEvent.REQUEST_CAPTURE, RequestCaptureInstruction.FIRST_FRAME)
}
const captureValidImage = () => {
dispatchCaptureEvent(ComponentCustomEvent.REQUEST_CAPTURE, RequestCaptureInstruction.FIRST_VALID_FRAME)
}
return (
<div>
<button onClick={captureAnyImage}>Capture any image</button>
<button onClick={captureValidImage}>Capture valid image</button>
</div>
)
}
Without importing @innovatrics/dot-face-auto-capture/events
you can use values of ComponentCustomEvent
and RequestCaptureInstruction
directly.
const captureAnyImage = () => {
document.dispatchEvent(
new CustomEvent("dot-custom-event:request-capture", {
detail: { instruction: "first-frame" },
}),
);
}
const captureValidImage = () => {
document.dispatchEvent(
new CustomEvent("dot-custom-event:request-capture", {
detail: { instruction: "first-valid-frame" },
}),
);
}
Example of using components together
import type { FaceCallback } from "@innovatrics/dot-face-auto-capture";
import {
dispatchControlEvent,
FaceCustomEvent,
ControlEventInstruction
} from "@innovatrics/dot-face-auto-capture/events";
import FaceCamera from "./FaceCamera";
import FaceUi from "./FaceUi";
const FaceAutoCapture = () => {
const handlePhotoTaken: FaceCallback = ({ image, data }, content) => {
console.log(image, data);
}
const handleError = (error: Error) => {
alert(error);
};
const handleContinueDetection = () => {
dispatchControlEvent(FaceCustomEvent.CONTROL, ControlEventInstruction.CONTINUE_DETECTION)
};
return (
<div>
<button onClick={handleContinueDetection}>Continue detection</button>
<div style={{ position: "relative" }}>
<FaceUi />
<FaceCamera
cameraFacing="user"
onPhotoTaken={handlePhotoTaken}
onError={handleError}
/>
</div>
</div>
);
};
Code Samples
See also DOT Web Samples showing the usage of DOT Web Auto Capture components in different front-end technologies like React, Angular…
Appendix
Changelog
6.2.0 - 2024-11-06
Added
captureMode
property to switch betweenAUTOCAPTURE
andWAIT_FOR_REQUEST
capture modedot-custom-event:request-capture
event to trigger capture inWAIT_FOR_REQUEST
modeiengine.lic
as another default license file name. Now the component will automatically load eitheriengine.lic
orlicense.lic
Changed
license.lic
default license file name flagged as deprecated
Fixed
Custom element prop types
6.1.8 - 2024-10-01
Fixed
Wrong image in
onPhotoTaken
callback
6.1.7 - 2024-10-01
Fixed
Error while switching between cameras on Android devices
6.1.6 - 2024-09-11
Fixed
Theme customization prop
6.1.5 - 2024-09-02
Changed
Improved security measures and enhanced protection against vulnerabilities
6.1.4 - 2024-08-21
Fixed
camera initialization on iOS, when multiple components are used on the same page
6.1.3 - 2024-08-21
Fixed
unnecessary camera permission request when photo was taken
6.1.2 - 2024-08-07
Added
ref
property to custom HTMLElement type
6.1.1 - 2024-08-01
Incremental version upgrade
6.1.0 - 2024-07-09
Added
font size, family, weight and style customization
Changed
Update
SAM
to version 1.39.3Improved detection of face size
6.0.0 - 2024-05-27
Added
License validation
dot_embedded_bg.wasm
- WASM binary file for license validationlicensePath
- path to license fileTiers - freemium/premium mode
Freemium overlay component Non-UI components
Changed
Update
SAM
to version 1.38.1
5.2.8 - 2024-04-10
Changed
Performance and documentation optimization
5.2.7 - 2024-03-01
Changed
Performance and documentation optimization
5.2.6 - 2024-02-20
Changed
Fix typo in
package.json
5.2.5 - 2024-02-20
Changed
Remove
type:module
frompackage.json
file in order to fix issue with Angular 16
5.2.4 - 2024-02-14
Fixed
Component not loading in certain conditions on Android in Firefox
5.2.3 - 2023-12-14
Added
styleTarget
property for specifying an alternate DOM node to inject styles. This is useful when rendering components in a shadow DOM. If not specified, the styles are injected into the<head>
element of the document.
5.2.2 - 2023-11-27
Removed
Use of
eval()
function in third-party library
5.2.1 - 2023-10-18
Changed
Update
SAM
to version 1.35.3Improved detection speed
Minimum camera resolution validation changed from validating both sides to validating just the shorter side. Now, minimal size of the shorter side is 720px.
5.2.0 - 2023-10-03
Changed
Update
SAM
to version 1.35.0Improved detection speed
Added
wasmDirectoryPath
- path to directory with Web assembly files.Support for multiple Web assembly files. The component will automatically load the
sam.wasm
orsam_simd.wasm
files from the specified folder, based on the device support of SIMD instructions. Web assembly files have to be placed inwasm
folder.
Removed
samWasmUrl
- property was removed. UsewasmDirectoryPath
property instead.
5.1.0 - 2023-09-28
Changed
isDeviceTiltWithinBoundsValidator
validator for detecting device pitch renamed toisDevicePitchWithinBoundsValidator
TILT_ANGLE_THRESHOLD
default threshold value renamed to`DEVICE_PITCH_ANGLE_THRESHOLD`tiltAngleThreshold
property for customizing allowed device tilt renamed todevicePitchAngleThreshold
5.0.4 - 2023-09-26
Update
content
parameter ofonPhotoTaken
callback
5.0.3 - 2023-09-21
Changed
Disable
SwitchCamera
button when component is incandidate_selection
phase
5.0.2 - 2023-09-20
Incremental version upgrade
5.0.1 - 2023-08-25
Fixed
Detector unable to initialize
5.0.0 - 2023-08-17
Changed
The
onPhotoTaken
callback change: Image and image data are returned as first parameter. Second parameter is a Record that represents a signed version of the image.Improvements in UI package, new
SwitchCamera
button icon.Unify thresholds to double-precision floating point format:
FACE_SHARPNESS_THRESHOLD
,FACE_BRIGHTNESS_LOW_THRESHOLD
,FACE_BRIGHTNESS_HIGH_THRESHOLD
.Changed default value of
MIN_FACE_SIZE_RATIO
to 0.16,MAX_FACE_SIZE_RATIO
to 0.20,FACE_SHARPNESS_THRESHOLD
to 0.3 andFACE_BRIGHTNESS_LOW_THRESHOLD
to 0.25.Long instruction text wraps to multiple lines. If text is longer than 34 characters.
Added
Backdrop for the default face placeholder.
backdropColor
property for changing the color of the default face placeholder backdropsessionIdForBinaryContent
property for generating byte array dataisDeviceTiltWithinBoundsValidator
validator for detecting device tilt (pitch)TILT_ANGLE_THRESHOLD
default threshold valuetiltAngleThreshold
property for customizing allowed device tiltdevice_tilted
instruction code and appropriate default message
Removed
cameraSettings
parameter fromonPhotoTaken
callbackimageType
property. Component returns result image injpeg
format.
Fixed
Calculating font size and camera button properties
4.1.6 - 2023-08-14
Security update
4.1.5 - 2023-07-03
Fixed
declaration files for Typescript version 5 in UI package
4.1.4 - 2023-06-21
Fixed
declaration files for Typescript version 5
4.1.3 - 2023-05-02
Incremental version upgrade
4.1.2 - 2023-03-31
Incremental version upgrade
4.1.1 - 2023-03-27
Incremental version upgrade
4.1.0 - 2023-03-24
Changed
Improvements in face detection
FACE_BRIGHTNESS_LOW_THRESHOLD
lowered from 400 to 300
Fixed
UI component occasionally started in
candidate_selection
phase after receivingcontinue-detection
event
Changed
detection crop ratio 4:3
Add
Component version in debug layer
4.0.4 - 2023-03-15
Fixed
Build package in
umd
formatFacePlaceholderIcon
changed fromenum
tounion
typeAppState
changed fromenum
toreadonly object
4.0.3 - 2023-03-07
Fixed
Detection not initialized on slow internet connection. Component remains in "waiting" state
"Candidate selection phase" at the beginning of detection when detecting multiple captures
applied
text-align: center
on instruction component on small screen
4.0.2 - 2023-02-23
Changed
changed instruction when face_not_present
4.0.1 - 2023-01-19
Fixed
export events from
@innovatrics/dot-face-auto-capture/events
4.0.0 - 2023-01-18
Removed
UI layer from camera component (buttons, placeholder, instruction, app state overlay and detection layer)
center face validator
FACE_CENTERING_NARROW_SIDE
thresholdFACE_CENTERING_WIDE_SIDE
threshold
Added
UI package with placeholder, instructions, buttons and detection layer
Custom events and events listeners for communication from app to component (switch-camera, toggle-mirror)
Custom events and events listeners for communication from components to app (camera-resolution-changed, instruction-changed, detected-document-changed, state-changed)
detection layer with detected face circle
showDetectionLayer
switch for show/hide camera buttons (switch camera, toggle mirror)showCameraButtons
switch for show/hide detection layerOutOfBounds
validatoroutOfBoundsValidationRectangle
outOfBoundsDetectionPoints
all rectangles and points into debug layer
SAM version
into debug layer
Changed
Rename
photoTakenCb
toonPhotoTaken
Order of instruction processing. Before validating the centering of the detected face, the size of the detected face is validated.
Component is now build as
umd
andes module
Camera buttons (switch camera, toggle mirror) are now hidden by default
3.5.2 - 2022-12-16
Fixed
Camera switch on Android devices with Firefox
3.5.1 - 2022-10-13
Fixed
Memoized props from first instance which holds reference to callback function from initialization on every capture
3.5.0 - 2022-10-10
Changed
Best candidate selection by sharpness
Dynamic candidate selection phase duration
Center face narrow side validator from 0.07 to 0.12
Fixed
Minimal camera resolution check
Selection of best image in candidate selection phase entering
Removed
Hotspots validator with
hotspotsMediumThreshold
andnumber hotspotsHighThreshold
3.4.3 - 2022-09-28
Fixed
Possible false candidate selection on first frame after entering candidate selection
3.4.2 - 2022-08-10
Fixed
Typescript declaration files export
3.3.1 - 2022-07-04
Fixed
Zero height of component when error occurs
Add
add
appStateInstructions
property to uiCustomisationadd option to change appState instructions text and visibility
Change
interface for changing
Loading
appState instruction text
3.3.0 - 2022-06-03
Added
Add support for capturing multiple face photos
Add custom event
face-auto-capture
withcontinue-detection
instruction to continue detection
Changed
When
photoTakenCb
is called, component switches into waiting stateParent of
<x-dot-face-auto-capture />
does not have to have a defined height
3.2.0 - 2022-05-23
Added
Add
Countly
analytics trackingAdd image parameters (brightness, sharpness, hotspot)
Session recording for face detection
Changed
onError
callback returnsAutoCaptureError
onError
callback is requiredShow error screen when error occurs
Fixed
Stucked component when error occurs
3.1.2 - 2022-04-04
Changed
Remove force manual capture on instruction click
3.1.1 - 2022-03-15
Changed
Change
optimalFaceSizeLimit
andoptimalFaceSizeParam
tominFaceSizeRatio
andmaxFaceSizeRatio
Change
faceCenterLimit
tofaceCenteringNarrowSide
andfaceCenteringWideSide
Set
minFaceSizeRatio
default value to0.35
andmaxFaceSizeRatio
to0.44
Set
faceCenteringNarrowSide
default value to0.07
andfaceCenteringWideSide
to0.21
3.1.0 - 2022-02-03
Fixed
Unify loading and instruction design
3.0.2 - 2022-01-28
Added
Add loading screen
Add
loading.text
property inuiCustomisation
for configuring text on loading screen
Changed
Show new instruction only if 600ms elapsed since last instruction change
3.0.1 - 2022-01-25
Added
file
sam.wasm
Fixed
safari version 15 on mac
Changed
Face detection accuracy improved.
Detection engine
Removed
blaze_models
packagemodelUrls
option from cameraOptions
2.3.1 - 2022-01-10
Fixed
Fix bug causing integration error
2.3.0 - 2022-01-05
Added
add
cameraSettings
intophotoTakenCb
callBack functionRedesign of the UI of Face Auto Capture component.
Changed
photoTakenCb
callBack function structure
2.2.2 - 2021-12-17
Incremental version upgrade
2.2.1 - 2021-12-09
Changed
Hide switch camera button if there is only 1 webcam available
2.2.0 - 2021-11-30
Added
thresholds.faceConfidence
- Detection confidence threshold with default value0.12
modelUrls
- Object with path to the models needed for detection
Changed
integrated new neural network for face detection
dynamic import of TensorFlow.js libraries
2.1.0 - 2021-11-18
First released version