前端开发过程中相信大家应该都遇到过图片上传的问题,尤其是遇到千人千图千种规格,那最好的解决方法就是在上传过程中设定一定规格的裁剪功能,这样更能达到预期的效果。所以今天写一篇关于cropper.js图片裁剪插件的用例。当然,今天是基于它的V1版本的v1.5.12做的案例,cropper目前最新的是V2(Beta)版本,后续也会做一个关于v2版的用例。
本次的用例主要是用于移动端图片选择,以及相机拍照后的图片选择裁剪功能。详细代码请往下看,具体效果图请看文章末尾。
安装
安装方法有两种,npm安装和浏览器直接引入方法:
npm install cropper jquery
或者:
<link rel="stylesheet" href="css/cropper.css">
<script src="js/jquery.js"></script>
<script src="js/cropper.js"></script>
// 或者用cdn引入的方法
<link rel="stylesheet" href="https://unpkg.com/cropperjs/dist/cropper.css">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://unpkg.com/cropperjs/dist/cropper.js"></script>
用法
在所有依赖引入后,就可以完全放心的使用它了。它的使用规则是通过new一个Cropper对象,然后里面可以传两个参数image,options。其中第一个参数为你要包装的图像或画布元素,第二个参数为cropper内置的一些属性设置及方法。
new Cropper(image,options)
下面是完整的移动端裁剪案例源码:
html
<div class="upload-box">
<!-- 回显上传图片 -->
<div class="upload-img-box">
<img src="img/2.png" alt="">
</div>
<div class="upload-btn">
<button type="button" class="btn-box">相机(图片)</button>
<input id="select-box" type="file" style="display: none;" />
</div>
</div>
<!-- 裁剪图片弹窗 -->
<div class="module-cropper" style="display: none;">
<div class="module-cropper-content">
<div class="module-cropper-bg">
<!-- 包装图像或画布元素 -->
<div class="cropper-img-box">
<img id="cropperImg" src="img/1.jpg" />
</div>
</div>
<div class="module-cropper-btn">
<span onclick="cancelCropper()">取消</span>
<span onclick="rotateCropper()">旋转</span>
<span onclick="cropperSucess()">完成</span>
</div>
</div>
</div>
CSS
* {
margin: 0;
padding: 0;
}
body {
max-width: 750px;
margin: 0 auto;
}
.upload-box {
width: 100%;
overflow: hidden;
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%,-50%);
}
.upload-img-box {
width: 80%;
margin: 20px auto;
padding: 20px;
box-sizing: border-box;
border: 1px solid #ddd;
border-radius: 5px;
}
.upload-img-box img {
width: 100%;
}
.upload-btn {
width: 80%;
margin: 0 auto;
overflow: hidden;
text-align: center;
}
.btn-box {
width: 120px;
background: #2DCEC2;
line-height: 35px;
text-align: center;
color: #fff;
border-radius:5px;
border:none;
outline-style: none;
}
.module-cropper {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
background: rgba(0,0,0,.8);
}
#cropperImg {
max-width: 100%;
}
.module-cropper-content {
width: 90%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.module-cropper-bg {
width: 100%;
height: 80vh;
overflow: hidden;
position: relative;
}
.cropper-img-box {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
/* width: 100%; */
}
.module-cropper-btn {
width: 100%;
overflow: hidden;
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 5vh;
}
.module-cropper-btn span {
color: #fff;
font-size: 13px;
}
JS
const image = document.getElementById('cropperImg');// 包装图像或画布元素
let options = {
aspectRatio: 16 / 9, // 裁剪框的宽高比,默认NAN,可以随意改变裁剪框的宽高比
viewMode:0, // 0,1,2,3
dragMode:'move', // 'crop': 可以产生一个新的裁剪框 'move': 只可以移动 'none': 什么也不处理
// preview:".small", // 添加额外的元素(容器)以供预览
responsive:true, //在调整窗口大小的时候重新渲染cropper,默认为true
restore:true, // 调整窗口大小后恢复裁剪的区域。
checkCrossOrigin:true, //检查当前图像是否为跨域图像,默认为true
modal:true, // 显示图片上方的黑色模态并在裁剪框下面,默认为true
guides:false, // 显示在裁剪框里面的虚线,默认为true
center:true, // 裁剪框在图片正中心,默认为true
highlight:true, // 在裁剪框上方显示白色的区域,默认为true
background:false, // 显示容器的网格背景(即马赛克背景),默认为true,若为false,这不显示
autoCrop:true, // 当初始化时,显示裁剪框,改成false裁剪框消失需要你重绘裁剪区域,默认为true
autoCropArea:0.8, // 定义自动裁剪面积大小(百分比)和图片进行对比,默认为0.8
movable:true, // 是否允许可以移动后面的图片,默认为true(但是如果dragMode为crop,由于和重绘裁剪框冲突,所以移动图片会失效)
rotatable:true, // 是否允许旋转图像,默认为true
scalable:true, // 是否允许缩放图像,默认为true
zoomable:true, // 是否允许放大图像,默认为true
zoomOnTouch:true, // 是否可以通过拖动触摸来放大图像,默认为true
wheelZoomRatio:0.1, // 用鼠标移动图像时,定义缩放比例,默认0.1
cropBoxMovable:true, // 是否通过拖拽来移动剪裁框,默认为true
cropBoxResizable:true, // 是否通过拖动来调整剪裁框的大小,默认为true
toggleDragModeOnDblclick:true, // 当点击两次时可以在“crop”和“move”之间切换拖拽模式,默认为true
crop: function(event) {
}
}
let cropper = new Cropper(image,options); // 初始化cropper对象
文中需要用的一些js方法
// 调起input(相机图片)事件
$(".btn-box").click(function(){
$('#select-box').click()
})
// input事件
$('#select-box').on('change',function(e){
let file = e.target.files[0];
let reader = new FileReader();
reader.onload = function(evt) {
let replaceSrc = evt.target.result;
// 更换cropper的图片
cropper.replace(replaceSrc, false);
}
reader.readAsDataURL(file);
$(".module-cropper").show();
})
// 取消弹窗
function cancelCropper(){
$(".module-cropper").hide();
}
// 旋转图片
function rotateCropper(){
cropper.rotate(90);
}
// 图片选择完成
function cropperSucess(){
let baseSrc = cropper.getCroppedCanvas().toDataURL('image/jpeg', 0.7);
//console.log(baseSrc); // base64格式
$(".module-cropper").hide();
$(".upload-img-box").find("img").attr("src",baseSrc)
}
上面就是完整案例的代码,效果图可以看文章末尾。
cropper常用参数及方法解析
options
上面案例中设置了一些cropper常用的属性,当然它还有很多属性(类型包括string,Number,String,Function)等,下面罗列一些内置的属性即属性值:
aspectRatio: 16 / 9, // 裁剪框的宽高比,默认NAN,可以随意改变裁剪框的宽高比
viewMode:0, // 0,1,2,3
dragMode:'move', // 'crop': 可以产生一个新的裁剪框 'move': 只可以移动 'none': 什么也不处理
preview:".small", // 添加额外的元素(容器)以供预览
responsive:true, //在调整窗口大小的时候重新渲染cropper,默认为true
restore:true, // 调整窗口大小后恢复裁剪的区域。
checkCrossOrigin:true, //检查当前图像是否为跨域图像,默认为true
modal:true, // 显示图片上方的黑色模态并在裁剪框下面,默认为true
guides:false, // 显示在裁剪框里面的虚线,默认为true
center:true, // 裁剪框在图片正中心,默认为true
highlight:true, // 在裁剪框上方显示白色的区域,默认为true
background:false, // 显示容器的网格背景(即马赛克背景),默认为true,若为false,这不显示
autoCrop:true, // 当初始化时,显示裁剪框,改成false裁剪框消失需要你重绘裁剪区域,默认为true
autoCropArea:0.8, // 定义自动裁剪面积大小(百分比)和图片进行对比,默认为0.8
movable:true, // 是否允许可以移动后面的图片,默认为true(但是如果dragMode为crop,由于和重绘裁剪框冲突,所以移动图片会失效)
rotatable:true, // 是否允许旋转图像,默认为true
scalable:true, // 是否允许缩放图像,默认为true
zoomable:true, // 是否允许放大图像,默认为true
zoomOnTouch:true, // 是否可以通过拖动触摸来放大图像,默认为true
wheelZoomRatio:0.1, // 用鼠标移动图像时,定义缩放比例,默认0.1
cropBoxMovable:true, // 是否通过拖拽来移动剪裁框,默认为true
cropBoxResizable:true, // 是否通过拖动来调整剪裁框的大小,默认为true
toggleDragModeOnDblclick:true, // 当点击两次时可以在“crop”和“move”之间切换拖拽模式,默认为true
minCanvasHeight:0, // canvas的最小高度,默认为0
minCanvasWidth:0, // canvas的最小宽度,默认为0
minContainerHeight:100, // 容器的最小高度,默认为100
minContainerWidth:200, // 容器的最小宽度,默认为200
minCropBoxWidth:0, // 裁剪层的最小宽度,默认为0
minCropBoxHeight:0,// 裁剪层的最小高度,默认为0
options类型为Function的属性:
ready:function(){}, // 插件准备完成执行的函数(只执行一次)
crop:function(){}, // 剪裁框发生变化执行的函数
zoom:function(){}, // 剪裁框缩放的时候执行的函数
cropstart:function(){}, // 剪裁框开始移动执行的函数
cropmove:function(){}, // 剪裁框移动时执行的函数
cropend:function(){}, //剪裁框移动结束执行的函数
常用的一些Methods
replace(url[, onlyColorChanged])
// 替换图像的src并重新构建cropper,第一个参数为要替换的新的图片地址,第二个参数onlyColorChanged类型为Boolean,默认为false,如果只是改变颜色,而不是大小,那么cropper只需要改变所有相关图像的src,不需要重新构建cropper。这可以用于应用过滤器。
let cropper = new Cropper(image,options);
cropper.replace(replaceSrc, false);
crop()
// 手动显示裁剪框
let cropper = new Cropper(image,options);
cropper.cropper({
autoCrop: false, //关闭自动显示裁剪框
ready: function () {
$(this).cropper('crop');
}
});
reset()
// 将图像和裁剪框重置为初始状态
let cropper = new Cropper(image,options);
cropper.cropper('reset');
clear()
// 清除裁切框
let cropper = new Cropper(image,options);
cropper.clear();
destroy()
// 销毁cropper并从图像中删除整个cropper
let cropper = new Cropper(image,options);
cropper.cropper('destroy');
move(offsetX[, offsetY])
// 使用相对偏移量移动图像(裁切框不移动)
// offsetX–类型:Number;在水平方向上移动(px)
// offsetY –类型:Number;在垂直方向上移动(px);如果不存在,其值和offsetX相同;
let cropper = new Cropper(image,options);
cropper.cropper('move', 1, 0);
moveTo(x[, y])
// 将画布(图像包装器)移动到一个绝对点
// X–类型:Number;画布canvas距离left的值;
// Y –类型:Number;画布canvas距离top的值;如果不存在,其值和X相同;
let cropper = new Cropper(image,options);
cropper.cropper('moveTo', 100, 10);
zoom(ratio)
// 放大图片,并使用相对比例。(裁切框不变化)
let cropper = new Cropper(image,options);
cropper.cropper('zoom', 0.1);
rotate(degree)
// 旋转图像以一定的角度
// 向右旋转 (degree > 0);向左旋转 (degree < 0);
let cropper = new Cropper(image,options);
cropper.cropper('rotate', 45);
getData([rounded])
// 输出最终裁剪的区域位置和大小数据(根据原始图像的自然大小
// rounded 类型:Boolean 默认:false;设置true可以获取其所有数据;
// 返回的数据类型:Object;
// - x裁切框距离左边的距离
// - y裁切框距离顶部的距离
// - width裁切框的宽度
// - height裁切框的高度
// - rotate裁切框的旋转的角度
// - scaleX缩放图像的横坐标
// - scaleY缩放图像的纵坐标
let cropper = new Cropper(image,options);
cropper.cropper('getData', true)
getImageData()
// 输出图像image位置、大小和其他相关数据
// - leftimage距离左边的距离
// - topimage距离顶部的距离
// - widthimage的宽度
// - heightimage的高度
// - naturalWidth image的原始宽度
// - naturalHeight image的原始高度
// - aspectRatio image的纵横比
// - rotateimage的旋转的角度
// - scaleX缩放图像的横坐标
// - scaleY缩放图像的纵坐标
let cropper = new Cropper(image,options);
cropper.cropper('getImageData')
上面是我们应该能用到的大部分方法及内置属性了,只能说cropper真的很强大,几乎包含了我们实际开发中所需要的内容。下面是开头提到的案例截图,需要的可以自取源码。
主页面,上传按钮及裁剪完成后回显内容
裁剪过程弹窗
https://mengnn.cn/nvm%E4%B9%8BNodeJS%E7%89%88%E6%9C%AC%E7%AE%A1%E7%90%86%E5%B7%A5%E5%85%B7/