视图模板
<div v-if="isShow"
class="mask w100 vh100 flex justify-center items-center overflow"
style="z-index: 300">
<div class="paddingH20 paddingB20 flex white-bg flex-column items-center radius10 hidden">
<div class="w100 flex justify-between paddingV20">
<span class="font16">图片截取</span>
<span class="iconfont icon-close font20 cursor"
@click="off"></span>
</div>
<div class="flex">
<div class="cut"
:style="{width:(imgW/imgH===1?'300px':'460px')}">
<VueCropper ref="cropper"
:img="option.img"
:output-size="option.size"
:output-type="option.outputType"
:info="true"
:full="option.full"
:fixed="fixed"
:fixed-number="[imgW?imgW:1,imgH?imgH:1]"
:can-move="option.canMove"
:can-move-box="option.canMoveBox"
:fixed-box="option.fixedBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="imgW?imgW:150"
:auto-crop-height="imgH?imgH:150"
:center-box="option.centerBox"
@real-time="realTime"
:high="option.high"
mode="cover">
</VueCropper>
</div>
<ul class="showPreview list-style-non flex flex-column justify-between items-center hidden marginL10"
v-show="!imgW">
<li class="flex flex-column items-center">
<div class="show-preview showImgOne hidden"
:style="{borderRadius:square?0:'50%'}">
<img :src="downImg">
</div>
</li>
<li class="flex flex-column items-center">
<div class="show-preview showImgTwo hidden"
:style="{borderRadius:square?0:'50%'}">
<img :src="downImg">
</div>
</li>
<li class="flex flex-column items-center">
<div class="show-preview showImgThree hidden"
:style="{borderRadius:square?0:'50%'}">
<img :src="downImg">
</div>
</li>
</ul>
</div>
<div class="paddingT20 w100 flex justify-between">
<button @click="changeScale(1)" class="btn">放大</button>
<button @click="changeScale(-1)" class="btn">缩小</button>
<button @click="rotateLeft" class="btn">向左旋转</button>
<button @click="rotateRight" class="btn">向右旋转</button>
<a @click="down('base64')" class="btn">确认</a>
</div>
</div>
</div>
处理方法
import {VueCropper} from 'vue-cropper'
export default {
name: 'CutImg',
components: {
VueCropper
},
props: ['square', 'imgW', 'imgH'],
data() {
return {
isShow: false,
model: false,
crap: true,
previews: {},
type: 1,
option: {
img: '',
size: 1,
full: false,
outputType: 'png',
canMove: true,
fixedBox: false,
original: false,
canMoveBox: true,
autoCrop: true,
centerBox: true,
high: false,
outputSize: 0.5, //剪切后的图片质量(0.1-1)
},
downImg: '',
show: true,
fixed: true,
//传入的文件信息
fileInfo:{
type:'',
name:''
}
}
},
methods: {
open(e, num) {
this.type = num;
this.isShow = true;
//上传图片
// this.option.img
const file = e.target.files[0]
if (!/\.(png|jpeg|jpg|PNG|JPEG|JPG)$/.test(e.target.value)) {
this.$message.warning('图片类型必须是png/jpeg/jpg中的一种');
return false
}
this.fileInfo.type = file.type
this.fileInfo.name = file.name
const reader = new FileReader();
reader.onload = (e) => {
let data = null;
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
this.option.img = data
};
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file)
},
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num)
},
rotateLeft() {
this.$refs.cropper.rotateLeft()
},
rotateRight() {
this.$refs.cropper.rotateRight()
},
// 实时预览函数
realTime(data) {
this.$refs.cropper.getCropData((data) => {
this.downImg = data
})
},
/**
* 得到图片类型
* @param type blob和base64
*/
down(type) {
this.$refs.cropper.getCropData((base64) => {
this.$refs.cropper.getCropBlob((blob) => {
var file = new File([blob], this.fileInfo.name, {type: this.fileInfo.type, lastModified: Date.now()});
this.$emit('upload',file)
this.isShow = false
});
})
},
off() {
this.isShow = false;
}
}
}
视图样式
.cut {
width: 300px;
height: 300px;
margin: 0 auto;
}
.test-button {
display: flex;
flex-wrap: wrap;
align-content: center;
justify-content: center;
}
.btn {
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
text-align: center;
box-sizing: border-box;
outline: none;
padding: 9px 15px;
font-size: 14px;
border-radius: 4px;
color: #fff;
background-color: #50bfff;
border-color: #50bfff;
transition: all .2s ease;
text-decoration: none;
user-select: none;
}
.showPreview {
width: 150px;
height: 300px;
}
.showImgOne {
width: 100px;
height: 100px;
border: 1px solid #888;
}
.showImgTwo {
width: 80px;
height: 80px;
border: 1px solid #888;
}
.showImgThree {
width: 50px;
height: 50px;
border: 1px solid #888;
}
.des {
line-height: 30px;
}
code.language-html {
padding: 10px 20px;
margin: 10px 0px;
display: block;
background-color: #333;
color: #fff;
overflow-x: auto;
font-family: Consolas, Monaco, Droid, Sans, Mono, Source, Code, Pro, Menlo, Lucida, Sans, Type, Writer, Ubuntu, Mono;
border-radius: 5px;
white-space: pre;
}
.show-info {
margin-bottom: 50px;
}
.show-info h2 {
line-height: 50px;
}
.test {
height: 500px;
}
.model {
position: fixed;
z-index: 10;
width: 100vw;
height: 100vh;
overflow: auto;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.8);
}
.model-show {
display: flex;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
}
.model img {
display: block;
margin: auto;
max-width: 80%;
user-select: none;
background-position: 0px 0px, 10px 10px;
background-size: 20px 20px;
background-image: linear-gradient(45deg, #eee 25%, transparent 25%, transparent 75%, #eee 75%, #eee 100%), linear-gradient(45deg, #eee 25%, white 25%, white 75%, #eee 75%, #eee 100%);
}
.c-item {
display: block;
user-select: none;
}
@keyframes slide {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}