vue图片裁剪插件vue-cropper
最近有图片裁剪的需求,做完后感觉vue-cropper这个插件使用比较方便、顺手,在此分享给大家。
vue-cropper插件使用
地址: https://github.com/xyxiao001/vue-cropper
使用:
# npm 安装
npm install vue-cropper
# yarn 安装
yarn add vue-cropper
# main.js里面使用 挂载全局
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
# 组件内使用
import { VueCropper } from 'vue-cropper'
components: {
VueCropper
}
组件样式
组件封装
npm安装好vue-cropper,封装组件Qd-cropper,在组件中直接引用vue-cropper即可
<template>
<div v-if="modal">
<Modal v-model="modal" :loading="true" :width="1000" :mask-closable="false" ref="tablemodal">
<p slot="header" style="text-align:center">
<span>图片裁剪</span>
</p>
<div class="cropper_content">
<div class="cropper_box">
<div class="cropper_styl">
<vue-cropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
:outputType="option.outputType"
:info="option.info"
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:full="option.full"
:fixedBox="option.fixedBox"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:height="option.height"
:infoTrue="option.infoTrue"
:maxImgSize="option.maxImgSize"
:enlarge="option.enlarge"
:mode="option.mode"
@realTime="realTime"
@imgLoad="imgLoad"
></vue-cropper>
</div>
<div class="scope_btn">
<label class="up_btn" for="uploads">上传图片</label>
<input
type="file"
id="uploads"
style="position: absolute; clip: rect(0 0 0 0)"
accept="image/png, image/jpeg, image/gif, image/jpg"
@change="selectImgFun($event)"
/>
<Button plain icon="el-icon-zoom-in" @click="changeScale(1)">放大</Button>
<Button plain icon="el-icon-zoom-out" @click="changeScale(-1)">缩小</Button>
<Button plain @click="rotateLeft">↺ 左旋转</Button>
<Button plain @click="rotateRight">↻ 右旋转</Button>
</div>
</div>
<div class="handle_cropper">
<div class="show_preview">
<div class="preview" :style="previews.div">
<img :src="previews.url" :style="previews.img" />
</div>
</div>
<div class="upload_btn">
<Button type="success">截图预览</Button>
</div>
</div>
</div>
<div slot="footer">
<Button type="text" @click="modal = false">取消</Button>
<Button type="primary" :loading="buttonLoading" @click="submitFun">保存</Button>
</div>
</Modal>
</div>
</template>
<script>
import ApiFun from "@api/basicarchives/customerManagement.js";
import { VueCropper } from "vue-cropper";
export default {
name: "Qd-cropper",
components: {
VueCropper
},
props: {
isFixed: {
type: Boolean,
default: false
}, // 是否开启截图框宽高固定比例
autoCropWidth: {
type: Number,
default: 200
}, // 默认生成截图框宽度
autoCropHeight: {
type: Number,
default: 200
}, // 默认生成截图框高度
fixedNumber: {
type: Array,
default: () => [1, 1]
}, // 截图框的宽高比例
initialImg: {
type: String,
require: true
}
},
data() {
return {
buttonLoading: false,
modal: true,
previews: {},
option: {
img: this.initialImg, // 裁剪图片的地址
outputSize: 1, // 裁剪生成图片的质量(可选0.1 - 1)
outputType: "png", // 裁剪生成图片的格式(jpeg || png || webp)
info: true, // 图片大小信息
canScale: true, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: this.autoCropWidth, // 默认生成截图框宽度
autoCropWidth: this.autoCropWidth, // 默认生成截图框宽度
autoCropHeight: this.autoCropHeight, // 默认生成截图框高度
fixed: this.isFixed, // 是否开启截图框宽高固定比例
fixedNumber: this.fixedNumber, // 截图框的宽高比例
full: false, // false按原比例裁切图片,不失真
fixedBox: false, // 固定截图框大小,不允许改变
canMove: false, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
height: true, // 是否按照设备的dpr 输出等比例图片
infoTrue: true, // true为展示真实输出图片宽高,false展示看到的截图框宽高
maxImgSize: 3000, // 限制图片最大宽度和高度
enlarge: 1 // 图片根据截图框输出比例倍数
}
};
},
methods: {
// 初始化函数
imgLoad(msg) {
console.log("工具初始化函数=====" + msg);
},
// 图片缩放
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
// 向左旋转
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
// 向右旋转
rotateRight() {
this.$refs.cropper.rotateRight();
},
// 实时预览函数
realTime(data) {
this.previews = data;
console.log("datadata", data);
},
// 选择图片
selectImgFun(eve) {
console.log("eveeveeve", eve);
const file = eve.target.files[0];
if (!/\.(jpg|jpeg|png|JPG|PNG)$/.test(eve.target.value)) {
this.$Message({
message: "图片类型要求: jpeg、jpg、png!",
type: "error"
});
return false;
}
// 转化为blob
const reader = new FileReader();
reader.onload = eve => {
let data;
if (typeof eve.target.result === "object") {
data = window.URL.createObjectURL(new Blob([eve.target.result]));
} else {
data = eve.target.result;
}
this.option.img = data;
console.log("this.option.img", this.option.img);
};
// 转化为base64
reader.readAsDataURL(file);
},
// 上传图片
submitFun() {
// 获取截图的blob数据
this.$refs.cropper.getCropBlob(blob => {
this.updatePhoto(blob);
});
},
async updatePhoto(blob) {
try {
const formData = new FormData();
formData.append("file", blob, ".jpg");
this.buttonLoading = true;
// 将裁剪图片上传至后台
ApiFun.upImages(formData).then(res => {
this.modal = false;
this.buttonLoading = false;
this.$Message.success("上传图片成功!");
});
} catch (error) {
this.buttonLoading = false;
console.log("接口报错:", error);
}
}
}
};
</script>
<style scoped lang="less">
.cropper_content {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
.cropper_box {
width: 49.5%;
.cropper_styl {
width: 100%;
height: 400px;
}
.scope_btn {
display: flex;
display: -webkit-flex;
justify-content: space-between;
margin-top: 10px;
.up_btn {
display: flex;
align-items: center;
justify-content: center;
outline: none;
line-height: 1;
white-space: nowrap;
cursor: pointer;
-webkit-appearance: none;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
-webkit-transition: 0.1s;
transition: 0.1s;
font-weight: 500;
padding: 8px 15px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #409eff;
border-color: #409eff;
}
}
}
.handle_cropper {
width: 49.5%;
.show_preview {
width: 100%;
height: 400px;
overflow: hidden;
border: 1px solid #999999;
display: flex;
justify-content: center;
align-items: center;
.preview {
overflow: hidden;
border: 1px solid #ccc;
background: #fff;
box-sizing: border-box;
}
}
.upload_btn {
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
margin-top: 10px;
}
}
}
</style>Ï
小结
提示:如有问题可直接联系我