怕你们复现麻烦,再贴完整代码。
下为cropper.vue和调用方法,vue文件需在pages.json里面注册,我这里是 '/pages/view/tools/cropper'
we-cropper地址,同目录存放,https://github.com/we-plugin/we-cropper/blob/master/dist/we-cropper.js
这个裁切文件实现了一些实用的功能:自定义尺寸裁切,批量自动裁切,手动裁切,及自动生成两级缩略图,需要可以拿去用。
<template>
<view style="height:100vh;overflow: hidden;">
<view class="cropper-wrapper" :style="{ height: cropperOpt.height + 'px',opacity: show?1:0 }">
<canvas type="2d" class="cropper" :disable-scroll="true" @touchstart="touchStart"
@touchmove="touchMove" @touchend="touchEnd" :style="{
width: cropperOpt.width,
height: cropperOpt.height,
backgroundColor: 'rgba(0, 0, 0, 0.8)' }"
canvas-id="cropper" id="cropper" @click="preview()"></canvas>
<canvas type="2d" class="cropper" :disable-scroll="true" :style="{
top: `-${cropperOpt.width * cropperOpt.pixelRatio}px`,
left: `-${cropperOpt.height * cropperOpt.pixelRatio}px`,
width: `${cropperOpt.width * cropperOpt.pixelRatio}px`,
height: `${cropperOpt.height * cropperOpt.pixelRatio}px`,
}"
canvas-id="targetId" id="targetId"></canvas>
</view>
<ff-button v-if="show" right="完成" :left="src?'重新选择':'选择图片'" @clickR="submit"
@clickL="select"></ff-button>
</view>
</template>
<script>
import WeCropper from './weCropper.js';
export default {
props: {
boundStyle: {
type: Object,
default () {
return {
lineWidth: 2,
borderColor: 'rgba(0, 255, 0, 0.8)',
mask: 'rgba(0, 0, 0, 0.5)'
}
}
}
},
data() {
return {
// 底部导航的高度
bottomNavHeight: 40,
cropperOpt: {
id: 'cropper',
targetId: 'targetId',
pixelRatio: 1,
scale: 2.5,
zoom: 5,
width: 0,
height: 0,
boundStyle: {
lineWidth: this.boundStyle.lineWidth,
mask: this.boundStyle.mask,
color: this.boundStyle.borderColor
},
cut: { x: 200, y: 200, width: 200, height: 200 }
},
destWidth: 200,
destHeight: 200,
src: null,
ops: null,
show: false,
cropper: null,
}
},
onLoad(ops) {
this.ops = ops
if (!ops.cropper)
this.ops.cropper = 'manual'
this.show = ops.cropper == 'manual'
uni.setNavigationBarColor({
frontColor: '#ffffff',
backgroundColor: '#000000'
})
if (!this.show) {
this.bottomNavHeight = 0
uni.setNavigationBarTitle({ title: '选择图片' })
}
let device = uni.getSystemInfoSync()
this.width = device.windowWidth
this.height = device.windowHeight
this.cropperOpt.width = this.width
this.cropperOpt.height = this.height - this.bottomNavHeight
this.cropperOpt.pixelRatio = device.pixelRatio
if (ops.width && ops.height) {
this.destWidth = +ops.width
this.destHeight = +ops.height
this.cropperOpt.cut = {
x: (this.width - +ops.width) / 2,
y: (this.height - +ops.height) / 2,
width: +ops.width,
height: +ops.height
}
}
this.cropper = new WeCropper(this.cropperOpt)
this.select()
},
methods: {
async select() {
this.src = await this.chooseImage(+this.ops.count || 1)
if (this.ops.cropper == 'auto') {
uni.showLoading({ title: '裁切中' })
let result = await this.autoCompressed()
uni.$emit('cropper', result)
uni.hideLoading()
uni.navigateBack()
} else if (this.ops.cropper == 'manual') {
await this.cropper.pushOrign(this.src[0])
} else {
uni.$emit('cropper', this.src)
uni.navigateBack()
}
},
async submit() {
let result = []
let tmp = await this.getCropperImage()
result.push(tmp)
if (this.ops.thumbnail) {
let thumbnail = await this.createThumbnail()
result = result.concat(thumbnail)
}
uni.$emit('cropper', result)
uni.navigateBack()
},
async preview() {
let result = await this.getCropperImage()
uni.previewImage({ urls: [result] })
},
getCropperImage(scale = 1) {
return this.cropper.getCropperImage({
destWidth: this.destWidth / scale,
destHeight: this.destHeight / scale,
fileType: this.ops.fileType || 'jpg',
// original: true
})
},
async createThumbnail() {
let thumb_m = await this.getCropperImage(2)
let thumb_s = await this.getCropperImage(4)
return [thumb_m, thumb_s]
},
async autoCompressed() {
let path = []
for (let i = 0; i < this.src.length; i++) {
await this.cropper.pushOrign(this.src[i])
path[i] = await this.getCropperImage()
}
return path
},
touchStart(e) { this.cropper.touchStart(e) },
touchMove(e) { this.cropper.touchMove(e) },
touchEnd(e) { this.cropper.touchEnd(e) },
chooseImage(count) {
return new Promise((resolve, reject) => {
uni.chooseImage({
count,
sizeType: ['compressed'],
sourceType: ['album'],
success: res => resolve(res.tempFilePaths),
fail: err => reject(err)
})
})
},
}
}
</script>
<style scoped>
.cropper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
;
}
.cropper-wrapper {
position: relative;
display: flex;
justify-content: space-between;
align-items: center;
/* height: 100%; */
width: 100%;
background-color: #949494;
}
</style>
调用代码,其他文件里面方法调用。
chooseImage() {
uni.$on('cropper', path => {
uni.$off('cropper')
this.oldbg.push(this.module.image)
this.$set(this.module, 'image', path[0])
this.disabled = false
})
let width = uni.getSystemInfoSync().windowWidth
this.$u.route('/pages/view/tools/cropper', {
width: width,
height: width * 4 / 3
})
},