主要利用vue-cropper插件实现。
npm地址:acomponent-ui - npm
具体操作请看文档,文档链接:AComponent-ui
即拿即用,组件内容:
<template>
<div class="cropper-content">
<div class="cropper-box">
<div class="cropper">
<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">
</vue-cropper>
</div>
<div class="cropper-btn">
<label class="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="selectImg($event)">
<el-button size="mini" type="danger" plain icon="el-icon-zoom-in" @click="changeScale(1)">放大</el-button>
<el-button size="mini" type="danger" plain icon="el-icon-zoom-out" @click="changeScale(-1)">缩小
</el-button>
<el-button size="mini" type="danger" plain @click="rotateLeft">↺ 左旋转</el-button>
<el-button size="mini" type="danger" plain @click="rotateRight">↻ 右旋转</el-button>
</div>
</div>
<div class="show-preview">
<div>预览图:</div>
<div class="preview" :style="previews.div" v-if="previews.url">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>
</template>
<script>
import cloneDeep from 'lodash/cloneDeep'
import {VueCropper} from 'vue-cropper'
export default {
name: "ACropper",
components: {
VueCropper
},
props: {
optionInfo: { // 配置数据集合
type: Object,
default() {
return {}
}
},
imgType: { // 图片格式
type: String,
default: 'jpg|png|jpeg'
}
},
data() {
return {
previews: {},
option: {
img: '', // 裁剪图片的地址
outputSize: 1, // 裁剪生成图片的质量(可选0.1 - 1)
outputType: 'jpeg', // 裁剪生成图片的格式(jpeg || png || webp)
info: true, // 图片大小信息
canScale: true, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
fixed: false, // 是否开启截图框宽高固定比例
full: false, // false按原比例裁切图片,不失真
fixedBox: false, // 固定截图框大小,不允许改变
canMove: false, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: true, // true为展示真实输出图片宽高,false展示看到的截图框宽高
enlarge: 1 // 图片根据截图框输出比例倍数
}
};
},
watch: {
optionInfo: {
handler(val) {
this.option = cloneDeep({...this.option, ...val})
},
immediate: true,
deep: true
}
},
methods: {
// 清除
clearCrop() {
this.option.img = ''
this.option.previews = {}
},
// 缩放
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
},
// 选择图片
selectImg(e) {
const {imgType} = this
let file = e.target.files[0]
const regimage = new RegExp('\\.(' + imgType + ')')
if (!regimage.test(e.target.value)) {
this.$message({
message: `图片类型要求:${imgType}`,
type: "error"
});
return false
}
//转化为blob
let reader = new FileReader()
reader.onload = (e) => {
let data
if (typeof e.target.result === 'object') {
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
this.option.img = data
}
//转化为base64
reader.readAsDataURL(file)
}
},
}
</script>
<style scoped lang="scss">
.cropper-content {
.cropper-box {
width: 100%;
.cropper {
width: auto;
height: 300px;
}
}
.show-preview {
text-align: left;
margin-top: 10px;
.preview {
margin-top: 10px;
overflow: hidden;
}
}
.cropper-btn {
margin-top: 30px;
.btn {
outline: none;
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
-webkit-appearance: none;
text-align: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
-webkit-transition: .1s;
transition: .1s;
font-weight: 500;
padding: 8px 15px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #409EFF;
border-color: #409EFF;
margin-right: 10px;
}
}
}
</style>