app_tree_planting/components/image/compress.vue
itgaojian163 aae2813dd8 初始化
2023-01-11 19:31:59 +08:00

396 lines
8.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template xlang="wxml" minapp="mpvue">
<view class="imageCompress">
<view class="photo" v-if="result.length > 0">
<view class="item" v-for="(item, index) in result" :key="index">
<image :src="item.url" @tap="previewPhoto(item.url)" mode="widthFix"></image>
<view class="remote-photo-tag" @tap="removePhoto(index)"><image src="/static/images/icon-remove.png"></image></view>
</view>
</view>
<view class="upload" v-if="result.length < limit">
<view class="info" @tap="upload()">
<image src="/static/images/icon-photo.png"></image>
<text>{{ tip }}</text>
<text v-if="remark" class="remark">{{ remark }}</text>
</view>
</view>
<canvas
class="canvas"
:canvas-id="canvasId"
:style="'width:' + destWidth + 'px;height:' + destHeight + 'px;top:' + -canvasIndex * 9000 + 'px;left:' + -canvasIndex * 9000 + 'px'"
></canvas>
</view>
</template>
<script>
export default {
name: 'imageCompress',
props: {
/*图片类型*/
type: {
type: String,
default: 'water'
},
/*上传限制*/
limit: {
type: Number,
default: 1
},
/*最大允许宽度*/
maxWidth: {
type: Number,
default: 750
},
/*默认图片url单张*/
src: {
type: String,
default: ''
},
/*默认图片url多张*/
list: {
type: Array,
default: () => {
return [];
}
},
/*上传提示*/
tip: {
type: String,
default: ''
},
/*上传备注*/
remark: {
type: String,
default: ''
},
/*是否上传至服务端*/
isUploadServer: {
type: Boolean,
default: true
},
/*服务端url*/
serverUrl: {
type: String,
default: ''
}
},
data() {
return {
result: [],
uploadPhoto: [],
photoIndex: 0,
uploadIndex: 1,
canvasIndex: 1,
canvasId: 'canvas',
destWidth: 750,
destHeight: 750
};
},
created() {
/*默认值初始化*/
this.initDefaultValue();
// #ifdef H5
this.canvasId = Date.now().toString(36);
// #endif
},
watch: {
src: function(newVal, oldVal) {
if (this.result.length == 0 && this.src) {
console.log('refresh');
this.src = newVal;
this.initDefaultValue();
}
},
list: function(newVal, oldVal) {
if (this.result.length == 0 && this.list.length > 0) {
this.list = newVal;
this.initDefaultValue();
}
},
tip: function(newVal, oldVal) {
this.tip = newVal;
}
},
methods: {
/*初始化默认值*/
initDefaultValue() {
if (this.result.length == 0) {
/*单张*/
if (this.src) {
let data = { url: this.src };
this.result.push(data);
}
/*多张*/
if (this.list.length > 0) {
this.list.forEach(item => {
let data = { url: item };
this.result.push(data);
});
}
}
},
/*上传图片*/
upload() {
let maxUploadCount = this.limit;
if (this.limit > 1) {
maxUploadCount = this.limit - this.result.length;
}
uni.chooseImage({
count: maxUploadCount,
sizeType: ['compressed'], // 指定只能为压缩图,首先进行一次默认压缩
sourceType: ['album', 'camera'], // 可以指定来源是相册还是相机,默认二者都有
success: res => {
this.uploadPhoto = res.tempFilePaths;
this.uploadIndex = 0;
if (this.limit > 1 && this.uploadPhoto.length > maxUploadCount) {
if (this.result.length > 0) {
this.$alert('只能再上传' + maxUploadCount + '张', 'warning');
} else {
this.$alert('最多只能上传' + maxUploadCount + '张', 'warning');
}
return;
}
if (this.limit == 1) {
this.result = [];
this.$loading('图片上传…');
} else {
this.initLoading();
}
this.compress(this.uploadPhoto[this.uploadIndex]);
}
});
},
/*压缩图片*/
compress(photo) {
uni.getImageInfo({
src: photo,
success: imageInfo => {
let canvasWidth = imageInfo.width;
let canvasHeight = imageInfo.height;
while (canvasWidth > this.maxWidth) {
canvasWidth = this.maxWidth;
canvasHeight = Math.trunc((imageInfo.height / imageInfo.width) * this.maxWidth);
}
this.destWidth = canvasWidth;
this.destHeight = canvasHeight;
/*绘制时间*/
let ctxTime = 10;
// #ifdef H5
ctxTime = this.canvasTime();
// #endif
/*绘制类型*/
let fileType = imageInfo.path.replace(/^.+\./, '');
if (fileType == 'png') {
fileType = 'png';
} else {
fileType = 'jpg';
}
/*绘制*/
let ctx = wx.createCanvasContext(this.canvasId, this);
setTimeout(() => {
ctx.drawImage(imageInfo.path, 0, 0, this.destWidth, this.destHeight);
ctx.draw(false, () => {
/*绘制时间*/
let drawTime = 10;
// #ifdef MP
drawTime = this.canvasTime();
// #endif
setTimeout(() => {
uni.canvasToTempFilePath(
{
x: 0,
y: 0,
width: this.destWidth,
height: this.destHeight,
destWidth: this.destWidth,
destHeight: this.destHeight,
fileType: fileType,
canvasId: this.canvasId,
success: res => {
this.submit(res.tempFilePath);
/*上传多张*/
if (this.uploadPhoto.length - 1 != this.uploadIndex) {
this.uploadIndex = this.uploadIndex + 1;
this.initLoading();
this.compress(this.uploadPhoto[this.uploadIndex]);
}
},
fail: err => {
console.log(err);
},
complete: res => {
this.canvasIndex += 1;
// #ifdef H5
this.canvasId = Date.now().toString('36');
// #endif
}
},
this
);
}, drawTime);
});
}, ctxTime);
}
});
},
/*绘制时间*/
canvasTime() {
let time = this.maxWidth / 2;
if (time >= 600) {
return 600;
} else if (time <= 100) {
return 100;
} else {
return time;
}
},
/*刷新加载提示*/
initLoading() {
if (this.uploadPhoto.length > 1) {
let loadingTxt = '图片上传(' + (this.uploadIndex + 1) + '/' + this.uploadPhoto.length + '';
this.$loading(loadingTxt);
}
},
/*上传提交*/
submit(photoUrl) {
/*不上传服务端*/
if (!this.isUploadServer) {
let data = { url: photoUrl };
this.result.push(data);
this.$emit('upload', data);
if (this.uploadPhoto.length - 1 == this.uploadIndex) {
uni.hideLoading();
}
return;
}
/*默认上传url*/
let serverUrl = this.serverUrl;
if (serverUrl == '') {
serverUrl = this.$api.user.upload;
}
/*上传至服务端*/
this.$app.uploadFile({
url: serverUrl,
filePath: photoUrl,
name: 'file',
formData: { type: this.type },
success: res => {
if (res.code == 0) {
let data = { url: res.data.url, detail: res.data };
this.result.push(data);
console.log(this.result);
this.$emit('upload', data);
} else {
this.$alert(res.msg, 'warning');
}
},
complete: res => {
if (this.uploadPhoto.length - 1 == this.uploadIndex) {
uni.hideLoading();
}
}
});
},
/*删除图片*/
removePhoto(index) {
this.photoIndex -= 1;
this.result.splice(index, 1);
this.$emit('remove', index);
},
/*预览图片*/
previewPhoto(photoUrl) {
uni.previewImage({
current: 0,
urls: [photoUrl]
});
}
}
};
</script>
<style lang="scss" scoped>
.imageCompress {
.photo {
display: flex;
flex-direction: column;
margin: 0 30rpx;
.item {
position: relative;
margin: 34rpx 0 0;
width: 100%;
line-height: 0;
&:first-child {
margin-top: 20rpx;
}
&:last-child {
margin-bottom: 20rpx;
}
image {
width: 100%;
}
.remote-photo-tag {
position: absolute;
top: -20rpx;
right: -20rpx;
z-index: 100;
image {
width: 40rpx;
height: 40rpx;
}
}
}
}
.upload {
display: flex;
justify-content: center;
.info {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 500rpx;
height: 340rpx;
border: 1rpx dashed #026836;
border-radius: 10rpx;
margin-top: 34rpx;
padding: 15rpx 0;
&:first-child {
margin-top: 20rpx;
}
&:last-child {
margin-bottom: 20rpx;
}
image {
width: 100rpx;
height: 100rpx;
}
text {
padding: 15rpx 50rpx 0;
line-height: normal;
text-align: center;
}
.remark {
color: #848c98;
font-size: 24rpx;
}
}
}
.canvas {
position: fixed;
z-index: -9999;
}
}
</style>