直接用<img>标签无法裁剪,需容器+CSS或Canvas实现;CSS方案用overflow:hidden和object-fit:cover实现视觉裁剪;Canvas方案用drawImage()九参数像素级裁剪,需准确映射鼠标坐标到原图像素。

直接用 <img> 标签无法实现“裁剪”——它只负责加载和缩放,不控制显示区域。真正可控的裁剪必须借助容器限制 + CSS 截断 或 Canvas 像素级操作。
用 CSS 容器 + object-fit 和 overflow 模拟裁剪
这是最轻量、无需 JS 的方案,适合固定比例预览(如头像、卡片图),但不支持用户拖选区域。
-
overflow: hidden是关键:父容器设固定宽高,子<img>超出部分会被裁掉 -
object-fit: cover让图片等比缩放填满容器,居中截取 —— 这才是“视觉裁剪”的核心 - 别用
width/height直接拉伸<img>,会变形;用max-width: 100%+height: auto保比例 - 示例结构:
<div style="width: 200px; height: 200px; overflow: hidden;"> <img src="photo.jpg" style="width: 100%; height: 100%; object-fit: cover;"> </div>
用 <canvas> 实现像素级可交互裁剪
用户要拖拽选区、缩放、实时预览?必须走 Canvas 路线。核心是 drawImage() 的 9 参数重载形式,它能从原图任意位置截取一块再画到 canvas 上。
- 错误做法:在 canvas 上画完整图后,用
clip()再裁 ——clip()只影响后续绘制,对已画内容无效 - 正确流程:先算出用户选区在原图中的
sx,sy,sWidth,sHeight,再调用ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) - 注意坐标映射:用户在 canvas 上拖出的矩形是显示尺寸,需按原图与 canvas 图像的缩放比反推真实像素坐标
- 常见坑:
img.naturalWidth和img.naturalHeight才是原图尺寸,img.width/img.height是当前显示尺寸,别混用
drawImage() 的 9 参数调用最容易写错的三个地方
这行代码是裁剪逻辑的命脉,参数顺序和含义必须刻进肌肉记忆:
立即学习“前端免费学习笔记(深入)”;
-
sx,sy:从原图哪个像素点开始裁(左上角为 0,0),不是 canvas 上的坐标 -
sWidth,sHeight:裁多大一块(单位:像素),不是百分比,也不是 CSS 像素 -
dx,dy,dWidth,dHeight:这块裁出来的东西,画到 canvas 的哪个位置、缩放到多大 —— 这里可以做二次缩放,比如把 300×300 的裁剪区画成 150×150 显示
真正的难点不在画布上画什么,而在用户拖选时如何把鼠标坐标实时、准确地映射回原图像素 —— 缩放、居中、容器 padding、设备像素比(window.devicePixelRatio)全得参与计算,漏一个就会偏移。


















