scandit-sdk
Version:
Scandit Barcode Scanner SDK for the Web
733 lines (638 loc) • 28.7 kB
text/typescript
import { ResizeObserver as ResizeObserverPolyfill } from "@juggle/resize-observer";
// tslint:disable-next-line: variable-name
const ResizeObserver: typeof ResizeObserverPolyfill =
// tslint:disable-next-line: no-any
"ResizeObserver" in window ? /* istanbul ignore next */ (<any>window).ResizeObserver : ResizeObserverPolyfill;
import {
cameraImage,
laserActiveImage,
laserPausedImage,
scanditLogoImage,
switchCameraImage,
toggleTorchImage
} from "./assets/base64assets";
import { BarcodePicker } from "./barcodePicker";
import { BrowserHelper } from "./browserHelper";
import { Camera } from "./camera";
import { CameraAccess } from "./cameraAccess";
import { CameraManager } from "./cameraManager";
import { ImageSettings } from "./imageSettings";
import { Scanner } from "./scanner";
import { ScanSettings } from "./scanSettings";
import { SearchArea } from "./searchArea";
/**
* @hidden
*/
export class BarcodePickerGui {
public static readonly grandParentElementClassName: string = "scandit scandit-container";
public static readonly parentElementClassName: string = "scandit scandit-barcode-picker";
public static readonly hiddenClassName: string = "scandit-hidden";
public static readonly hiddenOpacityClassName: string = "scandit-hidden-opacity";
public static readonly videoElementClassName: string = "scandit-video";
public static readonly scanditLogoImageElementClassName: string = "scandit-logo";
public static readonly laserContainerElementClassName: string = "scandit-laser";
public static readonly viewfinderElementClassName: string = "scandit-viewfinder";
public static readonly cameraSwitcherElementClassName: string = "scandit-camera-switcher";
public static readonly torchTogglerElementClassName: string = "scandit-torch-toggle";
public static readonly cameraUploadElementClassName: string = "scandit-camera-upload";
public static readonly flashColorClassName: string = "scandit-flash-color";
public static readonly flashWhiteClassName: string = "scandit-flash-white";
public static readonly flashWhiteInsetClassName: string = "scandit-flash-white-inset";
public static readonly opacityPulseClassName: string = "scandit-opacity-pulse";
public static readonly mirroredClassName: string = "mirrored";
public static readonly pausedClassName: string = "paused";
public readonly videoElement: HTMLVideoElement;
public readonly cameraSwitcherElement: HTMLImageElement;
public readonly torchTogglerElement: HTMLImageElement;
private readonly scanner: Scanner;
private readonly singleImageMode: boolean;
private readonly grandParentElement: HTMLDivElement;
private readonly parentElement: HTMLDivElement;
private readonly laserContainerElement: HTMLDivElement;
private readonly laserActiveImageElement: HTMLImageElement;
private readonly laserPausedImageElement: HTMLImageElement;
private readonly viewfinderElement: HTMLDivElement;
private readonly cameraUploadElement: HTMLDivElement;
private readonly cameraUploadInputElement: HTMLInputElement;
private readonly cameraUploadLabelElement: HTMLLabelElement;
private readonly cameraUploadProgressElement: HTMLDivElement;
private readonly videoImageCanvasContext: CanvasRenderingContext2D;
private readonly visibilityListener: EventListenerOrEventListenerObject;
private readonly videoResizeListener: EventListenerOrEventListenerObject;
private readonly newScanSettingsListener: (scanSettings: ScanSettings) => void;
private readonly licenseFeaturesReadyListener: (licenseFeatures: object) => void;
private readonly resizeObserver: ResizeObserverPolyfill;
private readonly cameraUploadCallback: () => Promise<void>;
private readonly mirrorImageOverrides: Map<string, boolean>;
private cameraManager?: CameraManager;
private originElement: HTMLElement;
private scanningPaused: boolean;
private visible: boolean;
private guiStyle: BarcodePicker.GuiStyle;
private videoFit: BarcodePicker.ObjectFit;
private customLaserArea?: SearchArea;
private customViewfinderArea?: SearchArea;
public constructor(options: {
scanner: Scanner;
originElement: HTMLElement;
singleImageMode: boolean;
scanningPaused: boolean;
visible: boolean;
guiStyle: BarcodePicker.GuiStyle;
videoFit: BarcodePicker.ObjectFit;
hideLogo: boolean;
laserArea?: SearchArea;
viewfinderArea?: SearchArea;
cameraUploadCallback(): Promise<void>;
}) {
this.scanner = options.scanner;
this.originElement = options.originElement;
this.singleImageMode = options.singleImageMode;
this.scanningPaused = options.scanningPaused;
this.cameraUploadCallback = options.cameraUploadCallback;
this.mirrorImageOverrides = new Map<string, boolean>();
this.grandParentElement = document.createElement("div");
this.grandParentElement.className = BarcodePickerGui.grandParentElementClassName;
this.originElement.appendChild(this.grandParentElement);
this.parentElement = document.createElement("div");
this.parentElement.className = BarcodePickerGui.parentElementClassName;
this.grandParentElement.appendChild(this.parentElement);
this.videoImageCanvasContext = <CanvasRenderingContext2D>document.createElement("canvas").getContext("2d");
this.videoElement = document.createElement("video");
this.cameraSwitcherElement = document.createElement("img");
this.torchTogglerElement = document.createElement("img");
this.laserContainerElement = document.createElement("div");
this.laserActiveImageElement = document.createElement("img");
this.laserPausedImageElement = document.createElement("img");
this.viewfinderElement = document.createElement("div");
if (options.singleImageMode) {
this.cameraUploadElement = document.createElement("div");
this.cameraUploadInputElement = document.createElement("input");
this.cameraUploadLabelElement = document.createElement("label");
this.cameraUploadProgressElement = document.createElement("div");
this.setupCameraUploadGuiAssets();
this.guiStyle = BarcodePicker.GuiStyle.NONE;
} else {
this.setupVideoElement();
this.setupCameraSwitcher();
this.setupTorchToggler();
this.setupFullGuiAssets();
this.setGuiStyle(options.guiStyle);
this.setVideoFit(options.videoFit);
this.setLaserArea(options.laserArea);
this.setViewfinderArea(options.viewfinderArea);
this.visibilityListener = this.checkAndRecoverPlayback.bind(this);
document.addEventListener("visibilitychange", this.visibilityListener);
this.newScanSettingsListener = this.handleNewScanSettings.bind(this);
this.scanner.onNewScanSettings(this.newScanSettingsListener);
this.handleNewScanSettings();
this.videoResizeListener = this.handleVideoResize.bind(this);
this.videoElement.addEventListener("resize", this.videoResizeListener);
}
if (options.hideLogo) {
this.licenseFeaturesReadyListener = this.showScanditLogo.bind(this, options.hideLogo);
this.scanner.onLicenseFeaturesReady(this.licenseFeaturesReadyListener);
} else {
this.showScanditLogo(false);
}
this.resize();
this.resizeObserver = new ResizeObserver(() => {
this.resize();
});
this.resizeObserver.observe(this.originElement);
this.setVisible(options.visible);
}
public destroy(): void {
if (this.visibilityListener != null) {
document.removeEventListener("visibilitychange", this.visibilityListener);
}
if (this.newScanSettingsListener != null) {
this.scanner.removeListener("newScanSettings", this.newScanSettingsListener);
}
if (this.videoResizeListener != null) {
document.removeEventListener("resize", this.videoResizeListener);
}
if (this.licenseFeaturesReadyListener != null) {
this.scanner.removeListener("licenseFeaturesReady", this.licenseFeaturesReadyListener);
}
this.resizeObserver.disconnect();
this.grandParentElement.remove();
this.originElement.classList.remove(BarcodePickerGui.hiddenClassName);
}
public setCameraManager(cameraManager: CameraManager): void {
this.cameraManager = cameraManager;
}
public pauseScanning(): void {
this.scanningPaused = true;
this.laserActiveImageElement.classList.add(BarcodePickerGui.hiddenOpacityClassName);
this.laserPausedImageElement.classList.remove(BarcodePickerGui.hiddenOpacityClassName);
this.viewfinderElement.classList.add(BarcodePickerGui.pausedClassName);
}
public resumeScanning(): void {
this.scanningPaused = false;
this.laserPausedImageElement.classList.add(BarcodePickerGui.hiddenOpacityClassName);
this.laserActiveImageElement.classList.remove(BarcodePickerGui.hiddenOpacityClassName);
this.viewfinderElement.classList.remove(BarcodePickerGui.pausedClassName);
}
public isVisible(): boolean {
return this.visible;
}
public setVisible(visible: boolean): void {
const browserName: string | undefined = BrowserHelper.userAgentInfo.getBrowser().name;
if (browserName != null && browserName.includes("Safari") && this.visible != null && !this.visible && visible) {
// Safari behaves very weirdly when displaying the video element again after being hidden:
// it undetectably reuses video frames "buffered" from the video just before it was hidden.
// We do this to avoid reusing old data
this.videoElement.pause();
this.videoElement.currentTime = 0;
this.videoElement.load();
this.playVideo();
}
this.visible = visible;
if (visible) {
this.originElement.classList.remove(BarcodePickerGui.hiddenClassName);
if (this.guiStyle === BarcodePicker.GuiStyle.LASER) {
this.laserActiveImageElement.classList.remove(BarcodePickerGui.flashColorClassName);
} else if (this.guiStyle === BarcodePicker.GuiStyle.VIEWFINDER) {
this.viewfinderElement.classList.remove(BarcodePickerGui.flashWhiteClassName);
}
} else {
this.originElement.classList.add(BarcodePickerGui.hiddenClassName);
}
}
public isMirrorImageEnabled(): boolean {
if (
this.cameraManager != null &&
this.cameraManager.selectedCamera != null &&
this.cameraManager.activeCamera != null
) {
const mirrorImageOverride: boolean | undefined = this.mirrorImageOverrides.get(
this.cameraManager.activeCamera.deviceId + this.cameraManager.activeCamera.label
);
if (mirrorImageOverride != null) {
return mirrorImageOverride;
} else {
return this.cameraManager.activeCamera.cameraType === Camera.Type.FRONT;
}
} else {
return false;
}
}
public setMirrorImageEnabled(enabled: boolean, override: boolean): void {
if (this.cameraManager != null && this.cameraManager.selectedCamera != null) {
if (enabled) {
this.videoElement.classList.add(BarcodePickerGui.mirroredClassName);
} else {
this.videoElement.classList.remove(BarcodePickerGui.mirroredClassName);
}
if (override) {
this.mirrorImageOverrides.set(
this.cameraManager.selectedCamera.deviceId + this.cameraManager.selectedCamera.label,
enabled
);
}
}
}
public setGuiStyle(guiStyle: BarcodePicker.GuiStyle): void {
if (this.singleImageMode) {
return;
}
switch (guiStyle) {
case BarcodePicker.GuiStyle.LASER:
this.guiStyle = guiStyle;
this.laserContainerElement.classList.remove(BarcodePickerGui.hiddenClassName);
this.viewfinderElement.classList.add(BarcodePickerGui.hiddenClassName);
break;
case BarcodePicker.GuiStyle.VIEWFINDER:
this.guiStyle = guiStyle;
this.laserContainerElement.classList.add(BarcodePickerGui.hiddenClassName);
this.viewfinderElement.classList.remove(BarcodePickerGui.hiddenClassName);
break;
case BarcodePicker.GuiStyle.NONE:
default:
this.guiStyle = BarcodePicker.GuiStyle.NONE;
this.laserContainerElement.classList.add(BarcodePickerGui.hiddenClassName);
this.viewfinderElement.classList.add(BarcodePickerGui.hiddenClassName);
break;
}
}
public setLaserArea(area?: SearchArea): void {
this.customLaserArea = area;
if (area == null) {
area = this.scanner.getScanSettings().getSearchArea();
}
const borderPercentage: number = 0.025;
const usablePercentage: number = 1 - borderPercentage * 2;
this.laserContainerElement.style.left = `${(borderPercentage + area.x * usablePercentage) * 100}%`;
this.laserContainerElement.style.width = `${area.width * usablePercentage * 100}%`;
this.laserContainerElement.style.top = `${(borderPercentage + area.y * usablePercentage) * 100}%`;
this.laserContainerElement.style.height = `${area.height * usablePercentage * 100}%`;
}
public setViewfinderArea(area?: SearchArea): void {
this.customViewfinderArea = area;
if (area == null) {
area = this.scanner.getScanSettings().getSearchArea();
}
const borderPercentage: number = 0.025;
const usablePercentage: number = 1 - borderPercentage * 2;
this.viewfinderElement.style.left = `${(borderPercentage + area.x * usablePercentage) * 100}%`;
this.viewfinderElement.style.width = `${area.width * usablePercentage * 100}%`;
this.viewfinderElement.style.top = `${(borderPercentage + area.y * usablePercentage) * 100}%`;
this.viewfinderElement.style.height = `${area.height * usablePercentage * 100}%`;
}
public setVideoFit(objectFit: BarcodePicker.ObjectFit): void {
if (this.singleImageMode) {
return;
}
this.videoFit = objectFit;
if (objectFit === BarcodePicker.ObjectFit.COVER) {
this.videoElement.style.objectFit = "cover";
this.videoElement.dataset.objectFit = "cover"; // used by "objectFitPolyfill" library
} else {
this.videoElement.style.objectFit = "contain";
this.videoElement.dataset.objectFit = "contain"; // used by "objectFitPolyfill" library
this.scanner.applyScanSettings(
this.scanner.getScanSettings().setBaseSearchArea({ x: 0, y: 0, width: 1.0, height: 1.0 })
);
}
this.resize();
}
public reassignOriginElement(originElement: HTMLElement): void {
if (!this.visible) {
this.originElement.classList.remove(BarcodePickerGui.hiddenClassName);
originElement.classList.add(BarcodePickerGui.hiddenClassName);
}
originElement.appendChild(this.grandParentElement);
this.checkAndRecoverPlayback();
this.resize();
this.resizeObserver.disconnect();
this.resizeObserver.observe(originElement);
this.originElement = originElement;
}
public flashGUI(): void {
if (this.guiStyle === BarcodePicker.GuiStyle.LASER) {
this.flashLaser();
} else if (this.guiStyle === BarcodePicker.GuiStyle.VIEWFINDER) {
this.flashViewfinder();
}
}
public getVideoImageData(): Uint8ClampedArray | undefined {
if (!this.singleImageMode) {
// This could happen in very weird situations and should be temporary
if (
this.videoElement.readyState !== 4 ||
this.videoImageCanvasContext.canvas.width <= 2 ||
this.videoImageCanvasContext.canvas.height <= 2
) {
return undefined;
}
this.videoImageCanvasContext.drawImage(this.videoElement, 0, 0);
}
return this.videoImageCanvasContext.getImageData(
0,
0,
this.videoImageCanvasContext.canvas.width,
this.videoImageCanvasContext.canvas.height
).data;
}
public getVideoCurrentTime(): number {
return this.videoElement.currentTime;
}
public setCameraSwitcherVisible(visible: boolean): void {
if (visible) {
this.cameraSwitcherElement.classList.remove(BarcodePickerGui.hiddenClassName);
} else {
this.cameraSwitcherElement.classList.add(BarcodePickerGui.hiddenClassName);
}
}
public setTorchTogglerVisible(visible: boolean): void {
if (visible) {
this.torchTogglerElement.classList.remove(BarcodePickerGui.hiddenClassName);
} else {
this.torchTogglerElement.classList.add(BarcodePickerGui.hiddenClassName);
}
}
public playVideo(): void {
const playPromise: Promise<void> = this.videoElement.play();
if (playPromise != null) {
playPromise.catch(
/* istanbul ignore next */ () => {
// Can sometimes cause an incorrect rejection (all is good, ignore).
}
);
}
}
private setCameraUploadGuiAvailable(available: boolean): void {
if (available) {
this.cameraUploadProgressElement.classList.add(BarcodePickerGui.flashWhiteInsetClassName);
this.cameraUploadElement.classList.remove(BarcodePickerGui.opacityPulseClassName);
} else {
this.cameraUploadProgressElement.classList.remove(BarcodePickerGui.flashWhiteInsetClassName);
this.cameraUploadElement.classList.add(BarcodePickerGui.opacityPulseClassName);
}
}
private setupVideoElement(): void {
this.videoElement.setAttribute("autoplay", "autoplay");
this.videoElement.setAttribute("playsinline", "true");
this.videoElement.setAttribute("muted", "muted");
this.videoElement.className = BarcodePickerGui.videoElementClassName;
this.parentElement.appendChild(this.videoElement);
}
private setupCameraUploadGuiAssets(): void {
this.cameraUploadElement.className = BarcodePickerGui.cameraUploadElementClassName;
this.parentElement.appendChild(this.cameraUploadElement);
this.cameraUploadInputElement.type = "file";
this.cameraUploadInputElement.accept = "image/*";
this.cameraUploadInputElement.setAttribute("capture", "environment");
this.cameraUploadInputElement.addEventListener("change", this.cameraUploadFile.bind(this));
this.cameraUploadInputElement.addEventListener(
"click",
/* istanbul ignore next */ event => {
if (this.scanningPaused || this.scanner.isBusyProcessing()) {
event.preventDefault();
}
}
);
this.cameraUploadLabelElement.appendChild(this.cameraUploadInputElement);
this.cameraUploadElement.appendChild(this.cameraUploadLabelElement);
const cameraUploadImageElement: HTMLImageElement = document.createElement("img");
cameraUploadImageElement.src = cameraImage;
this.cameraUploadLabelElement.appendChild(cameraUploadImageElement);
const cameraUploadTextElement: HTMLDivElement = document.createElement("div");
cameraUploadTextElement.innerText = "Scan from Camera";
this.cameraUploadLabelElement.appendChild(cameraUploadTextElement);
this.cameraUploadProgressElement.classList.add("radial-progress");
this.cameraUploadElement.appendChild(this.cameraUploadProgressElement);
}
private setupFullGuiAssets(): void {
this.laserActiveImageElement.src = laserActiveImage;
this.laserContainerElement.appendChild(this.laserActiveImageElement);
this.laserPausedImageElement.src = laserPausedImage;
this.laserContainerElement.appendChild(this.laserPausedImageElement);
this.laserContainerElement.className = BarcodePickerGui.laserContainerElementClassName;
this.parentElement.appendChild(this.laserContainerElement);
this.viewfinderElement.className = BarcodePickerGui.viewfinderElementClassName;
this.parentElement.appendChild(this.viewfinderElement);
// Show inactive GUI, as for now the scanner isn't ready yet
this.laserActiveImageElement.classList.add(BarcodePickerGui.hiddenOpacityClassName);
this.laserPausedImageElement.classList.remove(BarcodePickerGui.hiddenOpacityClassName);
this.viewfinderElement.classList.add(BarcodePickerGui.pausedClassName);
}
private flashLaser(): void {
this.laserActiveImageElement.classList.remove(BarcodePickerGui.flashColorClassName);
// tslint:disable-next-line:no-unused-expression
this.laserActiveImageElement.offsetHeight; // NOSONAR // Trigger reflow to restart animation
this.laserActiveImageElement.classList.add(BarcodePickerGui.flashColorClassName);
}
private flashViewfinder(): void {
this.viewfinderElement.classList.remove(BarcodePickerGui.flashWhiteClassName);
// tslint:disable-next-line:no-unused-expression
this.viewfinderElement.offsetHeight; // NOSONAR // Trigger reflow to restart animation
this.viewfinderElement.classList.add(BarcodePickerGui.flashWhiteClassName);
}
private resize(): void {
if (this.singleImageMode) {
this.resizeCameraUpload();
} else {
this.resizeVideo();
}
}
private resizeCameraUpload(): void {
const width: number = this.originElement.clientWidth;
const height: number = this.originElement.clientHeight;
this.cameraUploadLabelElement.style.transform = `scale(${Math.min(1, width / 500, height / 300)})`;
this.cameraUploadProgressElement.style.transform = `scale(${Math.min(1, width / 500, height / 300)})`;
}
private resizeVideo(): void {
if (this.videoElement.videoWidth <= 2 || this.videoElement.videoHeight <= 2) {
return;
}
this.parentElement.style.maxWidth = null;
this.parentElement.style.maxHeight = null;
let width: number = this.originElement.clientWidth;
let height: number = this.originElement.clientHeight;
const videoRatio: number = this.videoElement.videoWidth / this.videoElement.videoHeight;
if (this.videoFit === BarcodePicker.ObjectFit.COVER) {
let widthPercentage: number = 1;
let heightPercentage: number = 1;
if (videoRatio < width / height) {
heightPercentage = Math.min(1, height / (width / videoRatio));
} else {
widthPercentage = Math.min(1, width / (height * videoRatio));
}
this.scanner.applyScanSettings(
this.scanner.getScanSettings().setBaseSearchArea({
x: (1 - widthPercentage) / 2,
y: (1 - heightPercentage) / 2,
width: widthPercentage,
height: heightPercentage
})
);
return;
}
if (videoRatio > width / height) {
height = width / videoRatio;
} else {
width = height * videoRatio;
}
this.parentElement.style.maxWidth = `${Math.ceil(width)}px`;
this.parentElement.style.maxHeight = `${Math.ceil(height)}px`;
window.objectFitPolyfill(this.videoElement);
}
private checkAndRecoverPlayback(): void {
if (
this.cameraManager != null &&
this.cameraManager.activeCamera != null &&
this.videoElement != null &&
this.videoElement.srcObject != null
) {
if (!(<MediaStream>this.videoElement.srcObject).active) {
this.cameraManager.reinitializeCamera();
} else {
this.playVideo();
}
}
}
private updateCameraUploadProgress(progressPercentageValue: string): void {
this.cameraUploadProgressElement.setAttribute("data-progress", progressPercentageValue);
}
private async cameraUploadImageLoad(image: HTMLImageElement): Promise<void> {
this.updateCameraUploadProgress("100");
let resizedImageWidth: number;
let resizedImageHeight: number;
const resizedImageSizeLimit: number = 1440;
if (image.naturalWidth <= resizedImageSizeLimit && image.naturalHeight <= resizedImageSizeLimit) {
resizedImageWidth = image.naturalWidth;
resizedImageHeight = image.naturalHeight;
} else {
if (image.naturalWidth > image.naturalHeight) {
resizedImageWidth = resizedImageSizeLimit;
resizedImageHeight = Math.round((image.naturalHeight / image.naturalWidth) * resizedImageSizeLimit);
} else {
resizedImageWidth = Math.round((image.naturalWidth / image.naturalHeight) * resizedImageSizeLimit);
resizedImageHeight = resizedImageSizeLimit;
}
}
await this.cameraUploadFileProcess(image, resizedImageWidth, resizedImageHeight);
}
private async cameraUploadFileProcess(image: HTMLImageElement, width: number, height: number): Promise<void> {
this.videoImageCanvasContext.canvas.width = width;
this.videoImageCanvasContext.canvas.height = height;
this.videoImageCanvasContext.drawImage(image, 0, 0, width, height);
this.scanner.applyImageSettings({
width,
height,
format: ImageSettings.Format.RGBA_8U
});
this.setCameraUploadGuiAvailable(false);
await this.cameraUploadCallback();
this.setCameraUploadGuiAvailable(true);
}
private cameraUploadFile(): void {
const files: FileList | null = this.cameraUploadInputElement.files;
if (files != null && files.length !== 0) {
const image: HTMLImageElement = new Image();
const fileReader: FileReader = new FileReader();
fileReader.onload = () => {
this.cameraUploadInputElement.value = "";
if (fileReader.result != null) {
image.onload = this.cameraUploadImageLoad.bind(this, image);
image.onprogress = event2 => {
if (event2.lengthComputable) {
const progress: number = Math.round((event2.loaded / event2.total) * 20) * 5;
if (progress <= 100) {
this.updateCameraUploadProgress(progress.toString());
}
}
};
image.src = <string>fileReader.result;
}
};
this.updateCameraUploadProgress("0");
fileReader.readAsDataURL(files[0]);
}
}
private setupCameraSwitcher(): void {
this.cameraSwitcherElement.src = switchCameraImage;
this.cameraSwitcherElement.className = BarcodePickerGui.cameraSwitcherElementClassName;
this.cameraSwitcherElement.classList.add(BarcodePickerGui.hiddenClassName);
this.parentElement.appendChild(this.cameraSwitcherElement);
["touchstart", "mousedown"].forEach(eventName => {
this.cameraSwitcherElement.addEventListener(eventName, async event => {
if (this.cameraManager != null) {
const cameraManager: CameraManager = this.cameraManager;
event.preventDefault();
try {
const cameras: Camera[] = await CameraAccess.getCameras();
const newCameraIndex: number =
(cameras.findIndex(camera => {
return (
camera.deviceId ===
(cameraManager.activeCamera == null ? camera.deviceId : cameraManager.activeCamera.deviceId)
);
}) +
1) %
cameras.length;
cameraManager
.initializeCameraWithSettings(cameras[newCameraIndex], cameraManager.activeCameraSettings)
.catch(console.error);
} catch (error) {
console.error(error);
}
}
});
});
}
private setupTorchToggler(): void {
this.torchTogglerElement.src = toggleTorchImage;
this.torchTogglerElement.className = BarcodePickerGui.torchTogglerElementClassName;
this.torchTogglerElement.classList.add(BarcodePickerGui.hiddenClassName);
this.parentElement.appendChild(this.torchTogglerElement);
["touchstart", "mousedown"].forEach(eventName => {
this.torchTogglerElement.addEventListener(eventName, event => {
if (this.cameraManager != null) {
event.preventDefault();
this.cameraManager.toggleTorch();
}
});
});
}
private showScanditLogo(hideLogo: boolean, licenseFeatures?: { hiddenScanditLogoAllowed?: boolean }): void {
if (
hideLogo &&
licenseFeatures != null &&
licenseFeatures.hiddenScanditLogoAllowed != null &&
licenseFeatures.hiddenScanditLogoAllowed
) {
return;
}
const scanditLogoImageElement: HTMLImageElement = document.createElement("img");
scanditLogoImageElement.src = scanditLogoImage;
scanditLogoImageElement.className = BarcodePickerGui.scanditLogoImageElementClassName;
this.parentElement.appendChild(scanditLogoImageElement);
}
private handleNewScanSettings(): void {
if (this.customLaserArea == null) {
this.setLaserArea();
}
if (this.customViewfinderArea == null) {
this.setViewfinderArea();
}
}
private handleVideoResize(): void {
if (
this.videoImageCanvasContext.canvas.width === this.videoElement.videoWidth &&
this.videoImageCanvasContext.canvas.height === this.videoElement.videoHeight
) {
return;
}
this.videoImageCanvasContext.canvas.width = this.videoElement.videoWidth;
this.videoImageCanvasContext.canvas.height = this.videoElement.videoHeight;
this.scanner.applyImageSettings({
width: this.videoElement.videoWidth,
height: this.videoElement.videoHeight,
format: ImageSettings.Format.RGBA_8U
});
this.resize();
}
}