微信小程序使用canvas绘图的时候发现不同手机的不一样!有可能画布没画满!有可能超了!也出现一些问题在此记录分享
1.绘制的图片只能是本地路径,开发者工具是可以网络图片的!手机不行!所以要下载:wx.downloadFile(),安全域名中不能添加微信服务器!也就是说要画用户头像的画,只能获取用户信息后把头像下载到自己服务器,再从自己服务器下载下来画!烦
2.使用canvas绘图需要根据屏幕自适应宽高的,不然产品经理会balabala
3.文字是从左下角计算位置的(默认)、与文字方向有关(wx深井冰)
代码如下,注释的很详细了,有问题可以留言共同讨论
// pages/other/creatPoster.js
const ctx = wx.createCanvasContext('Canvas');
var http = require('../../utils/http.js')
var app = getApp()
var posterBg = '../../images/poster.png'
var posterHeight = 0
var posterWidth = 0
var avatarPadding = 0 //距离边界
var avatarRadiu = 0 //头像半径
var textScale = 0 //文字比例
Page({
/**
* 页面的初始数据
*/
data: {
posterHeight: 0,
},
onLoad: function(options) {
var that = this
wx.getSystemInfo({
success: function(res) {
posterWidth = Math.round(res.screenWidth * 0.68) // 0.68是我的canvas占屏幕宽的百分比
posterHeight = Math.round(posterWidth * 1920 / 1080) // 1920/1080是UI的宽高比,由此得出需要的canvas高
avatarPadding = Math.round(posterWidth * 20 / 375) //也可以根据UI图,按比例计算得出其他需要绘制的图片文字等位置
avatarRadiu = Math.round(posterWidth * 25 / 375)
textScale = Math.round(posterWidth / 375)
that.setData({
posterHeight: posterHeight
})
},
})
wx.showLoading({
title: '生成中...',
})
http.POST({
params: {
url: '/sendFriend',
load: false,
type: 'article',
open_id: app.globalData.user.open_id,
page: 'pages/goodsDetail/goodsDetail',
scene: "goodsId=" + options.goodsId
},
success: function(e) {
wx.downloadFile({
url: 'https://mp.kewo.com' + e.result, //仅为示例,并非真实的资源
success: function(er) {
wx.downloadFile({
url: app.globalData.user.avatar,
success: function(av) {
// 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
if (av.statusCode === 200) {
ctx.drawImage(posterBg, 0, 0, posterWidth, posterHeight)
ctx.setFillStyle("white")
ctx.setFontSize(textScale * 7)
ctx.fillText(app.globalData.userInfo.nickName, posterWidth / 375 * 90, posterWidth / 375 * 40) //app.globalData.userInfo.nickName
// 巨坑:文字是从左下角计算绘制的!!!
ctx.setFontSize(textScale * 32)
ctx.fillText(options.price, posterWidth / 375 * 168, posterWidth / 375 * 440)
ctx.fillText(options.price, posterWidth / 375 * 168, posterWidth / 375 * 440 + 1)
ctx.setFontSize(textScale * 18)
ctx.fillText(options.num < 10 ? ' ' + options.num : options.num, posterWidth / 375 * 66, posterWidth / 375 * 630)
ctx.save();
ctx.beginPath(); //开始绘制
//先画个圆 前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
ctx.arc(avatarPadding + avatarRadiu, avatarPadding + avatarRadiu, avatarRadiu, 0, Math.PI * 2, false);
ctx.clip(); //画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因
ctx.drawImage(av.tempFilePath, avatarPadding, avatarPadding, avatarRadiu * 2, avatarRadiu * 2)
ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制
ctx.drawImage(er.tempFilePath, posterWidth / 375 * 249, posterWidth / 375 * 495, posterWidth / 375 * 102, posterWidth / 375 * 102) //er.tempFilePath
ctx.draw(false, wx.canvasToTempFilePath({
canvasId: 'Canvas',
success: function(res) {
var s = res.tempFilePath;
console.log(s);
that.setData({
tempFilePath: s
})
wx.hideLoading()
},
fail: function(res) {
console.log(res);
}
}))
}
},
fail: function() {
wx.hideLoading()
wx.showToast({
title: '下载图片失败',
icon: 'none'
})
}
})
},
fail: function() {
wx.hideLoading()
wx.showToast({
title: '下载图片失败',
icon: 'none'
})
}
})
},
fail: function(e) {
wx.hideLoading()
wx.showToast({
title: '下载图片失败',
icon: 'none'
})
}
})
},
save: function() {
var that = this
wx.saveImageToPhotosAlbum({
filePath: that.data.tempFilePath,
success: function() {
wx.showToast({
title: '已保存至相册:' + that.data.tempFilePath,
})
}
})
},
close: function() {
wx.navigateBack({
delta: 1,
})
},
setFormId: function(e) {
console.log(e)
if (e.detail.formId != null && app.globalData.user.open_id != null) {
http.setFormId(e.detail.formId, app.globalData.user.open_id)
}
}
})
wxml不重要了
<!--pages/other/creatPoster.wxml-->
<view class='contant'>
<view class='widow'>
<image class='close' src='../../images/close.png' bindtap='close'></image>
<canvas canvas-id="Canvas" style='height:{{posterHeight}}px' class='poster'></canvas>
<button style='height:100rpx;width:80%;background:#23459C;border-radius:0px 0px 5px 5px;color:white;display:flex;justify-content:center;align-items:center;font-size:38rpx' bindtap='save' form-type='submit'>
保存海报
</button>
<text style='font-size:24rpx;margin:20rpx 0 20rpx 0;color:#9B9B9B'>保存图片可分享至朋友圈</text>
</view>
</view>
还有wxss
/* pages/other/creatPoster.wxss */
.contant {
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
background: rgba(0, 0, 0, 0.5);
}
/*375 667 */
.widow {
width: 85%;
margin-top: 40rpx;
display: flex;
flex-direction: column;
align-items: center;
background: rgba(255, 255, 255, 0.9);
border-radius: 4px;
}
.widow .close {
width: 60rpx;
height: 60rpx;
margin: 10rpx 10rpx 10rpx 10rpx;
align-self: flex-end;
}
.widow .poster {
width:80%;
margin-top: -10rpx;
}