本文主要是介绍Vue学习笔记:vue-cropper实现封装截图组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
-
vue-cropper一款好用的前端截图插件
项目介绍:
使用vue+elementUI写的项目,需要用到图片截图功能、视频截图、视频直播等功能,关于截图不失真,发现vue-cropper这款插件能满足需求,可以让用户自由调整截图框的宽高、位置,可以根据用户的需求选择截图的格式(png、jpg),也可以选择图片的编码格式(base64、blob)等。
案例展示:
http://zhb_nyx.gitee.io/cropperimg/#/cropperImg
官方网站:
https://github.com/xyxiao001/vue-cropper
组件文档:
图片裁剪 | zhb-ui
第一步:项目中引入vue-cropper插件
npm install vue-cropper --save 或者 npm install vue-cropper -S
第二步:引入依赖,
在main.js中引入
import VueCropper from 'vue-cropper'Vue.use(VueCropper)
按需引入
import VueCropper from 'vue-cropper'
第三步:封装弹框内截图组件
如上图样式布局,
<template><div class="imgCrop-body"><!--图片显示区域--><div class="imgCrop-box"><!--原图--><div class="imgCrop-con"><vue-cropperref="cropper":img="option.img":output-size="option.size":output-type="option.outputType":info="true":full="option.full":fixed="fixed":fixed-number="fixedNumber":can-move="option.canMove":can-move-box="option.canMoveBox":fixed-box="option.fixedBox":original="option.original":auto-crop="option.autoCrop":auto-crop-width="option.autoCropWidth":auto-crop-height="option.autoCropHeight":center-box="option.centerBox"@real-time="realTime":high="option.high"@img-load="imgLoad"mode="cover"></vue-cropper></div><!--截图--><div class="imgCrop-con imgCrop-con-preview" ref="imgCropPreviews"><div class="show-preview" :style="{'width': previews.w + 'px', 'height': previews.h + 'px', 'overflow': 'hidden', 'margin': '5px'}"><div :style="previews.div"><img :src="previews.url" :style="previews.img"></div></div></div></div><!--操作区域--><div class="imgCrop-btn"><div class="ict-query-button"><label for="uploads" style="width:100%;height: 100%; ">上传</label><inputtype="file"id="uploads"style="position:absolute; clip:rect(0 0 0 0);"ref="uploadImg"accept="image/png, image/jpeg, image/gif, image/jpg"@change="uploadImg($event, 1)"></div><div class="ict-query-button" v-if="!crap" @click="startCrop">截取</div><div class="ict-query-button" v-else @click="stopCropAndSave">保存</div><div class="ict-query-button" @click="changeScale(100)">放大</div><div class="ict-query-button" @click="changeScale(-100)">缩小</div><div class="ict-query-button" @click="clearCrop">清空</div><div class="ict-query-button" @click="refreshCrop">刷新</div><div class="ict-query-button" @click="rotateLeft">向右旋转90度</div><div class="ict-query-button" @click="rotateRight">向左旋转90度</div></div></div><!--到底啦!=======================================================-->
</template>
<script>export default {name: "cropperImgComponents",data(){return {crap: true,previews: {},option: {// 裁剪图片的地址img: '',// 裁剪生成图片的质量size: 1,// 输出原图比例截图 props名fullfull: false,// 裁剪生成图片的格式outputType: 'png',// 上传图片是否可以移动canMove: true,// 固定截图框大小 不允许改变fixedBox: false,// 上传图片按照原始比例渲染original: false,// 截图框能否拖动canMoveBox: true,// 是否默认生成截图框autoCrop: true,// 只有自动截图开启 宽度高度才生效// 默认生成截图框宽度autoCropWidth: 400,// 默认生成截图框高度autoCropHeight: 350,// 截图框是否被限制在图片里面centerBox: false,// 是否按照设备的dpr 输出等比例图片high: true},show: true,// 是否开启截图框宽高固定比例fixed: false,// 截图框的宽高比例fixedNumber: [1, 2],// 裁剪框的大小信息info: true,// canScale 图片是否允许滚轮缩放canScale: true,// infoTrue true 为展示真实输出图片宽高 false 展示看到的截图框宽高:infoTrue: true,// maxImgSize 限制图片最大宽度和高度maxImgSize: 2000,// enlarge 图片根据截图框输出比例倍数enlarge: 1,// mode 图片默认渲染方式mode: 'contain'}},mounted() {},methods:{setCropImg(){this.$refs.uploadImg.click()this.crap = true},//上传图片uploadImg(e, num) {var file = e.target.files[0]this.file = fileconsole.log(file);if (file.size / 1024 / 1024 > 5) {this.$message.info("上传文件不超过5M");return;}if (!/\.(jpg|png|JPG|PNG)$/.test(file.name)) {this.$message.info('图片类型必须是jpg,png中的一种')return false}var reader = new FileReader()reader.onload = (e) => {let dataif (typeof e.target.result === 'object') {// 把Array Buffer转化为blob 如果是base64不需要data = window.URL.createObjectURL(new Blob([e.target.result]))} else {data = e.target.result}if (num === 1) {this.option.img = data} else if (num === 2) {this.example2.img = data}}// 转化为base64// reader.readAsDataURL(file)// 转化为blobreader.readAsArrayBuffer(file)},imgLoad(msg) {console.log(msg)this.previews.url = msg.url},// 实时预览函数realTime(data) {this.previews = datathis.$emit('', this.previews)console.log(data)},//开始截图startCrop() {this.crap = truethis.$refs.cropper.startCrop()},//停止截图&保存stopCropAndSave() {this.crap = falsethis.$refs.cropper.stopCrop()this.$refs.cropper.getCropData((data) => {this.base64ToFile(data,'cropFile')})},//清空截图clearCrop() {this.$refs.cropper.clearCrop()this.crap = false},//放大缩小changeScale(num) {num = num || 1this.$refs.cropper.changeScale(num)},//刷新refreshCrop() {this.$refs.cropper.refresh()this.crap = false},//向左旋转rotateLeft() {this.$refs.cropper.rotateLeft()},//向右旋转rotateRight() {this.$refs.cropper.rotateRight()},//base64ToFilebase64ToFile(urlData, fileName) {var arr = urlData.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 imgFile = new File([u8arr], fileName, {type:mime});this.$parent.getCropApi(imgFile,urlData)},}}
</script>
<style lang="scss" scoped>.imgCrop-body{width: 100%;height: 100%;overflow: hidden;//图片显示区域.imgCrop-box{width: 100%;height: calc(100% - 100px);display: flex;justify-content: center;align-items: center;.imgCrop-con{width: calc(50% - 20px);height: calc(100% - 20px);margin: 10px;&.imgCrop-con-preview{background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMzTjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC");}}}//操作区域.imgCrop-btn{width: 100%;height: 50px;margin-top: 20px;display: flex;justify-content: center;>div{margin: 0 10px;}}}</style>
第四步:封装点击打开文件上传,弹出截取图片
<template><div class="upfile"><div class="addFile" v-if="isAddFile" @click="getCropImg">+</div><div v-else class="addFileImg" @click="getCropImg"><img :src="imgBase64"></div><!--截图区域--><div class="CropDialogVisible" v-show="isCropDialogVisible"><div class="CropDialog-main" style="height: 80vh;position: relative;"><div class="CropDialog-close" @click="isCropDialogVisible = false">×</div><cropper-img ref="cropImg"></cropper-img></div></div></div>
</template><script>import cropperImg from './cropperImg.vue'export default {name: "upfile",props: ["type","imgUrl"],created() {console.log(this.imgUrl);if(this.imgUrl){this.imgBase64 = this.imgUrlthis.filedisabled = false}},data() {return {imgBase64:'',//isCropDialogVisible:false,cropFile:'',isAddFile:true};},components:{cropperImg},methods: {getCropImg(){let that = thisthis.$refs.cropImg.setCropImg()setTimeout(function () {that.isCropDialogVisible = true},500)},getCropApi(file,base64){console.log(file, base64);this.imgBase64 = base64this.isCropDialogVisible = falsethis.isAddFile = falsethis.$emit("getCropFile",{File:file,Base64:base64})}}};
</script><style lang="scss" scoped>.CropDialogVisible{width: 100%;height: 100%;position: fixed;top:0;left: 0;background: rgba(0,0,0,.4);display: flex;align-items: center;justify-content: center;z-index: 1000;.CropDialog-main{width: 80%;height: 80%;background: #ffffff;.CropDialog-close{width: 40px;height: 40px;background: #666666;color: #ffffff;display: flex;align-items: center;justify-content: center;border-radius: 50%;position: absolute;top: -12px;right: -20px;font-size: 38px;cursor: pointer;}}}.upfile{width: 200px;.addFileImg{display: block;width: 80px;height: 80px;background: #eeeeee;cursor: pointer;img{display: block;width: 100%;height: 100%;}}.addFile{width: 80px;height: 80px;border: 1px dotted #64686B;border-radius:4px;font-size: 35px;display: flex;align-items: center;justify-content: center;cursor: pointer;color:#64686B;}}.avatar-file {text-align: center;}.avatar-file-text {width: 240px;border: 1px solid #dddddd;border-radius:3px;line-height: 30px;height: 30px;display: flex;align-items: center;justify-content: center;font-weight: 500;font-size: 14px;white-space: nowrap;padding: 0 5px;cursor: pointer;border-radius:0;}.avatar-file-text img {width: 16px;height: 16px;margin-right: 9px;}.avatar-file-imgbox {height: 65px;display: flex;align-items: center;justify-content: flex-start;border: 1px solid#C0C4CC;}.filename {font-size: 14px;font-weight: 400;text-decoration: underline;text-align: left;color: #1d73f6;line-height: 22px;margin-left: 10px;}.filename span {width: 8px;height: 8px;// color: #ff0000;font-size: 36px;cursor: pointer;}
</style>
第五步:调用截取图片组件
<template>
<div style="width: 100%;display: flex;align-items: center;justify-content: center;"><div style="display: flex;align-items: center"><span style="margin-right: 20px;">截取图片</span><cropper-file></cropper-file></div>
</div>
</template><script>import cropperFile from './cropperFile.vue'export default {name: "cropper",data(){},methods:{},components:{cropperFile}}
</script><style scoped></style>
现已将该功能整合进我的UI组件库内,大家可以前往下载使用;
文档如上;
最后
热爱分享!乐于助人!
大家好,我是“前端互助会”,欢迎大家关注微信公众号“前端公众号”!
一起学习,共同成长!
这篇关于Vue学习笔记:vue-cropper实现封装截图组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!