mirror of
https://github.com/nimiq/qr-scanner.git
synced 2026-07-28 04:06:51 +00:00
11 lines
3.8 KiB
JavaScript
11 lines
3.8 KiB
JavaScript
'use strict';class QrScanner{constructor(a,b,c=QrScanner.DEFAULT_CANVAS_SIZE){this.$video=a;this.$canvas=document.createElement("canvas");this._onDecode=b;this._active=false;this.$canvas.width=c;this.$canvas.height=c;this._sourceRect={x:0,y:0,width:c,height:c};this.$video.addEventListener("canplay",()=>this._updateSourceRect());this.$video.addEventListener("play",()=>{this._updateSourceRect();this._scanFrame()},false);this._qrWorker=new Worker("/qr-scanner/qr-scanner-worker.min.js")}_updateSourceRect(){const a=
|
|
Math.round(2/3*Math.min(this.$video.videoWidth,this.$video.videoHeight));this._sourceRect.width=this._sourceRect.height=a;this._sourceRect.x=(this.$video.videoWidth-a)/2;this._sourceRect.y=(this.$video.videoHeight-a)/2}_scanFrame(){if(this.$video.paused||this.$video.ended)return false;requestAnimationFrame(()=>{QrScanner.scanImage(this.$video,this._sourceRect,this._qrWorker,this.$canvas,true).then(this._onDecode,(a)=>{a!=="QR code not found."&&console.error(a)}).then(()=>this._scanFrame())})}set active(a){if(a&&
|
|
!this._active){this._cameraOn();this._active=true}else{this._cameraOff();this._active=false}}_cameraOn(a){clearTimeout(this._offTimeout);const b=[{facingMode:"environment",width:{min:1024}},{facingMode:"environment",width:{min:768}},{facingMode:"environment"}];a=a||b;navigator.mediaDevices.getUserMedia({video:a.shift()}).then((a)=>this.$video.srcObject=a).catch(()=>{if(a.length>0)this._cameraOn(a);else throw Error("Couldn't start camera");})}_cameraOff(){this.$video.pause();this._offTimeout=setTimeout(()=>
|
|
this.$video.srcObject.getTracks()[0].stop(),3E3)}setGrayscaleWeights(a,b,c){this._qrWorker.postMessage({type:"grayscaleWeights",data:{red:a,green:b,blue:c}})}static scanImage(a,b=null,c=null,d=null,e=false,g=false){const f=new Promise((f,g)=>{c=c||new Worker("/qr-scanner/qr-scanner-worker.min.js");let l,k,h;k=(a)=>{if(a.data.type==="qrResult"){c.removeEventListener("message",k);c.removeEventListener("error",h);clearTimeout(l);a.data.data!==null?f(a.data.data):g("QR code not found.")}};h=()=>{c.removeEventListener("message",
|
|
k);c.removeEventListener("error",h);clearTimeout(l);g("Worker error.")};c.addEventListener("message",k);c.addEventListener("error",h);l=setTimeout(h,3E3);QrScanner._loadImage(a).then((a)=>{a=QrScanner._getImageData(a,b,d,e);c.postMessage({type:"decode",data:a},[a.data.buffer])}).catch(g)});return b&&g?f.catch(()=>QrScanner.scanImage(a,null,c,d,e)):f}static _getImageData(a,b=null,c=null,d=false){c=c||document.createElement("canvas");const e=b&&b.x?b.x:0,g=b&&b.y?b.y:0,f=b&&b.width?b.width:a.width||
|
|
a.videoWidth;b=b&&b.height?b.height:a.height||a.videoHeight;if(!d&&(c.width!==f||c.height!==b)){c.width=f;c.height=b}d=c.getContext("2d",{alpha:false});d.imageSmoothingEnabled=false;d.drawImage(a,e,g,f,b,0,0,c.width,c.height);return d.getImageData(0,0,c.width,c.height)}static _loadImage(a){if(a instanceof HTMLCanvasElement||a instanceof HTMLVideoElement||window.ImageBitmap&&a instanceof window.ImageBitmap||window.OffscreenCanvas&&a instanceof window.OffscreenCanvas)return Promise.resolve(a);if(a instanceof
|
|
Image)return QrScanner._awaitImageLoad(a).then(()=>a);if(a instanceof File||a instanceof URL||typeof a==="string"){const b=new Image;b.src=a instanceof File?URL.createObjectURL(a):a;return QrScanner._awaitImageLoad(b).then(()=>{a instanceof File&&URL.revokeObjectURL(b.src);return b})}return Promise.reject("Unsupported image type.")}static _awaitImageLoad(a){return new Promise((b,c)=>{if(a.complete&&a.naturalWidth!==0)b();else{let d,e;d=()=>{a.removeEventListener("load",d);a.removeEventListener("error",
|
|
e);b()};e=()=>{a.removeEventListener("load",d);a.removeEventListener("error",e);c("Image load error")};a.addEventListener("load",d);a.addEventListener("error",e)}})}}QrScanner.DEFAULT_CANVAS_SIZE=400;
|
|
|
|
//# sourceMappingURL=qr-scanner.min.js.map
|