矩形选框实时预览核心是“视觉反馈+坐标映射+双画布协同”:用绝对定位div实现轻量拖拽选框,鼠标坐标经缩放比换算为原始像素坐标,叠加canvas遮罩突出选区,最终用drawimage九参数精准裁剪输出。

矩形选框的实时预览效果,核心是“视觉反馈+坐标映射+双画布协同”,不是直接裁剪,而是让用户看到裁剪区域在原图上的准确位置和范围。
用 DOM 元素叠加实现轻量级拖拽选框
不依赖 canvas 绘制选框本身,而是用一个带边框的 <div> 叠加在展示画布上方。它响应鼠标事件、可拖动缩放,样式可控,性能好,且天然支持 CSS 过渡动画。
<ul>
<li>给该 div 设置 <code>position: absolute,父容器为相对定位的画布容器
mousedown 判断点击位置是否在图像区域内(可用 getBoundingClientRect() 获取画布视口坐标)mousemove 时动态更新 div 的 left、top、width、height
box-sizing: border-box 和半透明背景/虚线边框,增强视觉识别度将鼠标坐标正确映射到原始图像像素空间
展示画布通常做了缩放(比如限制最大宽高),而裁剪必须基于原图真实像素。用户拖出的选框坐标是视口坐标,需按比例换算成自然尺寸下的 sx、sy、sWidth、sHeight。
- 计算缩放比:
scale = Math.min(containerWidth / img.naturalWidth, containerHeight / img.naturalHeight) - 鼠标位置减去画布左上偏移后,再除以
scale,得到原始图像中的像素坐标 - 选框宽高同样除以
scale,并做边界校验(不能超出0 ~ naturalWidth/Height)
在展示层同步绘制半透明遮罩与选框轮廓
仅靠 DOM 选框不够直观,建议在展示画布上叠加一层 Canvas 遮罩,突出显示选区外区域,让选框更醒目。
- 创建一个与展示画布等大的临时 canvas,置于图像下方或上方(z-index 控制)
- 用
ctx.fillStyle = 'rgba(0,0,0,0.6)'填满全画布 - 调用
ctx.clearRect(x, y, width, height)挖空选框区域——注意这里用的是展示层坐标 - 再用
strokeRect或自定义路径描边,强化选框轮廓
预览裁剪结果无需重绘整图,只需局部提取
当用户确认裁剪,不要把整个展示画布内容导出,而是用原始图像 + 映射后的像素坐标,调用 drawImage 九参数形式精确截取。
- 新建一个离屏 canvas,宽高设为裁剪区域的原始像素尺寸(非展示尺寸)
- 调用
cCtx.drawImage(img, sx, sy, sWidth, sHeight, 0, 0, sWidth, sHeight) - 用
toDataURL或toBlob输出,保证清晰度不因缩放损失 - 该步骤可即时执行,作为“实时预览”的最终输出验证











