基于vue-cropper的上传裁剪后的头像
No.1
需求
上传头像
图片格式为jpg/jpge || png,大小为1M以内
上传头像必须进行裁剪
No.2
思路
选择图片作为头像。
上传图片前进行判断,符合要求就进行下一步,不符合要求,则提示错误。
符合要求后,到裁剪页面,进行图片裁剪。
裁剪完成后,在进行上传图片。
显示上传成功后的头像。
以上,就是上次头像的大概思路了。接下来,就是如何开发。
No.3
开发
安装vue-cropper
vue-cropper的官网:
https://github.com/xyxiao001/vue-cropper
在项目根目录打开cmd输入安装指令:
npm install vue-cropper
封装vue-cropper
安装成功后,因为我是封装成一个组件,所以,我先创建一个vue文件,用于封装cropper组件。
template模板内容
<!--
裁剪图片 组件
传参:
1、show.sync 是否显示 Boolean false
2、url 上传文件路径 String
3、callback 返回裁剪后的图片路径 function(data)
4、close 右上角关闭按钮 function()
5、shadebackground 更改遮罩层的背景颜色
6、shadeopacity 更改遮罩层的透明度
-->
<template>
<el-dialog title="裁剪图片" :visible.sync="visible" @close="close">
<div id="cropper">
<VueCropper
ref="cropper"
:img="src"
:outputSize="option.outputSize"
:outputType="option.outputType"
:canMove="option.canMove"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
:original="option.original"
:infoTrue="option.infoTrue"
:centerBox="option.centerBox"
:canMoveBox="option.canMoveBox"
:canScale="option.canScale"
></VueCropper>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="startCrop()">确 定</el-button>
</span>
</el-dialog>
</template>
javascript内容
option是剪裁插件的属性配置,具体更多含义查看官网介绍
<script>
import { VueCropper } from "vue-cropper";
export default {
props: {
show: {
type: Boolean,
default: false
},
src: {
type: String,
default: ''
},
shadebackground: {
type: String,
default: "#000"
},
shadeopacity: {
type: String,
default: ".5"
}
},
components: { VueCropper },
data() {
return {
option: {
outputSize: 1, // 裁剪生成图片的质量 0.1 - 1
outputType: "jepg", // 裁剪生成图片的格式 jpeg || png || webp
canScale: true, // 图片是否允许滚轮缩放 默认true
autoCrop: true, // 是否默认生成截图框 默认false
canMove: true, //上传图片是否可以移动 默认true
autoCropWidth: 367, //默认生成截图框宽度 容器的80% 0~max
autoCropHeight: 280, //默认生成截图框高度 容器的80% 0~max
fixedBox: true, //是否开启截图框宽高固定比例
original: false, // 上传图片按照原始比例渲染 false true | false
infoTrue: true, // 为展示真实输出图片宽高 false 展示看到的截图框宽高 false true | false
centerBox: true, // 截图框是否被限制在图片里面 false true | false
canMoveBox: false, //截图框能否拖动 true true | false
},
visible: this.show,
modal: {}
};
},
methods: {
// 开始截图
startCrop() {
let othis = this;
othis.$refs.cropper.getCropData(function(data){
let arr = data.split(','), mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
let type = mime.split('/')[1];
let newfile = new File([u8arr], "newimg" + "." + type, { type: mime });
let URL = window.URL || window.webkitURL;
let newimg = URL.createObjectURL(newfile);
othis.modal.backgroundColor = "#000"; //裁剪的背景色
othis.modal.opacity = ".5"; //裁剪的透明度
othis.$emit("callback",newimg); //子传父 返回裁剪后的图片路径
});
},
//右上角关闭弹窗
close(){
let othis = this;
othis.modal.backgroundColor = "#000";
othis.modal.opacity = ".5";
othis.$emit("callback");
}
},
watch: {
show () {
let othis = this;
othis.visible = othis.show;
othis.modal = othis.$tools.getstyle(".v-modal");
othis.modal.backgroundColor = othis.shadebackground;
othis.modal.opacity = othis.shadeopacity;
}
}
}
</script>
css内容
剪裁框的样式
<style>
#cropper {
margin: 0 auto;
height: 350px;
}
</style>
No.4
使用
我使用的是ElementUI的上传图片的模块
template模板数据
<template>
<div>
<el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" drag :auto-upload="false" :show-file-list="false" :on-change='changeUpload'>
<img v-if="details.qrCode" :src="details.qrCode" class="avatars2">
<div v-else class="avatar-uploader-icon">
<i class=" el-icon-upload"></i>
<p class="el-upload__text f14">上传头像</p>
<p class="el-upload__tip red" slot="tip">格式jpg/png,不超1M</p>
</div>
</el-upload>
<cropper-all :show.sync="cropperShow" :src="cropperImg" @callback="callback"></cropper-all>
</div>
</template>
使用element-ui的上传按钮,要配置:auto-upload="false"(不要自动上传), :on-change='changeUpload'(选择完图片后的方法)
在当前页面引入封装的组件
import cropperAll from '@/components/cropper.js'
data数据
data() {
return {
//显示剪切
cropperShow: false,
cropperImg: '',
//头像
details: {
qrCode: ''
},
};
},
methods方法
/**
* 上传按钮
* @param {Object} file 上传文件返回的数据
*/
changeUpload(file){
const isLt1M = file.size / 1024 / 1024 < 1
if (!isLt1M) {
this.$message.error('上传文件大小不能超过 1MB!')
return false
}
// 上传成功后将图片地址赋值给裁剪框显示图片
this.$nextTick(() => {
this.cropperImg = URL.createObjectURL(file.raw)
this.cropperShow = true
})
},
/**
* 接收裁剪后的图片
* @param {String} img 裁剪后的图片路径
*/
callback(img){
if(img) this.details.qrCode = img;
this.cropperShow = false;
this.cropperImg = ''
}
No.5
效果
希望对大家有帮助,共勉!
更多前端分享,请关注:
前端路人甲