上传裁剪用到哪些文件

html 里按这个顺序引:

弹窗包在 .tailoring-container 里,真正动手裁的是 #tailoringImg,裁完画到 #finalImg。选图走隐藏的 #chooseImg,外面包一层 label.choose-btn,点「选择图片」等于点文件框。
维护这一页时入口就是 index.html,不要再套一层别的壳把相对路径打乱,css 和 js 会一起 404。
页面骨架

.l-btn 用 padding: 5px 10px 撑开,不要写死宽高;可点的地方加上 cursor: pointer。accept 写成 image/jpeg,image/png,image/jpg 不是合法 MIME,有的浏览器会忽略。
如何打开和关闭裁剪的弹窗
弹窗默认 display: none。点 #replaceImg 调 openTailor,里面 show() 之后立刻算一次位置。说白了:隐藏时宽高按 0 算,先显示再居中,否则弹窗会贴在左上角。这坑我见过不止一次。
关掉有三条路:点遮罩 .black-cloth、点右上角 .close-tailoring、裁完点确定。三条都走 closeTailor 里的 hide(),不要再用 toggle 来回切,连点两次「更换图片」会把窗关没。
事件挂在 body 上委托,弹窗是后显示的也点得到:

窗口拉大拉小走 resize。宽大于 768 时左右都居中;窄于 768 时 left: 0,弹窗拉满宽,右侧预览在 css 里藏掉,裁剪区全宽。
选图不能直接把 input.files[0] 塞给 cropper,要先 FileReader.readAsDataURL,读完再 cropper("replace", dataUrl, false)。第三个参数 false 是按高度适配、尽量不失真。
裁剪比例、预览和旋转功能如何做
cropper 挂在 #tailoringImg 上。本例 aspectRatio 写成 1 / 1,框永远是正方形,头像、圆形展示都吃这套。横幅要 16:9 就改成 16 / 9,证件照要 3:4 就改成 3 / 4。
preview: ".previewImg" 会把裁框里的画面同步到所有带这个类的节点。页面上一个 .square、一个 .circular,都加了 previewImg,一个直角一个圆角,拖框的时候两边一起动。右侧预览固定 200×200,多出来的被 overflow: hidden 切掉。
autoCropArea: 0.5 是第一次出现时裁框占图的比例,0 到 1。本例写成 0.5 方便一上来就看到四周还能拖;业务里觉得框太小,改成 0.8 更接近整张图。

guides: false 不画九宫格虚线。cropBoxMovable、cropBoxResizable 管框能不能挪、能不能拉。zoomable: false 配 zoomOnWheel: false,滚轮不会把图缩没;手机上 zoomOnTouch: true 仍允许双指缩放。
底下三个按钮:
1、复位:cropper("reset"),图和框回到选图刚进来那一下。
2、旋转:cropper("rotate", 45),每次顺时针 45 度,狂点就转圈。
3、换向:cropper("scaleX", -1) 水平翻转,再用 scaleX(1) 翻回来。flagX 记当前朝哪边,不然连点会停在同一面干瞪眼。

我第一次看 scaleX 也卡了一下:它不是旋转,是镜子那样左右对调。竖着拍的手机图,人脸在左边、要镜像到右边,走的就是这个,不是 rotate。
裁完的图怎么显示到页面上
点确定时先看 #tailoringImg 有没有 src。没选图就点,getCroppedCanvas() 会拿到空,再调 toDataURL 会崩。有图才导出:

getCroppedCanvas() 按当前裁框画出一张 canvas,toDataURL("image/png") 变成 data URL,塞进 #finalImg 的 src。页面上 .final-box 是 320×320 的方框,图 width: 100% 铺满。1:1 裁出来的图丢进去不会被压扁;外面若再套一层 border-radius: 50%,就是圆头像。
导出用 png 是为了透明边。体积要更小可以改成 image/jpeg,第二个参数写质量,比如 cas.toDataURL("image/jpeg", 0.9)。
确定之后 closeTailor() 把弹窗藏掉,结果留在 #finalImg 上。到这一步还只是本地预览,没交给后台。
如何对接到真实项目中
裁完只把 data URL 塞进 #finalImg 够看效果。接到项目里还要把文件交给后台。toDataURL 字符串偏长,我更愿意用 toBlob 塞进 FormData,跟普通文件上传一条路。
jQuery 这套建议用 Layui 做提示,具体按实际项目来定。没选图、接口失败都走 layer.msg,不要 alert。
res.code、字段名、上传地址换成项目里的约定。下面这份把开关弹窗、选图、裁剪和上传写在一起,用它覆盖 crop.js,页面结构仍用前面的 html。

processData、contentType 必须是 false,否则 jQuery 会把 FormData 拆成字符串,后台收不到文件。成功后用接口返回的 URL 写 #finalImg,不要继续用本地 data URL,刷新页面图还在。
比例只改 aspectRatio;预览大小改 .previewImg 的宽高;旋转角度改 rotate 的第二个参数。弹窗宽高在 ImgCropping.css 的 .tailoring-content,现在是 768×560。