cropperjs上傳圖片截取
參考:http://www.reibang.com/p/9dc2f643cb6a
參考:http://www.reibang.com/p/4fc756df20f9
- 首先下載依賴npm i cropperjs眷蜈,這里上傳用到了ali-oss拜英,所以同時(shí)安裝ali-oss的依賴npm i ali-oss
- 組件代碼如下
<template>
<div class="v-simple-cropper">
<!-- <input class="file" type="file" accept="image/*" @change="uploadChange" /> -->
<van-uploader
v-model="fileList"
:after-read="afterRead"
:before-delete="beforeDelete"
:max-count="1"
image-fit="contain"
/>
<div class="tip">請(qǐng)上傳一寸免冠照片</div>
<div class="v-cropper-layer" ref="layer" v-show="showlayer">
<div class="layer-header">
<button class="cancel" @click="cancelHandle">取消</button>
<button class="cancel" @click="cropperRotate(90)">旋轉(zhuǎn)</button>
<button class="confirm" @click="confirmHandle">選取</button>
</div>
<img ref="cropperImg" />
</div>
</div>
</template>
<script>
import Cropper from "cropperjs";
import "cropperjs/dist/cropper.min.css";
import { getALiYun } from "@/api/dict";
import { client } from "@/utils/alioss";
export default {
name: "Cropper",
props: {
fileUrl: String,
uploadURL: Function,
deleteURL: Function,
},
data() {
return {
cropper: null,
showlayer: false,
initParam: {
scale: 1, // 相對(duì)手機(jī)屏幕放大的倍數(shù)
},
fileList: [],
ALiYun: {},
};
},
created() {
this.getALiYun();
},
mounted() {
this.init();
if (this.fileUrl) {
const index = this.fileUrl.lastIndexOf("/");
const name = this.fileUrl.substr(index + 1);
let obj = {
content: this.fileUrl,
url: this.fileUrl,
name: decodeURIComponent(name),
};
this.fileList.push(obj);
}
},
methods: {
// 獲取后臺(tái)OSS數(shù)據(jù)源
async getALiYun() {
getALiYun().then((res) => {
if (res.code === 200) {
this.ALiYun = res.data;
}
});
},
// 初始化
init() {
const cropperImg = this.$refs.cropperImg;
this.cropper = new Cropper(cropperImg, {
aspectRatio: 446 / 650, // 剪裁比例
dragMode: "move",
viewMode: 1,
cropBoxResizable: false,
});
},
// 選擇圖片
afterRead(file) {
// 判斷擴(kuò)展名
const tmpCnt = file.file.name.lastIndexOf(".");
const exName = file.file.name.substring(tmpCnt + 1);
const names = ["jpg", "jpeg", "png"];
if (names.indexOf(exName) < 0) {
this.fileList = [];
this.$Toast.fail("不支持的格式!");
return;
}
this.fileList[0].status = "uploading";
this.fileList[0].message = "上傳中..";
const URL = window.URL || window.webkitURL;
let binaryData = [];
binaryData.push(file.file);
this.cropper.replace(URL.createObjectURL(new Blob(binaryData)));
this.showlayer = true;
},
// 旋轉(zhuǎn)
cropperRotate(val) {
this.cropper.rotate(val);
},
cancelHandle() {
this.cropper.reset();
this.fileList = [];
this.showlayer = false;
},
confirmHandle() {
const cropBox = this.cropper.getCropBoxData();
const scale = this.initParam["scale"] || 1;
this.cropper
.getCroppedCanvas({
width: cropBox.width * scale,
height: cropBox.height * scale,
})
//把裁剪的圖片轉(zhuǎn)換成blob類型文件,在通過(guò)new File()低散,轉(zhuǎn)換成file文件
.toBlob(async (blob) => {
//重置file的name,以時(shí)間戳作為文件名
const timeString = new Date().getTime();
const imgFile = new File([blob], `${timeString}.jpg`, {
type: "image/jepg",
});
this.showlayer = false;
const res = await this.uploadFile(imgFile);
this.$emit("uploadURL", res);
});
},
uploadFile(file) {
return new Promise((resolve) => {
const fileName = `${Date.parse(new Date())}/${file.name}`; //定義唯一的文件名
return client(this.ALiYun)
.put(fileName, file)
.then(({ res, url, name }) => {
if (res && res.status == 200) {
console.log("阿里云OSS上傳成功");
let obj = {
name: file.name,
content: url,
file,
};
this.fileList = [];
this.fileList.push(obj);
resolve(url);
} else {
this.fileList = [];
this.$Toast.fail("上傳失敗");
}
})
.catch((err) => {
console.log(`阿里云OSS上傳失敗回調(diào)`, err);
});
});
},
beforeDelete(){
this.fileList = [];
this.$emit("deleteURL");
}
},
};
</script>
<style lang="less" scoped>
.v-simple-cropper {
// width: 100%;
// height: 100%;
// position: absolute;
// left: 0;
// top: 0;
text-align: center;
padding-top: 10px;
// .file {
// // width: 100%;
// // height: 100%;
// // opacity: 0;
// // width: 100px;
// height: 100px;
// }
.tip {
font-size: 14px;
margin: 5px 0;
}
/deep/.van-uploader__upload {
margin: 0 !important;
}
.v-cropper-layer {
position: fixed;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: #fff;
z-index: 99999;
.layer-header {
position: absolute;
bottom: 0;
left: 0;
z-index: 99999;
background: rgba(#fff, 0.5);
width: 100%;
height: 1.5rem;
padding: 0 0.2rem;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.cancel,
.confirm {
line-height: 1.5rem;
font-size: 0.58rem;
background: none;
border: 0;
outline: 0;
// float: left;
}
// .confirm {
// // float: right;
// }
img {
position: inherit !important;
border-radius: inherit !important;
float: inherit !important;
}
}
}
</style>
- 頁(yè)面引入及使用代碼如下
<Cropper
@uploadURL="uploadURL"
@deleteURL="deleteURL"
:fileUrl="infoForm.personalPhoto"
/>
import Cropper from "@/components/Cropper/index.vue";
components: {
Cropper,
},
// 獲取圖片url
uploadURL(url) {
console.log(url, "1111111111111111");
},
deleteURL() {
this.infoForm.personalPhoto = "";
},