如何在JavaScript中实现相机的Tap To Focus(点击对焦)功能?
Web自定义相机点击对焦功能实现方案
实现点击对焦依赖MediaStream Image Capture API,仅支持后置环境摄像头,适配主流现代浏览器(Chrome 60+、Safari 14.1+、Edge 79+),实现步骤如下:
步骤1:获取视频流与摄像头轨道
你的初始代码仅完成了摄像头权限申请,需要先提取视频轨道并校验对焦能力:
const permissionConstraints = { video: { width: { exact: 1280 }, height: { exact: 1280 }, aspectRatio: { ideal: 1 }, facingMode: 'environment' } }; let videoTrack, imageCapture; // 视频预览元素,你需要在页面中提前放置<video id="preview" autoplay playsinline></video> const previewEl = document.getElementById('preview'); navigator.mediaDevices.getUserMedia(permissionConstraints).then((stream) => { // 绑定流到预览元素 previewEl.srcObject = stream; // 提取视频轨道 videoTrack = stream.getVideoTracks()[0]; imageCapture = new ImageCapture(videoTrack); // 校验设备是否支持对焦功能 const capabilities = videoTrack.getCapabilities(); if (!capabilities.focusMode?.includes('single-shot')) { console.warn('当前设备不支持手动对焦'); return; } })
步骤2:绑定点击事件实现对焦
需要将点击位置转换为摄像头要求的归一化坐标(范围0-1,左上角为[0,0],右下角为[1,1]),再触发对焦:
previewEl.addEventListener('click', async (e) => { if (!videoTrack || !imageCapture) return; // 计算点击位置相对于预览元素的比例(归一化) const rect = previewEl.getBoundingClientRect(); const x = (e.clientX - rect.left) / rect.width; const y = (e.clientY - rect.top) / rect.height; try { // 先设置对焦区域,再触发单次对焦 await videoTrack.applyConstraints({ advanced: [{ focusMode: 'single-shot', focusPoint: { x, y } }] }); // 对焦完成后可按需恢复自动对焦 setTimeout(() => { videoTrack.applyConstraints({ advanced: [{ focusMode: 'continuous' }] }); }, 2000); } catch (err) { console.error('对焦失败:', err); } });
注意事项
- 部分安卓设备对焦点参数命名为
pointsOfInterest而非focusPoint,如果上述代码不生效可以替换对焦区域配置:advanced: [{ focusMode: 'single-shot', pointsOfInterest: [{ x, y }] }] - 必须在
HTTPS环境下运行,本地开发localhost也可以正常调用相关API - iOS Safari需要给video标签添加
playsinline属性才能正常触发对焦能力
内容的提问来源于stack exchange,提问作者jeel faldu
相关产品推荐
相关产品推荐

