SDK开发完成
This commit is contained in:
File diff suppressed because one or more lines are too long
29
demo.html
29
demo.html
@@ -180,7 +180,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<main class="page">
|
<main class="page">
|
||||||
<section class="hero">
|
<section class="hero">
|
||||||
<h1>IScan 扫码 SDK Demo</h1>
|
<h1>IScan 通用扫码 SDK</h1>
|
||||||
<p>统一接入桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</p>
|
<p>统一接入桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -188,11 +188,9 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2>功能说明</h2>
|
<h2>功能说明</h2>
|
||||||
<ul class="feature-list">
|
<ul class="feature-list">
|
||||||
<li>桥接环境优先调用 App 原生扫码。</li>
|
<li>支持桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</li>
|
||||||
<li>微信环境支持初始化 JSSDK 并调用 scanQRCode。</li>
|
<li>浏览器环境使用 ZXing的wasm库识别二维码和条形码。</li>
|
||||||
<li>浏览器环境使用 BarcodeDetector 识别二维码和条形码。</li>
|
<li>扫码结果又监听规则统一回调。</li>
|
||||||
<li>摄像头不可用时可选择图片识别。</li>
|
|
||||||
<li>支持扫码枪快速输入,并与扫码监听规则统一回调。</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -209,20 +207,21 @@
|
|||||||
<p>点击开始后,会按桥接、微信、Web 摄像头、图片识别的顺序选择可用扫码方式。</p>
|
<p>点击开始后,会按桥接、微信、Web 摄像头、图片识别的顺序选择可用扫码方式。</p>
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<button onclick="startScan()" class="btn">开始扫码</button>
|
<button onclick="startScan()" class="btn">开始扫码</button>
|
||||||
|
<button onclick="scanVideo()" class="btn secondary">开启视频扫码</button>
|
||||||
<button onclick="scanImage()" class="btn secondary">选择图片识别</button>
|
<button onclick="scanImage()" class="btn secondary">选择图片识别</button>
|
||||||
<button onclick="stopScan()" class="btn secondary">停止扫码</button>
|
<button onclick="stopScan()" class="btn secondary">停止扫码</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="grid">
|
<section class="card">
|
||||||
<div class="card">
|
|
||||||
<h2>扫码结果</h2>
|
<h2>扫码结果</h2>
|
||||||
<pre id="result" class="panel result"></pre>
|
<pre id="result" class="panel result"></pre>
|
||||||
</div>
|
</section>
|
||||||
<div class="card">
|
|
||||||
|
<section class="card">
|
||||||
<h2>错误信息</h2>
|
<h2>错误信息</h2>
|
||||||
<pre id="error" class="panel error"></pre>
|
<pre id="error" class="panel error"></pre>
|
||||||
</div>
|
<p style="color: #919191">错误信息可能来源于扫码结果、扫码过程、扫码初始化等。</p>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="card code">
|
<section class="card code">
|
||||||
@@ -234,10 +233,11 @@
|
|||||||
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
// 监听扫码状态
|
||||||
IScan.setStatusListener(function () {
|
IScan.setStatusListener(function () {
|
||||||
console.log("status:", IScan.getStatus());
|
console.log("status:", IScan.getStatus());
|
||||||
});
|
});
|
||||||
|
// 监听扫码结果
|
||||||
IScan.onScanListener(function (res) {
|
IScan.onScanListener(function (res) {
|
||||||
console.log("scan result:", res);
|
console.log("scan result:", res);
|
||||||
}, "scan", null, 100);
|
}, "scan", null, 100);
|
||||||
@@ -348,6 +348,11 @@ IScan.stopScan();</pre>
|
|||||||
IScan.scanImage();
|
IScan.scanImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scanVideo() {
|
||||||
|
hide();
|
||||||
|
IScan.scanVideo();
|
||||||
|
}
|
||||||
|
|
||||||
ready();
|
ready();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
20
dist/index.d.ts
vendored
20
dist/index.d.ts
vendored
@@ -3,17 +3,25 @@
|
|||||||
*/
|
*/
|
||||||
interface ScanConfigOptions {
|
interface ScanConfigOptions {
|
||||||
/**
|
/**
|
||||||
* 网页扫码canvas样式
|
* 网页扫码canvas是否启用,默认启用
|
||||||
*/
|
*/
|
||||||
webCanvasStyle?: string,
|
webCanvasEnabled?: boolean,
|
||||||
|
/**
|
||||||
|
* 网页扫码canvas样式,默认:position: fixed; width: 300px; height: 300px; top: 0; left: 0; z-index: 9999;
|
||||||
|
*/
|
||||||
|
webScanCanvasStyle?: string,
|
||||||
/**
|
/**
|
||||||
* 网页扫码类型,默认支持二维码和条码
|
* 网页扫码类型,默认支持二维码和条码
|
||||||
*/
|
*/
|
||||||
webScanType?: ('qrCode' | 'barCode')[],
|
webScanType?: ('qrCode' | 'barCode')[],
|
||||||
/**
|
/**
|
||||||
* 网页扫码canvas是否启用,默认启用
|
* 网页扫码视频是否镜像,默认自动判断:前置/PC镜像,后置不镜像
|
||||||
*/
|
*/
|
||||||
webCanvasEnabled?: boolean,
|
webScanVideoMirror?: boolean,
|
||||||
|
/**
|
||||||
|
* 网页扫码视频是否垂直镜像,默认不镜像
|
||||||
|
*/
|
||||||
|
webScanVideoMirrorVertical?: boolean,
|
||||||
/**
|
/**
|
||||||
* 网页扫码成功提示音地址,默认使用内置提示音
|
* 网页扫码成功提示音地址,默认使用内置提示音
|
||||||
*/
|
*/
|
||||||
@@ -153,6 +161,10 @@ interface IScan {
|
|||||||
* 开启扫码
|
* 开启扫码
|
||||||
*/
|
*/
|
||||||
startScan(): void;
|
startScan(): void;
|
||||||
|
/**
|
||||||
|
* 开启视频扫码
|
||||||
|
*/
|
||||||
|
scanVideo(): void;
|
||||||
/**
|
/**
|
||||||
* 选择图片进行识别
|
* 选择图片进行识别
|
||||||
*/
|
*/
|
||||||
|
|||||||
10
dist/index.html
vendored
10
dist/index.html
vendored
@@ -161,17 +161,18 @@
|
|||||||
|
|
||||||
section {
|
section {
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
}</style></head><body><main class="page"><section class="hero"><h1>IScan 扫码 SDK Demo</h1><p>统一接入桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</p></section><section class="grid"><div class="card"><h2>功能说明</h2><ul class="feature-list"><li>桥接环境优先调用 App 原生扫码。</li><li>微信环境支持初始化 JSSDK 并调用 scanQRCode。</li><li>浏览器环境使用 BarcodeDetector 识别二维码和条形码。</li><li>摄像头不可用时可选择图片识别。</li><li>支持扫码枪快速输入,并与扫码监听规则统一回调。</li></ul></div><div class="card"><h2>当前状态</h2><p>SDK 状态:<span id="status" class="status">loading</span></p><p>运行环境:</p><pre id="output" class="panel"></pre></div></section><section class="card"><h2>操作</h2><p>点击开始后,会按桥接、微信、Web 摄像头、图片识别的顺序选择可用扫码方式。</p><div class="actions"><button onclick="startScan()" class="btn">开始扫码</button> <button onclick="scanImage()" class="btn secondary">选择图片识别</button> <button onclick="stopScan()" class="btn secondary">停止扫码</button></div></section><section class="grid"><div class="card"><h2>扫码结果</h2><pre id="result" class="panel result"></pre></div><div class="card"><h2>错误信息</h2><pre id="error" class="panel error"></pre></div></section><section class="card code"><h2>接入方式</h2><pre>IScan.config({
|
}</style></head><body><main class="page"><section class="hero"><h1>IScan 通用扫码 SDK</h1><p>统一接入桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</p></section><section class="grid"><div class="card"><h2>功能说明</h2><ul class="feature-list"><li>支持桥接扫码、微信 JSSDK 扫码、Web 摄像头扫码、图片识别和扫码枪输入。</li><li>浏览器环境使用 ZXing的wasm库识别二维码和条形码。</li><li>扫码结果又监听规则统一回调。</li></ul></div><div class="card"><h2>当前状态</h2><p>SDK 状态:<span id="status" class="status">loading</span></p><p>运行环境:</p><pre id="output" class="panel"></pre></div></section><section class="card"><h2>操作</h2><p>点击开始后,会按桥接、微信、Web 摄像头、图片识别的顺序选择可用扫码方式。</p><div class="actions"><button onclick="startScan()" class="btn">开始扫码</button> <button onclick="scanVideo()" class="btn secondary">开启视频扫码</button> <button onclick="scanImage()" class="btn secondary">选择图片识别</button> <button onclick="stopScan()" class="btn secondary">停止扫码</button></div></section><section class="card"><h2>扫码结果</h2><pre id="result" class="panel result"></pre></section><section class="card"><h2>错误信息</h2><pre id="error" class="panel error"></pre><p style="color: #919191">错误信息可能来源于扫码结果、扫码过程、扫码初始化等。</p></section><section class="card code"><h2>接入方式</h2><pre>IScan.config({
|
||||||
webCanvasEnabled: true,
|
webCanvasEnabled: true,
|
||||||
webScanBeepEnabled: true,
|
webScanBeepEnabled: true,
|
||||||
initWechatJssdk: {
|
initWechatJssdk: {
|
||||||
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
apiUrl: "https://your-domain.com/wechat/jssdk-config"
|
||||||
}
|
}
|
||||||
}).then(function () {
|
}).then(function () {
|
||||||
|
// 监听扫码状态
|
||||||
IScan.setStatusListener(function () {
|
IScan.setStatusListener(function () {
|
||||||
console.log("status:", IScan.getStatus());
|
console.log("status:", IScan.getStatus());
|
||||||
});
|
});
|
||||||
|
// 监听扫码结果
|
||||||
IScan.onScanListener(function (res) {
|
IScan.onScanListener(function (res) {
|
||||||
console.log("scan result:", res);
|
console.log("scan result:", res);
|
||||||
}, "scan", null, 100);
|
}, "scan", null, 100);
|
||||||
@@ -277,4 +278,9 @@ IScan.stopScan();</pre></section></main><script>(function () {
|
|||||||
IScan.scanImage();
|
IScan.scanImage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function scanVideo() {
|
||||||
|
hide();
|
||||||
|
IScan.scanVideo();
|
||||||
|
}
|
||||||
|
|
||||||
ready();</script><script src="index.js"></script></body></html>
|
ready();</script><script src="index.js"></script></body></html>
|
||||||
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -1,6 +1,7 @@
|
|||||||
import './polyfill';
|
import './polyfill';
|
||||||
import { setConfig, getVersion } from './services/config';
|
import { setConfig, getVersion } from './services/config';
|
||||||
import { onScanListener, offScanListener, setStatusListener, getStatus, startScan, stopScan, scanImage, clear } from './services/provider/scan';
|
import { onScanListener, offScanListener, setStatusListener, getStatus,
|
||||||
|
startScan, stopScan, scanVideo, scanImage, clear } from './services/provider/scan';
|
||||||
import { initWxJssdk } from './services/wx';
|
import { initWxJssdk } from './services/wx';
|
||||||
import { printDebug } from './utils/logger';
|
import { printDebug } from './utils/logger';
|
||||||
|
|
||||||
@@ -41,6 +42,7 @@ export default Object.assign({}, {
|
|||||||
getStatus,
|
getStatus,
|
||||||
startScan,
|
startScan,
|
||||||
stopScan,
|
stopScan,
|
||||||
|
scanVideo,
|
||||||
scanImage,
|
scanImage,
|
||||||
clear,
|
clear,
|
||||||
});
|
});
|
||||||
@@ -258,7 +258,7 @@ export function onScanListener(listener, key, match, level) {
|
|||||||
key,
|
key,
|
||||||
match: match || "",
|
match: match || "",
|
||||||
level: level || 0,
|
level: level || 0,
|
||||||
listener: listener ,
|
listener: listener,
|
||||||
cancel: () => {
|
cancel: () => {
|
||||||
const index = _scan_listener_list.indexOf(item);
|
const index = _scan_listener_list.indexOf(item);
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@@ -332,12 +332,12 @@ export function startScan() {
|
|||||||
scanPromise = __startWxScan();
|
scanPromise = __startWxScan();
|
||||||
} else if (isSupportWebScan()) {
|
} else if (isSupportWebScan()) {
|
||||||
console.log("startScanForWeb");
|
console.log("startScanForWeb");
|
||||||
scanPromise = startScanForWeb(getConfig("webCanvasStyle"), __result);
|
scanPromise = startScanForWeb(getConfig("webScanCanvasStyle"), __result);
|
||||||
} else if (isSupportImageScan()) {
|
} else if (isSupportImageScan()) {
|
||||||
console.log("startScanForImage");
|
console.log("startScanForImage");
|
||||||
scanPromise = __startImageScan();
|
scanPromise = __startImageScan();
|
||||||
} else {
|
} else {
|
||||||
console.log("not support scanner");
|
console.log("Not support scanner");
|
||||||
}
|
}
|
||||||
return Promise.race([scanPromise, scannerPromise]);
|
return Promise.race([scanPromise, scannerPromise]);
|
||||||
}).finally(() => {
|
}).finally(() => {
|
||||||
@@ -346,16 +346,38 @@ export function startScan() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scanImage() {
|
export function scanVideo() {
|
||||||
if (!isSupportImageScan()) {
|
if (!isSupportWebScan()) {
|
||||||
console.log("not support image scanner");
|
console.log("Not support video scanner");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
startScanForImage().then(resp => {
|
Promise.resolve().then(() => {
|
||||||
|
__scanning();
|
||||||
|
return startScanForWeb(getConfig("webScanCanvasStyle"), __result).then(resp => {
|
||||||
if (resp && resp.result) {
|
if (resp && resp.result) {
|
||||||
__result(resp.result);
|
__result(resp.result);
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
throw resp.error;
|
||||||
console.log("scan image error", err);
|
}).catch(err => { });
|
||||||
|
}).finally(() => {
|
||||||
|
__closed();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function scanImage() {
|
||||||
|
if (!isSupportImageScan()) {
|
||||||
|
console.log("Not support image scanner");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Promise.resolve().then(() => {
|
||||||
|
__scanning();
|
||||||
|
return startScanForImage().then(resp => {
|
||||||
|
if (resp && resp.result) {
|
||||||
|
__result(resp.result);
|
||||||
|
}
|
||||||
|
throw resp.error;
|
||||||
|
}).catch(err => { });
|
||||||
|
}).finally(() => {
|
||||||
|
__closed();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -32,15 +32,35 @@ function createEl(tagName, id, style, appendChild) {
|
|||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
function canvasDrawLine(context, width, begin, end, color) {
|
function transformPoint(point, width, height, mirrorHorizontal, mirrorVertical, cover) {
|
||||||
|
let x = point.x;
|
||||||
|
let y = point.y;
|
||||||
|
if (cover) {
|
||||||
|
x = cover.x + point.x * cover.scale;
|
||||||
|
y = cover.y + point.y * cover.scale;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: mirrorHorizontal ? width - x : x,
|
||||||
|
y: mirrorVertical ? height - y : y
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function canvasDrawLine(context, width, height, begin, end, color, mirrorHorizontal, mirrorVertical, cover) {
|
||||||
|
const beginPoint = transformPoint(begin, width, height, mirrorHorizontal, mirrorVertical, cover);
|
||||||
|
const endPoint = transformPoint(end, width, height, mirrorHorizontal, mirrorVertical, cover);
|
||||||
context.beginPath();
|
context.beginPath();
|
||||||
context.moveTo(width - begin.x, begin.y);
|
context.moveTo(beginPoint.x, beginPoint.y);
|
||||||
context.lineTo(width - end.x, end.y);
|
context.lineTo(endPoint.x, endPoint.y);
|
||||||
context.lineWidth = 4;
|
context.lineWidth = 4;
|
||||||
context.strokeStyle = color;
|
context.strokeStyle = color;
|
||||||
context.stroke();
|
context.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isMobile() {
|
||||||
|
return typeof navigator !== 'undefined'
|
||||||
|
&& /Android|iPhone|iPad|iPod|Mobile/i.test(navigator.userAgent || "");
|
||||||
|
}
|
||||||
|
|
||||||
function getBarcodeFormats(scanType) {
|
function getBarcodeFormats(scanType) {
|
||||||
let formats = [];
|
let formats = [];
|
||||||
if (!scanType) {
|
if (!scanType) {
|
||||||
@@ -114,11 +134,57 @@ function createBarcodeDetector(scanType) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBarcode(context, width, barcode) {
|
function shouldMirrorWebVideo(stream) {
|
||||||
|
const webScanVideoMirror = getConfig("webScanVideoMirror");
|
||||||
|
if (typeof webScanVideoMirror === "boolean") {
|
||||||
|
return webScanVideoMirror;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const track = stream && stream.getVideoTracks && stream.getVideoTracks()[0];
|
||||||
|
const settings = track && track.getSettings && track.getSettings();
|
||||||
|
if (settings && settings.facingMode === "environment") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (settings && settings.facingMode === "user") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
}
|
||||||
|
return !isMobile();
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldMirrorWebVideoVertical() {
|
||||||
|
return getConfig("webScanVideoMirrorVertical") === true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCanvasDisplaySize(canvasEl, fallbackWidth, fallbackHeight) {
|
||||||
|
const rect = canvasEl.getBoundingClientRect();
|
||||||
|
const width = rect.width || parseFloat(canvasEl.style.width) || fallbackWidth;
|
||||||
|
const height = rect.height || parseFloat(canvasEl.style.height) || fallbackHeight;
|
||||||
|
return {
|
||||||
|
width: Math.max(1, Math.round(width)),
|
||||||
|
height: Math.max(1, Math.round(height))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCoverDrawOptions(sourceWidth, sourceHeight, targetWidth, targetHeight) {
|
||||||
|
const scale = Math.max(targetWidth / sourceWidth, targetHeight / sourceHeight);
|
||||||
|
const width = sourceWidth * scale;
|
||||||
|
const height = sourceHeight * scale;
|
||||||
|
return {
|
||||||
|
scale,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
x: (targetWidth - width) / 2,
|
||||||
|
y: (targetHeight - height) / 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawBarcode(context, width, height, barcode, mirrorHorizontal, mirrorVertical, cover) {
|
||||||
const cornerPoints = barcode.cornerPoints;
|
const cornerPoints = barcode.cornerPoints;
|
||||||
if (cornerPoints && cornerPoints.length) {
|
if (cornerPoints && cornerPoints.length) {
|
||||||
for (let i = 0; i < cornerPoints.length; i++) {
|
for (let i = 0; i < cornerPoints.length; i++) {
|
||||||
canvasDrawLine(context, width, cornerPoints[i], cornerPoints[(i + 1) % cornerPoints.length], "#FF3B58");
|
canvasDrawLine(context, width, height, cornerPoints[i], cornerPoints[(i + 1) % cornerPoints.length], "#FF3B58", mirrorHorizontal, mirrorVertical, cover);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -131,7 +197,7 @@ function drawBarcode(context, width, barcode) {
|
|||||||
{ x: rect.x, y: rect.y + rect.height }
|
{ x: rect.x, y: rect.y + rect.height }
|
||||||
];
|
];
|
||||||
for (let i = 0; i < points.length; i++) {
|
for (let i = 0; i < points.length; i++) {
|
||||||
canvasDrawLine(context, width, points[i], points[(i + 1) % points.length], "#FF3B58");
|
canvasDrawLine(context, width, height, points[i], points[(i + 1) % points.length], "#FF3B58", mirrorHorizontal, mirrorVertical, cover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,13 +327,14 @@ export function startScanForWeb(canvasStyle, onResult) {
|
|||||||
"display: none", false);
|
"display: none", false);
|
||||||
let canvasEnabled = getConfig("webCanvasEnabled") !== false;
|
let canvasEnabled = getConfig("webCanvasEnabled") !== false;
|
||||||
let canvasDisplay = "";
|
let canvasDisplay = "";
|
||||||
let canvasBaseStyle = canvasStyle || "position: fixed; width: 300px; height: 240px; top: 0; left: 0; z-index: 9999;";
|
let canvasBaseStyle = canvasStyle || "position: fixed; width: 300px; height: 300px; top: 0; left: 0; z-index: 9999;";
|
||||||
let canvasEl = createEl("canvas",
|
let canvasEl = createEl("canvas",
|
||||||
"__webscan_canvas__",
|
"__webscan_canvas__",
|
||||||
canvasBaseStyle + " display: none;", true);
|
canvasBaseStyle + " display: none;", true);
|
||||||
canvasDisplay = canvasEl.style.display;
|
canvasDisplay = canvasEl.style.display;
|
||||||
canvasEl.style.cssText = canvasBaseStyle;
|
canvasEl.style.cssText = canvasBaseStyle;
|
||||||
canvasDisplay = canvasEl.style.display;
|
canvasDisplay = canvasEl.style.display;
|
||||||
|
let canvasDisplaySize = getCanvasDisplaySize(canvasEl, 300, 240);
|
||||||
canvasEl.style.display = "none";
|
canvasEl.style.display = "none";
|
||||||
let context = canvasEl.getContext("2d");
|
let context = canvasEl.getContext("2d");
|
||||||
let currentUuid = scanWeb.uuid;
|
let currentUuid = scanWeb.uuid;
|
||||||
@@ -288,6 +355,8 @@ export function startScanForWeb(canvasStyle, onResult) {
|
|||||||
}).then(function (options) {
|
}).then(function (options) {
|
||||||
const detector = options.detector;
|
const detector = options.detector;
|
||||||
const stream = options.stream;
|
const stream = options.stream;
|
||||||
|
const mirrorVideo = shouldMirrorWebVideo(stream);
|
||||||
|
const mirrorVideoVertical = shouldMirrorWebVideoVertical();
|
||||||
videoEl.srcObject = stream;
|
videoEl.srcObject = stream;
|
||||||
videoEl.setAttribute("playsinline", true); // iOS使用
|
videoEl.setAttribute("playsinline", true); // iOS使用
|
||||||
videoEl.play();
|
videoEl.play();
|
||||||
@@ -307,10 +376,18 @@ export function startScanForWeb(canvasStyle, onResult) {
|
|||||||
let tick = () => {
|
let tick = () => {
|
||||||
try {
|
try {
|
||||||
if (videoEl.readyState === videoEl.HAVE_ENOUGH_DATA && !detecting) {
|
if (videoEl.readyState === videoEl.HAVE_ENOUGH_DATA && !detecting) {
|
||||||
canvasEl.height = videoEl.videoHeight;
|
canvasEl.width = canvasDisplaySize.width;
|
||||||
canvasEl.width = videoEl.videoWidth;
|
canvasEl.height = canvasDisplaySize.height;
|
||||||
context.setTransform(-1, 0, 0, 1, canvasEl.width, 0);
|
const cover = getCoverDrawOptions(videoEl.videoWidth, videoEl.videoHeight, canvasEl.width, canvasEl.height);
|
||||||
context.drawImage(videoEl, 0, 0, canvasEl.width, canvasEl.height);
|
context.setTransform(
|
||||||
|
mirrorVideo ? -1 : 1,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
mirrorVideoVertical ? -1 : 1,
|
||||||
|
mirrorVideo ? canvasEl.width : 0,
|
||||||
|
mirrorVideoVertical ? canvasEl.height : 0
|
||||||
|
);
|
||||||
|
context.drawImage(videoEl, cover.x, cover.y, cover.width, cover.height);
|
||||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
if (canvasEnabled && !displayed) {
|
if (canvasEnabled && !displayed) {
|
||||||
displayed = true;
|
displayed = true;
|
||||||
@@ -323,7 +400,7 @@ export function startScanForWeb(canvasStyle, onResult) {
|
|||||||
if (!onResult || !onResult(code.rawValue)) {
|
if (!onResult || !onResult(code.rawValue)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
drawBarcode(context, canvasEl.width, code);
|
drawBarcode(context, canvasEl.width, canvasEl.height, code, mirrorVideo, mirrorVideoVertical, cover);
|
||||||
playScanBeep();
|
playScanBeep();
|
||||||
scanWeb.uuid = null;
|
scanWeb.uuid = null;
|
||||||
scanWeb.finish = true;
|
scanWeb.finish = true;
|
||||||
|
|||||||
20
types/index.d.ts
vendored
20
types/index.d.ts
vendored
@@ -3,17 +3,25 @@
|
|||||||
*/
|
*/
|
||||||
interface ScanConfigOptions {
|
interface ScanConfigOptions {
|
||||||
/**
|
/**
|
||||||
* 网页扫码canvas样式
|
* 网页扫码canvas是否启用,默认启用
|
||||||
*/
|
*/
|
||||||
webCanvasStyle?: string,
|
webCanvasEnabled?: boolean,
|
||||||
|
/**
|
||||||
|
* 网页扫码canvas样式,默认:position: fixed; width: 300px; height: 300px; top: 0; left: 0; z-index: 9999;
|
||||||
|
*/
|
||||||
|
webScanCanvasStyle?: string,
|
||||||
/**
|
/**
|
||||||
* 网页扫码类型,默认支持二维码和条码
|
* 网页扫码类型,默认支持二维码和条码
|
||||||
*/
|
*/
|
||||||
webScanType?: ('qrCode' | 'barCode')[],
|
webScanType?: ('qrCode' | 'barCode')[],
|
||||||
/**
|
/**
|
||||||
* 网页扫码canvas是否启用,默认启用
|
* 网页扫码视频是否镜像,默认自动判断:前置/PC镜像,后置不镜像
|
||||||
*/
|
*/
|
||||||
webCanvasEnabled?: boolean,
|
webScanVideoMirror?: boolean,
|
||||||
|
/**
|
||||||
|
* 网页扫码视频是否垂直镜像,默认不镜像
|
||||||
|
*/
|
||||||
|
webScanVideoMirrorVertical?: boolean,
|
||||||
/**
|
/**
|
||||||
* 网页扫码成功提示音地址,默认使用内置提示音
|
* 网页扫码成功提示音地址,默认使用内置提示音
|
||||||
*/
|
*/
|
||||||
@@ -153,6 +161,10 @@ interface IScan {
|
|||||||
* 开启扫码
|
* 开启扫码
|
||||||
*/
|
*/
|
||||||
startScan(): void;
|
startScan(): void;
|
||||||
|
/**
|
||||||
|
* 开启视频扫码
|
||||||
|
*/
|
||||||
|
scanVideo(): void;
|
||||||
/**
|
/**
|
||||||
* 选择图片进行识别
|
* 选择图片进行识别
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user