fix(h5): show captured face behind report scan animation
This commit is contained in:
+31
-6
@@ -143,6 +143,22 @@
|
||||
|
||||
/* ─── 弹窗管理 ─── */
|
||||
var SCAN_CYCLE_MS = 1000, scanCycle = null, scanMask = null;
|
||||
function setScanPhoto(source, mirrored) {
|
||||
var image = $('#scan-photo');
|
||||
image.classList.toggle('mirror', !!mirrored);
|
||||
if (image.getAttribute('src') === source) return;
|
||||
image.onload = function () {
|
||||
// A delayed JPEG decode must still get one complete visible scan cycle.
|
||||
if ($('#p-analyzing').classList.contains('show')) restartScanCycle();
|
||||
};
|
||||
image.onerror = function () { image.removeAttribute('src'); };
|
||||
image.src = source;
|
||||
}
|
||||
function clearScanPhoto() {
|
||||
var image = $('#scan-photo');
|
||||
image.onload = image.onerror = null;
|
||||
image.removeAttribute('src'); image.classList.remove('mirror');
|
||||
}
|
||||
function restartScanCycle() {
|
||||
if (!scanCycle || scanCycle.done) return;
|
||||
var overlay = $('#p-analyzing'), cycle = scanCycle;
|
||||
@@ -204,7 +220,10 @@
|
||||
$('#' + id).classList.add('show');
|
||||
if (id === 'p-analyzing') { startScanCycle(); $('.scan-cancel').focus({ preventScroll: true }); }
|
||||
}
|
||||
function closeOverlay(id) { $('#' + id).classList.remove('show'); if (id === 'p-analyzing') stopScanCycle(); }
|
||||
function closeOverlay(id) {
|
||||
$('#' + id).classList.remove('show');
|
||||
if (id === 'p-analyzing') { stopScanCycle(); clearScanPhoto(); }
|
||||
}
|
||||
|
||||
// 点遮罩空白处关闭(与各自关闭按钮同行为:隐私→回启动页、拍照引导→留在档案页)
|
||||
// 只响应遮罩本身(拍照引导另含底图层),不误伤弹窗卡片内交互
|
||||
@@ -442,7 +461,7 @@
|
||||
var IS_MOCK = /[?&]mock=1/.test(location.search); // mock:不加载 face-api、不跑检测,analyze 直返内置样本
|
||||
var camVideo = $('#cam-video'), camFile = $('#cam-file'), albumFile = $('#album-file');
|
||||
var camStream = null, camLive = false, camFallback = false, camSeqCam = 0; // camSeqCam:相机启动令牌,防止迟到的授权回调泄漏摄像头
|
||||
var photos = []; // 三连拍(dataURL),拍摄中与 CAM_STEPS 同序;送检前经 photosByView 重排为 [正脸, 左脸, 右脸]
|
||||
var photos = [], scanPhotoMirrored = false; // 三连拍(dataURL),拍摄中与 CAM_STEPS 同序;送检前经 photosByView 重排为 [正脸, 左脸, 右脸]
|
||||
var captureDiagnostics = [], holdState = null;
|
||||
|
||||
// 约束逐级放宽:facingMode 裸值在部分 Android 抛 OverconstrainedError,先 ideal 再退 video:true,最后才降级
|
||||
@@ -568,7 +587,7 @@
|
||||
hideCamStatus();
|
||||
shutterLock = false;
|
||||
if (err) { toast(err); voice.play(VOICE.fail, { cut: true }); return; } // 不合格:停在本步重拍
|
||||
onPhotoCaptured(url);
|
||||
onPhotoCaptured(url, false); // Files already have their own camera orientation.
|
||||
});
|
||||
};
|
||||
img.onerror = function () { toast('照片读取失败,请重新选择'); };
|
||||
@@ -1009,9 +1028,13 @@
|
||||
var shutterLock = false; // 快门防连点锁:流程进行中直接忽略
|
||||
|
||||
// 照片就绪(已通过校验)后推进流程:存图→「拍摄完成」→300ms 过渡→下一步;三步严格按顺序,本步合格才进下一步
|
||||
function onPhotoCaptured(dataUrl) {
|
||||
function onPhotoCaptured(dataUrl, mirrored) {
|
||||
shutterLock = true; // 推进窗口上锁(停顿期间不检测、不接受快门),直到下一步/送检
|
||||
photos[camStep] = dataUrl;
|
||||
if (camStep === 0) {
|
||||
scanPhotoMirrored = !!mirrored;
|
||||
setScanPhoto(dataUrl, scanPhotoMirrored); // Decode the front photo before the waiting screen opens.
|
||||
}
|
||||
voice.play(VOICE.shot, { cut: true }); // 「拍摄完成」:已拍下,本步未播完的引导作废
|
||||
var seq = camSeq, hasNext = camStep < CAM_STEPS.length - 1;
|
||||
if (hasNext) {
|
||||
@@ -1049,7 +1072,7 @@
|
||||
var fill = $('#cam-fill');
|
||||
fill.classList.add('on'); // .on 无过渡,瞬间点亮
|
||||
setTimeout(function () {
|
||||
var shot = captureFromVideo();
|
||||
var shot = captureFromVideo(), mirrored = effMirror();
|
||||
setTimeout(function () {
|
||||
fill.classList.remove('on'); // 移除 .on 恢复过渡,淡出
|
||||
capturing = false;
|
||||
@@ -1062,7 +1085,7 @@
|
||||
shutterLock = false; holdState = null; okSince = 0;
|
||||
setHint(error, false); armNudge(); return;
|
||||
}
|
||||
onPhotoCaptured(shot);
|
||||
onPhotoCaptured(shot, mirrored);
|
||||
});
|
||||
}, 300);
|
||||
}, 300);
|
||||
@@ -1072,6 +1095,7 @@
|
||||
function submitPhotos(seq) {
|
||||
camStep = 0;
|
||||
photos = photosByView(photos);
|
||||
setScanPhoto(photos[0], scanPhotoMirrored);
|
||||
openOverlay('p-analyzing');
|
||||
voice.play(VOICE.analyzing); // 「正在生成您的肌肤报告」
|
||||
// 档案与检测一起上报(后台记录用):年龄非法值服务端按 null 处理
|
||||
@@ -1629,6 +1653,7 @@
|
||||
camSeq++; // 使旧的快门/分析回调失效
|
||||
camStep = 0;
|
||||
photos = []; // 新一轮三连拍(从 startCamera 挪出:后台恢复续拍时保留已拍)
|
||||
scanPhotoMirrored = false; clearScanPhoto();
|
||||
captureDiagnostics = [];
|
||||
shutterLock = false; // 重新进入流程,保险解锁
|
||||
showScreen('s-cam', 'push');
|
||||
|
||||
Reference in New Issue
Block a user