独书先生 Menu

Cropper.js 实现上传图片裁剪功能 | 支持移动端

分类:Web

需求分析:

实现上传图片文件,弹窗对图片进行自定义裁剪,裁剪完后能够保存裁剪完后新的图片,以发送到服务器。具体场景比如换头像功能,裁剪成正方形或圆形,上传一张新的产品图裁剪成长方形等。

实现思路:

点击input [file]上传图片,监听这个input的 change事件,实例化FileReader读取图片的src地址传给cropper.js裁剪框插件,插件内自动实现裁剪功能,后使用cropper.js的getCroppedCanvas方法得到裁剪后的图片url,传给服务器存储,再显示到前台。

实例解析:

实现一个上传头像并裁剪的功能,页面首先已存在一个头像,现在点击这个头像或文字,弹出一个裁剪框包含刚选中的本地图片,裁剪后点击保存即保存到页面上(这里做演示,未作后台处理,后面代码处会标注),取消的话就隐藏弹出框。本实例主要针对移动端设计。

 

效果演示:

HTML:

一个div放置原头像,input等,另一个隐藏的div放置裁剪框,在上传图片后显示,点击保存或取消可隐藏

<div class="userInfo-pic"><a>
<input id="imgPicker" type="file" />
<img id="userHeadPic" src="http://p31rkzyhv.bkt.clouddn.com/lufei.jpg" alt="" /></a>点击上传 

</div>
<!--更换头像弹出框-->
<div class="mask editImg">

<!--放置可裁剪头像的容器-->
<div class="container"><img id="userEditImg" /></div>
<div class="editBtn"><button id="saveImg">保存</button><button id="cancleImg">取消</button></div>
</div>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropper/3.1.4/cropper.min.js"></script>

CSS:

重点实现把input [file]标签设置大小能盖住后面的图片和文字,并设置透明,这样点击头像或者“点击上传”文字的时候,实际上点击的是这个input,就实现了不显示input,但是却点击的input。

html{
font-size:62.5%;
}
/*上传图片区域*/
.userInfo-pic{
padding:4%;
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
display: -ms-flexbox; /* TWEENER - IE 10 */
display: -webkit-flex; /* NEW - Chrome */
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
justify-content:center;
align-items:Center;
background:#3fd187;
}
.userInfo-pic a{
position: relative;
color:#fff;
text-align: center;
width:8rem;
}
/*input覆盖住后面的图片和文字*/
.userInfo-pic input{
opacity:0;
filter:alpha(opacity=0);
height: 8rem;
width: 8rem;
position: absolute;
top: 0;
left: 0;
margin:0 auto;
z-index: 9;
}
.userInfo-pic img{
width:5rem;
height:5rem;
border-radius:103%;
}

/*弹窗蒙版*/
.mask{
display:none;
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
background: rgba(0,0,0,0.3);
z-index:2;
}

.editImg{
z-index: 1;
}
/*裁剪图片位置*/
.editImg>div:first-of-type{
position: absolute;
top:20%;
left:0;
width:100%;
height:60%;
}
.editImg>div:last-of-type{
text-align: center;
position: absolute;
bottom:2%;
left:0;
width:100%;
}
.editImg button{
margin:0 10%;
width:30%;
height:2.7rem;
background:#3fd187;
border-radius:0.5rem;
}
.editImg img{
max-width:100%;
}

JS:

这里使用FileReader获取图片的地址,特别注意一个顺序问题,先把地址赋值给剪辑框的img元素,然后再初始化cropper插件,显示裁剪框(如果赋值前就初始化cropper,后面图片地址传不到裁剪框里)。裁剪后,图片通过cropper(‘getCroppedCanvas’)获取地址,并转换成 base64 dataURL用于传输,注意下面的演示示例仅仅把获取到的图片显示在当前的头像处用于看到效果,实际应用中应该用Ajax传输到后台,更改头像的图片链接地址,再传回来当前页面用于显示。

$(document).ready(function(){
/*上传头像功能,使用Cropper.js图片裁剪插件*/
var $imgPicker = document.querySelector("#imgPicker");
var $userEditImg = document.querySelector("#userEditImg");

/*监听上传图片*/
$imgPicker.addEventListener('change',function(e){
$(this).attr("disabled","disabled");
//实例化一个FileReader
var reader = new FileReader();
reader.onload = function(e){
//当reader加载时,把图片文件的地址赋值给剪辑框的img元素
$("#userEditImg").attr('src',reader.result);

//cropper插件显示剪辑框
$(".container>img").cropper({
aspectRatio:1/1,
crop:function(e){
console.log(e.x);
}
});
};
//读取选中的图片,并转换成dataURL格式
reader.readAsDataURL(this.files[0]);
/*显示弹窗*/
$(".editImg").show();
},false);

/*点击保存按钮,可获取到裁剪后的图片,用于传输到后台存储并显示到头像框中*/
$("#saveImg").click(function(){
var dataURL = $(".container>img").cropper('getCroppedCanvas').toDataURL('image/png');
$("#userHeadPic").attr("src",dataURL);/*简易显示,连接数据库后改为从后台获取*/
$(".container>img").cropper('destroy');
$(".editImg").hide();
$("#imgPicker").removeAttr("disabled");

});
/*点击取消,隐藏弹窗*/
$("#cancleImg").click(function(){
$(".container>img").cropper('destroy');
$(".editImg").hide();
$("#imgPicker").removeAttr("disabled");
});

});

Demo

配套组件:
初始通用HTML组件:点击上传图片样式
如下:

upload_pic

具体扩展及详细信息,可参见其他优秀博文:

cropper.js 实现HTML5 裁剪图片并上传

感谢!