Vue学习笔记:vue-cropper实现封装截图组件

本文主要是介绍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实现封装截图组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099490

相关文章

windos server2022里的DFS配置的实现

《windosserver2022里的DFS配置的实现》DFS是WindowsServer操作系统提供的一种功能,用于在多台服务器上集中管理共享文件夹和文件的分布式存储解决方案,本文就来介绍一下wi... 目录什么是DFS?优势:应用场景:DFS配置步骤什么是DFS?DFS指的是分布式文件系统(Distr

NFS实现多服务器文件的共享的方法步骤

《NFS实现多服务器文件的共享的方法步骤》NFS允许网络中的计算机之间共享资源,客户端可以透明地读写远端NFS服务器上的文件,本文就来介绍一下NFS实现多服务器文件的共享的方法步骤,感兴趣的可以了解一... 目录一、简介二、部署1、准备1、服务端和客户端:安装nfs-utils2、服务端:创建共享目录3、服

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

python实现pdf转word和excel的示例代码

《python实现pdf转word和excel的示例代码》本文主要介绍了python实现pdf转word和excel的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、引言二、python编程1,PDF转Word2,PDF转Excel三、前端页面效果展示总结一

Python xmltodict实现简化XML数据处理

《Pythonxmltodict实现简化XML数据处理》Python社区为提供了xmltodict库,它专为简化XML与Python数据结构的转换而设计,本文主要来为大家介绍一下如何使用xmltod... 目录一、引言二、XMLtodict介绍设计理念适用场景三、功能参数与属性1、parse函数2、unpa

C#实现获得某个枚举的所有名称

《C#实现获得某个枚举的所有名称》这篇文章主要为大家详细介绍了C#如何实现获得某个枚举的所有名称,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... C#中获得某个枚举的所有名称using System;using System.Collections.Generic;usi

Go语言实现将中文转化为拼音功能

《Go语言实现将中文转化为拼音功能》这篇文章主要为大家详细介绍了Go语言中如何实现将中文转化为拼音功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 有这么一个需求:新用户入职 创建一系列账号比较麻烦,打算通过接口传入姓名进行初始化。想把姓名转化成拼音。因为有些账号即需要中文也需要英

C# 读写ini文件操作实现

《C#读写ini文件操作实现》本文主要介绍了C#读写ini文件操作实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录一、INI文件结构二、读取INI文件中的数据在C#应用程序中,常将INI文件作为配置文件,用于存储应用程序的

C#实现获取电脑中的端口号和硬件信息

《C#实现获取电脑中的端口号和硬件信息》这篇文章主要为大家详细介绍了C#实现获取电脑中的端口号和硬件信息的相关方法,文中的示例代码讲解详细,有需要的小伙伴可以参考一下... 我们经常在使用一个串口软件的时候,发现软件中的端口号并不是普通的COM1,而是带有硬件信息的。那么如果我们使用C#编写软件时候,如