小程序分享给朋友的图片默认是5:4的尺寸, 实际业务中提供的图片尺寸不一定恰是这个比例,微信默认从左上角进行裁图,而一般图片主要信息都是在中间,所以默认裁图方式,易丢失图片主要信息
我们采用canvas手动进行裁图,生成分享图片
// index.wxml 采用canvas2D接口,使裁剪支持gif图
<canvas id="j-clip" type="2d" style="{{clipStyle}} {{customStyle}}"></canvas>
// index.js
import canvasClip from './lib/clip.js'
Component({
properties: {
customStyle: {
type: String
},
src: {
type: String
}
},
data: {
clipStyle: 'width: 500rpx; height: 400rpx; position: absolute; z-index: 999;top: 9999rpx; left: 9999rpx;'
},
lifetimes: {
ready() {
// 裁剪成功之前,先使页面不可操作,防止用户此时操作,拿不到裁剪后的图片
wx.showLoading({
title: '',
mask: true
})
}
},
observers: {
src(val) {
val && canvasClip('#j-clip', val, this).then(path => {
this.triggerEvent('done', path)
setTimeout(function() {
wx.hideLoading()
})
}).catch(err => {
this.triggerEvent('fail', err)
wx.hideLoading()
})
}
}
})
// ./lib/clip.js
const canvasClip = (canvasId, url, self, cw = 500, ch = 400, ratio = 5 / 4) => {
return new Promise((resolve, reject) => {
wx.createSelectorQuery().in(self)
.select(canvasId)
.fields({
node: true
})
.exec(res => {
const canvas = res[0].node
canvas.width = cw
canvas.height = ch
const ctx = canvas.getContext('2d')
const img = canvas.createImage()
img.onload = () => {
let x = 0
let y = 0
let imgWidth = img.width // 图片宽
let imgHeight = img.height // 图片高
let sImgWidth
let sImgHeight
if ((imgWidth / imgHeight) > ratio) {
sImgHeight = ch
sImgWidth = (sImgHeight * imgWidth) / imgHeight
x = -(sImgWidth - cw) / 2
} else {
sImgWidth = cw
sImgHeight = (sImgWidth * imgHeight) / imgWidth
y = -(sImgHeight - ch) / 2
}
ctx.drawImage(img, x, y, sImgWidth, sImgHeight)
wx.canvasToTempFilePath({
canvasId: canvasId,
canvas: canvas,
success: res => {
const path = res.tempFilePath
resolve(path)
console.log('************* path', path)
},
fail: (err) => {
reject('裁图:存储canvas到临时路径失败', err)
}
})
}
img.src = url
})
})
}
export default canvasClip