199 lines
4.7 KiB
Vue

<template>
<div>
<div class="container">
<div class="img-container" v-loading="loading">
<div class="img-region">
<img :src="sourceImg" ref="image" style="max-width: 100%;" alt="">
</div>
<div class="button-region">
<el-button round type="primary" @click="sureSava">保存头像</el-button>
<el-button round v-show="selectImg.id" type="primary" @click="noCropSave(selectImg.id)">不剪裁保存</el-button>
</div>
</div>
<el-divider direction="vertical"></el-divider>
<div class="avatar-preview">
<h3>头像预览</h3>
<div class="before big"></div>
<span>大头像100*100</span>
<div class="before small margin-top"></div>
<span>小头像55*55</span>
</div>
</div>
</div>
</template>
<script>
import "@/assets/css/cropper.css"
import Cropper from 'cropperjs'
import fileConfig from "@/utils/file-config";
export default {
name: 'CropperDialog',
components: {},
props: {
fileImg: {
type: Blob,
default: {}
},
selectImg: {
type: Object,
default: {}
},
avatar: {
type: String,
defalut: ''
}
},
data () {
return {
loading: true,
cropper: null,
filename: '',
sourceImg: ''
}
},
mounted() {
this.$nextTick(()=>{
this.initCropper()
this.loading = false
this.changImg(this.fileImg)
this.setSelectImg(this.selectImg)
})
},
methods: {
initCropper(){
this.cropper = new Cropper(this.$refs.image, {
responsive: true,
restore: true,
checkCrossOrigin: true,
checkOrientation: true,
modal: true,
guides: true,
center: true,
highlight: true,
autoCrop: true,
movable: true,
rotatable: true,
scalable: true,
zoomable: true,
zoomOnTouch: true,
zoomOnWheel: true,
cropBoxMovable: true,
cropBoxResizable: true,
toggleDragModeOnDblclick: true,
preview: '.before',
aspectRatio: 1,
viewMode: 1,
// dragMode: 'none',
// initialAspectRatio: 1,
// background: false,
// autoCropArea: 0.6,
});
},
setSelectImg(selectImg) {
if(selectImg.id){
this.loading = true
this.cropper.reset()
let url = fileConfig.previewUrl(this.$store.state.user.name, selectImg, this.$store.getters.token) + '?o=crop&w=1024'
this.sourceImg = url
this.cropper.replace(url)
this.loading = false
}
},
changImg(file) {
this.filename = file.name
if(file.size > 0){
this.loading = true
this.cropper.reset()
const that = this
let reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(){
that.cropper.replace(reader.result)
that.loading = false
}
}
},
sureSava() {
let cro = this.cropper.getCroppedCanvas({
maxWidth: 1204 ,
maxHeight: 1024,
fillColor: '#FFF',
imageSmoothingEnabled: true,
imageSmoothingQuality: 'high'
})
let dataURL = cro.toDataURL('image/jpeg');
cro.toBlob((blob)=>{
blob.name = this.filename
this.$emit('croppedCanvas', dataURL, blob)
})
},
// 不剪裁保存
noCropSave(fileId) {
this.$emit('noCropSave', fileId)
}
},
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
.container{
display: flex;
}
.big{
width: 100px;
height: 100px;
overflow: hidden;
}
.small{
width: 55px;
height: 55px;
overflow: hidden;
}
.img-container{
height: 450px;
line-height: 450px;
text-align: center;
width: 712px;
overflow: hidden;
.img-region {
height: 350px;
line-height: 350px;
text-align: center;
width: 623px;
overflow: hidden;
}
.button-region {
height: 100px;
line-height: 100px;
}
}
.afterCropper{
flex: 1;
margin-left: 20px;
border: 1px solid salmon;
text-align: center;
}
.afterCropper img{
width: 150px;
margin-top: 30px;
}
.avatar-preview {
span{
font-size: 12px;
}
.margin-top{
margin-top: 15px;
}
}
>>>.el-divider--vertical {
height: 450px;
margin: 0 20px;
}
>>>.el-loading-spinner {
top: 0;
margin-top: 0;
}
</style>