一、由于海报中元素的宽高位置等是动态的,所以把这些值放在data中,并且为rpx单位
// data中均为rpx值
data: {
// 海报外框
wrap: {
x: 0, y: 0, w: 600, h: 1000, src: '/images/img1.png'
},
// 自定义图片(相册图片,可拖拽拉伸)
photo: {
x: 200, y: 0, w: 200, h: 200, src: '/images/img2.png'
},
// 自定义图片的最终状态(拖拽拉伸后的位置、宽高)
finalPhoto: {
x: 200, y: 0, w: 200, h: 200
},
// 文本位置
text: {
x: 90, y: 920, fontSize: 60, color: '#FFF', text: '一行文本'
},
// 最终canvas生成image的路径
finalImg: ''
},
二、canvas元素直接取data中的值,单位为rpx
<canvas class="cvs" canvas-id="cvs"
style="width:{{wrap.w}}rpx;height:{{wrap.h}}rpx;"></canvas>
三、封装rpx与px互转的函数
/**
* rpx 转 px
*/
rpx2Px: (() => {
var windowWidth = wx.getSystemInfoSync().windowWidth
var scale = windowWidth / 750
return (size) => {
return size * scale
}
})(),
/**
* px转rpx
*/
px2Rpx: (() => {
var windowWidth = wx.getSystemInfoSync().windowWidth
var scale = windowWidth / 750
return (size) => {
return size / scale
}
})(),
四、使用movable-view实现自定义图片的拖拽与缩放,该组件的事件中,返回的x y等为px单位值,可以先转为rpx存到data中,记得要加上起始坐标x y
/**
* 拖动事件
*/
posiChange(e) {
const { x, y } = e.detail
let { photo, finalPhoto } = this.data
const { px2Rpx } = this
finalPhoto.x = photo.x + px2Rpx(x)
finalPhoto.y = photo.y + px2Rpx(y)
},
/**
* 缩放事件
*/
scaleChange(e) {
const { x, y, scale } = e.detail
let { photo, finalPhoto } = this.data
const { px2Rpx } = this
finalPhoto.x = photo.x + px2Rpx(x)
finalPhoto.y = photo.y + px2Rpx(y)
finalPhoto.w = photo.w * scale
finalPhoto.h = photo.h * scale
},
五、画图过程中,CanvasContext API中需要的值为px单位,需要把data中的rpx转为px
/**
* 画图
*/
drawCanvas() {
const { rpx2Px } = this
const { wrap, photo, finalPhoto, text } = this.data
// 外框
let x = rpx2Px(wrap.x),
y = rpx2Px(wrap.y),
w = rpx2Px(wrap.w),
h = rpx2Px(wrap.h),
wrapSrc = wrap.src
// 照片
let photoX = rpx2Px(finalPhoto.x),
photoY = rpx2Px(finalPhoto.y),
photoW = rpx2Px(finalPhoto.w),
photoH = rpx2Px(finalPhoto.h),
photoSrc = photo.src
// 文字
let textX = rpx2Px(text.x),
textY = rpx2Px(text.y),
textSize = rpx2Px(text.fontSize),
color = text.color,
textText = text.text
let ctx = wx.createCanvasContext('myCanvas', this)
// 画白色背景
ctx.clearRect(left, top, width, height)
ctx.rect(left, top, width, height)
ctx.setFillStyle('#FFF')
ctx.fillRect(left, top, width, height)
},
六、canvas生成图片时,可能会出现问题,把wx.canvasToTempFilePath放在定时器中执行
ctx.draw(false, ()=> {
setTimeout(()=> {
wx.canvasToTempFilePath({
canvasId: 'cvs',
success: (res)=> {
this.setData({
finalImg: res.tempFilePath
})
}
}, this)
}, 500)
})
七、封装圆角图片的方法
function drawRoundRect (ctx, img, x, y, w, h, r) {
ctx.save() // 保存之前状态
ctx.beginPath() // 开启新路径
ctx.moveTo(x + r, y) // 左上角直线起点
ctx.arcTo(x + w, y, x + w, y + h, r) // 顶部直线 + 右上角弧线
ctx.arcTo(x + w, y + h, x, y + h, r) // 右边直线 + 右下角弧线
ctx.arcTo(x, y + h, x, y, r) // 底部直线 + 左下角弧线
ctx.arcTo(x, y, x + w, y, r) // 左边直线 + 左上角弧线
ctx.stroke()
ctx.clip() // 裁剪
ctx.drawImage(img, x, y, w, h)
ctx.closePath()
ctx.restore() // 返回上一状态
}
八、封装圆形图片方法
function drawRound (ctx, img, x, y, w, h) {
var r = w / 2
ctx.save() // 保存之前状态
ctx.beginPath() // 开启新路径
ctx.arc(x + r, y + r, r, 0, Math.PI * 2)
ctx.stroke()
ctx.clip() // 裁剪
ctx.drawImage(img, x, y, w, h)
ctx.closePath()
ctx.restore() // 返回上一状态
}