/* ═════ 05-07 拍照页 ═════ 对齐 H5 h5/css/style.css 的 #s-cam 静态态: .cam-step top 7.1%,21.5px/700,letter-spacing 1u,text-shadow .cam-guide bottom 22.4%,14.5px,分隔线 15u 高 .cam-controls bottom 5.2%,高 62u,内边距 56u,快门 62u 单位换算:calc(N * var(--u)) → 2N rpx */ .cam { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; background: #000; } /* H5 静态态:白底 + 85% 黑蒙版 ≈ #262626 */ .cam-bg { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #fff; } /* ─── 顶部步骤文案 ─── */ .cam-step { position: absolute; left: 0; right: 0; top: 7.1%; text-align: center; color: #fff; font-size: 21.5px; font-weight: 700; line-height: 1.5; letter-spacing: 2rpx; text-shadow: 0 1px 10px rgba(0, 0, 0, .4); z-index: 2; } .cam-step-tip { font-size: 21.5px; } .cam-step-no { font-size: 21.5px; } /* ─── 真机取景相机(铺满,不能有子节点) ─── */ .cam-device { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 0; } /* H5 原始轮廓生成的透明 PNG;额外边缘遮罩保持不同比例视口的暗框。 */ .cam-mask { position: absolute; left: 0; top: 0; right: 0; bottom: 0; z-index: 1; pointer-events: none; } /* ─── 底部引导条 ─── */ .cam-guide { position: absolute; left: 0; right: 0; bottom: 22.4%; display: flex; justify-content: center; align-items: center; z-index: 2; } .cam-guide-item { color: #fff; font-size: 14.5px; font-weight: 400; } .cam-guide-sep { width: 0; height: 30rpx; border-left: 1px solid rgba(255, 255, 255, .7); margin: 0 52rpx; } /* ─── 控制条:相册 / 快门 / 翻转 ─── */ .cam-controls { position: absolute; left: 0; right: 0; bottom: 5.2%; height: 124rpx; display: flex; align-items: center; justify-content: space-between; padding: 0 112rpx; box-sizing: border-box; margin-bottom: env(safe-area-inset-bottom); z-index: 2; } .cam-side { width: 60rpx; height: 124rpx; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 14.5px; } .cam-shutter { width: 124rpx; height: 124rpx; border-radius: 50%; border: none; display: flex; align-items: center; justify-content: center; box-sizing: border-box; } .cam-shutter-dot { width: 96rpx; height: 96rpx; border-radius: 50%; background: #fff; } .cam-side image { width:60rpx; height:60rpx; } .cam-side-switch { position:relative; } .cam-switch-label { position:absolute; top:calc(50% + 34rpx); left:50%; transform:translateX(-50%); white-space:nowrap; font-size:10px; line-height:1.3; } .cam-verifying { position:absolute; top:0; right:0; bottom:0; left:0; z-index:100; display:flex; flex-direction:column; align-items:center; justify-content:center; background:#101823; color:#fff; font-size:14px; gap:32rpx; } .cam-shutter-auto { visibility:hidden; } .cam-live-hint { position:absolute; bottom:27%; left:24rpx; right:24rpx; text-align:center; color:#fff; font-size:17px; font-weight:500; z-index:3; } .cam-live-hint.good { color:#34C759; } .cam-shutter image { width:124rpx; height:124rpx; } .cam-mask-image { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); } .cam-mask-image.mirror { transform:translate(-50%,-50%) scaleX(-1); } .cam-live-scan { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); overflow:hidden; -webkit-mask-size:100% 100%; mask-size:100% 100%; } .cam-live-scan.mirror { transform:translate(-50%,-50%) scaleX(-1); } .scan-front { -webkit-mask-image:url('../../assets/camera/hole-front.png'); mask-image:url('../../assets/camera/hole-front.png'); } .scan-right { -webkit-mask-image:url('../../assets/camera/hole-right.png'); mask-image:url('../../assets/camera/hole-right.png'); } .scan-left { -webkit-mask-image:url('../../assets/camera/hole-left.png'); mask-image:url('../../assets/camera/hole-left.png'); } .cam-live-band { position:absolute; top:10%; left:0; right:0; height:12%; background:linear-gradient(to bottom,rgba(245,240,120,0),rgba(245,240,120,.32),rgba(245,240,120,.95)); animation:camera-scan 2.2s ease-in-out infinite; } @keyframes camera-scan { from {transform:translateY(0);} to {transform:translateY(440%);} } .cam-mask-edge { position:absolute; background:rgba(0,0,0,.85); } .edge-top { top:0; left:0; right:0; } .edge-bottom { bottom:0; left:0; right:0; } .edge-left { left:0; top:0; bottom:0; } .edge-right { right:0; top:0; bottom:0; } .cam-next { position:absolute; left:50%; top:50%; transform:translate(-50%,-50%); width:460rpx; box-sizing:content-box; padding:44rpx 32rpx 40rpx; border-radius:24rpx; background:rgba(0,0,0,.72); color:#fff; text-align:center; z-index:5; } .cam-next-ok { margin:0 auto 24rpx; border-radius:50%; width:80rpx; height:80rpx; line-height:80rpx; background:#34C759; font-size:26px; } .cam-next-done { font-size:17px; font-weight:500; } .cam-next-tip { margin-top:16rpx; white-space:pre-line; font-size:14px; line-height:1.5; } .cam-countdown { position:absolute; top:45%; left:50%; transform:translate(-50%,-50%); color:#fff; font:600 88px/1 Arial,sans-serif; z-index:8; } .cam-fill { position:absolute; top:0; left:0; right:0; bottom:0; background:#fff; z-index:9; } .cam-enable { position:absolute; bottom:16%; left:50%; transform:translateX(-50%); padding:16rpx 32rpx; border:1px solid #fff; border-radius:8rpx; color:#fff; z-index:4; } .cam-settings { position:absolute; top:24rpx; left:24rpx; color:#fff; font-size:12px; z-index:4; } .compress-canvas { position:fixed; left:200vw; top:0; pointer-events:none; } /* ─── 提示/错误 ─── */ .cam-hint { position: absolute; left: 64rpx; right: 64rpx; bottom: 34%; text-align: center; color: rgba(255, 255, 255, .9); font-size: 13px; line-height: 1.6; z-index: 3; } /* ─── 拍后预览 ─── */ .cam-preview { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 10; } .cam-preview-img { width: 100%; height: 68%; } .cam-preview-btns { display: flex; gap: 40rpx; margin-top: 40rpx; } .cam-preview-btn { width: 220rpx; height: 72rpx; line-height: 72rpx; text-align: center; border-radius: 10rpx; border: 1px solid rgba(255, 255, 255, .6); color: #fff; font-size: 14.5px; } .cam-preview-btn.ok { background: #F5F078; border-color: #F5F078; color: #282828; } /* ─── 分析中 ─── */ .cam-analyzing { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #000; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 20; } .cam-analyzing-text { color: #fff; font-size: 17px; letter-spacing: 1rpx; padding:0 40rpx; text-align:center; z-index:2; } .cam-cancel { position:absolute; bottom:20rpx; left:0; right:0; text-align:center; color: rgba(255, 255, 255, .7); font-size: 13px; text-decoration: underline; } .scan-stage { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); } .scan-artwork { width:100%; height:100%; } .scan-face { position:absolute; left:0; top:0; right:0; bottom:0; -webkit-mask-image:url('../../assets/camera/scan-face-mask.png'); mask-image:url('../../assets/camera/scan-face-mask.png'); -webkit-mask-size:100% 100%; mask-size:100% 100%; overflow:hidden; } .scan-beam { position:absolute; left:0; right:0; top:20%; height:18%; background:linear-gradient(to bottom,#F5F078 0%,#F5F078 35%,rgba(245,240,120,0) 100%); animation:report-scan 1s ease-in-out infinite; } @keyframes report-scan { 0%,100% {transform:translateY(0);} 50% {transform:translateY(166%);} } .scan-flip-icon { position:absolute; left:77.314815%; top:87.900526%; width:8.888889%; height:4.591105%; background:#000; display:flex; align-items:center; justify-content:center; } .scan-flip-icon image { width:83.333333%; height:83.333333%; } .analysis-stage { position:absolute; bottom:100rpx; left:32rpx; right:32rpx; text-align:center; color:#bbb; font-size:12px; } .analysis-retry,.analysis-retake { color:#fff; font-size:14px; padding:20rpx 36rpx; margin-top:24rpx; border:1px solid #777; border-radius:10rpx; z-index:2; } /* ─── 权限诊断(开发版) ─── */ .cam-diag-entry { position: absolute; top: 88rpx; right: 32rpx; z-index: 30; padding: 12rpx 20rpx; border-radius: 12rpx; background: rgba(0, 0, 0, .55); color: #fff; font-size: 12px; } .cam-diag { position: absolute; left: 32rpx; right: 32rpx; top: 160rpx; bottom: 160rpx; z-index: 40; background: rgba(6, 16, 26, .96); border: 1rpx solid rgba(120, 200, 255, .35); border-radius: 20rpx; padding: 20rpx; display: flex; flex-direction: column; } .cam-diag-scroll { flex: 1; } .cam-diag-text { color: #9fd0ff; font-size: 11px; line-height: 1.7; white-space: pre-wrap; word-break: break-all; } .cam-diag-close { margin-top: 16rpx; text-align: center; background: #F5F078; color: #282828; border-radius: 12rpx; padding: 14rpx 0; font-size: 13px; } .cam-probe-toolbar { position:fixed; z-index:50; left:24rpx; right:24rpx; padding:14rpx 18rpx; border-radius:12rpx; background:rgba(12,39,56,.94); color:#fff; } .cam-probe-version { margin-bottom:10rpx; font-size:22rpx; line-height:30rpx; } .cam-probe-actions { display:flex; gap:14rpx; } .cam-probe-actions button { flex:1; margin:0; padding:0 8rpx; font-size:25rpx; line-height:64rpx; background:#F5F078; color:#142632; } /* ─── 调试模式结果 ─── */ .cam-debug { position: absolute; left: 0; top: 0; right: 0; bottom: 0; background: #fff; padding: 88rpx 40rpx 40rpx; box-sizing: border-box; overflow-y: auto; z-index: 25; } .cam-debug-title { font-size: 17px; font-weight: 600; margin-bottom: 16rpx; } .cam-debug-note { font-size: 12px; color: #707070; line-height: 1.6; margin-bottom: 24rpx; } .cam-debug-item { margin-bottom: 32rpx; } .cam-debug-img { width: 100%; height: 320rpx; background: #f2f2f2; } .cam-debug-meta { font-size: 12px; color: #4A4A4A; margin-top: 12rpx; } .cam-debug-btn { width: 100%; margin-top: 8rpx; } .cam-debug-exit { margin-top: 24rpx; text-align: center; font-size: 13px; color: #707070; text-decoration: underline; }