先给你们看一下最终效果。css
大多数功能都是由Cropper.js封装好的,调整并制做了:ios
一开始制做这个需求思路有两个,使用canvas原生或者寻找现成的库,对比了一番以为canvas实现时间耗费较长,且秉承着不重复造轮子的原则(实际上是菜),决定使用Cropper.js。官方封装了不少参数、方法、事件,上手容易,文档阅读体验较好、并且便于扩展。git
Cropper.js官方仓库+文档:github.com/fengyuanche…github
Installationnpm
npm install cropperjs
复制代码
咱们实现上述功能须要的核心HTMl部分只有:canvas
<!-- 1.一个用于获取上传文件的input,type="file",而且监听onchange事件 -->
<input
type="file"
accept="image/*"
id="imgReader"
onchange="loadingImg"
>
<!-- 2.一个用于给Cropper.js覆盖使用的img -->
<img id="cropImg">
<!-- 3.两个用于预览的div -->
<div class="previewText">裁剪预览</div>
<div class="previewBox"></div>
<div class="previewBoxRound"></div>
复制代码
首先先将用于上传的input隐藏起来,咱们并不须要它的样式axios
.inpuFile{
display: none;
}
复制代码
而后给你项目中的某个按钮添加一个点击事件,而且调用后端
function uploadImg(){
document.querySelector('#imgReader').click()
},
复制代码
便可打开上传文件的窗口,而后选择你须要的图片 浏览器
上传文件成功后,会触发onchange事件,调用loadingImg()bash
//引入Cropper.js
import 'cropperjs/dist/cropper.css';
import Cropper from 'cropperjs';
let CROPPER //建立一个cropper的全局对象
function loadingImg(eve){
//读取上传文件
let reader = new FileReader();
if(event.target.files[0]){
//readAsDataURL方法能够将File对象转化为data:URL格式的字符串(base64编码)
reader.readAsDataURL(eve.target.files[0]);
reader.onload = (e)=>{
let dataURL = reader.result;
//将img的src改成刚上传的文件的转换格式
document.querySelector('#cropImg').src = dataURL;
const image = document.getElementById('cropImg');
//建立cropper实例-----------------------------------------
CROPPER = new Cropper(image, {
aspectRatio: 16 / 16,
viewMode:0,
minContainerWidth:500,
minContainerHeight:500,
dragMode:'move',
preview:[ document.querySelector('.previewBox'),
document.querySelector('.previewBoxRound')]
})
}
}
}
复制代码
new Cropper(element[, options])
第一个参数:element
第二个参数(可选):
咱们须要用到的参数有:
{
aspectRatio: 16 / 16, //固定裁剪框的比例(横/竖),此处16/16则固定为正方形
minContainerWidth:500, //容器最小的宽度
minContainerHeight:500, //容器最小的高度
dragMode:'move', //设置裁剪框为能够移动
preview:[ document.querySelector('.previewBox'), //设置咱们须要添加实时预览的地方
document.querySelector('.previewBoxRound')]
//更多参数请参照官方仓库...咱们这里用不着
}
复制代码
先忽略实时预览,完成到这里咱们就可看到咱们上传的图片以及裁剪功能:
上面建立cropper的时候,咱们在选项中添加了
preview:[ document.querySelector('.previewBox'),
document.querySelector('.previewBoxRound')]
复制代码
preview就是用来设置咱们须要实时预览的地方,可是设置完成以后要给上述的两个div添加一下样式,才能够正常显示
.previewBox,.previewBoxRound{
box-shadow: 0 0 5px #adadad;
width: 100px;
height: 100px;
margin-top: 30px;
overflow: hidden; /*这个超出设置为隐藏很重要,不然就会整个显示出来了*/
}
.previewBoxRound{
border-radius: 50%; /*设置为圆形*/
}
复制代码
function GetData(){
//getCroppedCanvas方法能够将裁剪区域的数据转换成canvas数据
CROPPER.getCroppedCanvas({
maxWidth: 4096,
maxHeight: 4096,
fillColor: '#fff',
imageSmoothingEnabled: true,
imageSmoothingQuality: 'high',
}).toBlob((blob) => {
//而后调用浏览器原生的toBlob方法将canvas数据转换成blob数据
//以后就能够愉快的将blob数据发送至后端啦,可根据本身状况进行发送,我这里用的是axios
const formData = new FormData();
// 第三个参数为文件名,可选填.
formData.append('croppedImage', blob/*, 'example.png' */);
let config = {
headers:{'Content-Type':'multipart/form-data'}
}
this.$axios.post(flow_mission_UploadFile(),param,config)
.then((response)=>{
console.log(response)
})
.catch((err)=>{
console.log(err)
})
})
}
复制代码
裁剪部分默认会根据上传图片的大小进行改变
//在new Cropper的参数中设置
minContainerWidth:500, //容器最小的宽度
minContainerHeight:500, //容器最小的高度
复制代码
#cropImg{
height: 450px;
width: 450px;
box-shadow: 0 0 5px #adadad;
}
复制代码
再次上传不一样图片的时候,仍是出现原来的图片,只须要在上传文件的时候,对以前存在的CROPPER进行摧毁就能够了
function uploadImg(){
document.querySelector('#imgReader').click()
if(CROPPER){
CROPPER.destroy()
}
},
复制代码
这里列举几个我这里用到的
还有不少其余方法和事件能够自行参照仓库,一个普通的上传头像功能就这样应该够用了!这里就不一一列举啦
若是以为写得有很差的地方请多多指教,喜欢的话能够点个赞哈!