微信小程序2D canvas绘制分享海报
2021-07-26 本文已影响0人
小李不小
- 画布。2.9.0 起支持一套新 Canvas 2D 接口(需指定 type 属性),同时支持同层渲染,原有接口不再维护。相关api:获取 canvas 实例。
id:true 是否返回节点 id
node:true 是否返回节点对应的 Node 实例
size:true 是否返回节点尺寸(width height)
onReady(){
const query = wx.createSelectorQuery()
query.select('#canvas_box')
.fields({
id: true,
node: true,
size: true
})
.exec(this.init.bind(this))
},
wx.createSelectorQuery()
返回一个 SelectorQuery 对象实例。在自定义组件或包含自定义组件的页面中,应使用 this.createSelectorQuery() 来代替。
全部代码
wxml
<canvas
type="2d"
id="canvas_box"
style="width:260px;height:420px "
></canvas>
<button class='bottom' catchtap="bc" canvas-id="mycanvas"> 保存到相册 </button>
js
const app = getApp()
Page({
data: {
resqrCodeUrl:"https://tmawx.shenzhenair.com/Shwxcharfile/ts/oEy5O5Xdz-aSL5TUV89AFBwsYdsk/oEy5O5Xdz-aSL5TUV89AFBwsYdsk.jpeg", //二维码
CodeUrlbg:'https://tmawx.shenzhenair.com/Shwxcharfile/ts/app/img_invite_privilege.png',//背景图片
destMinWidth: 690, //背景宽度
maxHeight: 995,//背景高度
destMul: 2, //画布写出倍数
},
//init函数 通过 Canvas.getContext('2d') 接口可以获取 CanvasRenderingContext2D 对象,实现了 [HTML Canvas 2D Context](https://www.w3.org/TR/2dcontext/) 定义的属性、方法。
init(res) {
console.log('init----',res)
const canvas = res[0].node
const ctx = canvas.getContext('2d')
const dpr = wx.getSystemInfoSync().pixelRatio;//获取屏幕的像素比 值为2
//新接口需显示设置画布宽高; w*2 h*2
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
ctx.scale(dpr, dpr); //缩放
this.setData({
canvas,
ctx
});
//渲染bg图片和二维码还有文字,必须按照顺序来,先渲染背景,再渲染logo,最后渲染文字,如果顺序不统一,logo先渲染,就会导致背景图片加载不出来。
//向画布载入图片的方法
this.canvasDraw(ctx,canvas).then(res=>{
console.log('1',res)
// 向画布载入logo的方法
return this.code(ctx)
}).then(rrr=>{
console.log('2',rrr)
//图片头像渲染完成之后,渲染文字
this.title(ctx)
})
},
// 封面图 使用 pormise方法来输出 代码执行成功,返回一个成功标识出去
canvasDraw(ctx,canvas) {
return new Promise(res=>{
let img = this.data.canvas.createImage(); //创建img对象
img.src =this.data.CodeUrlbg;
img.onload = () => {
console.log(img.complete); //true
this.data.ctx.drawImage(img, 0, 0,260, 430);
setTimeout(() => {
res(true)
}, 100);
};
})
},
// 头像 使用 pormise方法来输出 代码执行成功,返回一个成功标识出去
code(ctx) {
const that=this;
return new Promise(rrr=>{
let code = this.data.canvas.createImage(); //创建img对象
code.onload = () => {
this.data.ctx.drawImage(code, 75,20, 105, 110);
};
code.src =this.data.resqrCodeUrl;
setTimeout(() => {
rrr(true)
}, 100);
})
},
//文字模块,不使用pormise,因为他是最后模块,所有不需要了
title(ctx) {
let text = '接小程序开发,web开发,H5开发,小程序云开发,PHP开发'
let moy = '有需要的直接微信扫码'
ctx.font = 'normal bold 12px sans-serif';
ctx.fillStyle = "rgba(60, 59, 59)";
console.log('======,', text.length)
let firstLine = text.substring(0, 20); //文字切割方法
let secondLine = text.substring(20, 38);
ctx.fillText(firstLine, 10, 275, 280)
ctx.fillText(secondLine, 10, 290, 280)
ctx.fillStyle = "rgba(0,0,0)";//添加颜色
ctx.font = 'normal bold 16px sans-serif';//指定文字样式
ctx.fillStyle = "red"; //新增样式
ctx.fillText(moy, 10, 315, 280) // ctx.fillText(文字, 像素, 移动y, 移动x)
},
bc() {
// 保存到相册
console.log('保存canvasId',this.data.canvas._canvasId)
wx.canvasToTempFilePath({ //将canvas生成图片
canvas:this.data.canvas,
x: 0,
y: 0,
width: 690,
height: 995,
destWidth: 690*2, //截取canvas的宽度
destHeight:995*2, //截取canvas的高度
success: function (res) {
console.log('生成图片成功:',res)
wx.saveImageToPhotosAlbum({ //保存图片到相册
filePath: res.tempFilePath,
success: function (res) {
wx.showToast({
title: "保存图片成功!",
duration: 2000
})
}
})
},
},this)
},
onShow(){
},
onLoad: function () {
},
onReady(){
const query = wx.createSelectorQuery()
query.select('#canvas_box')
.fields({
id: true,
node: true,
size: true
})
.exec(this.init.bind(this))
},
})
结果
logo模块是logo图片
背后花花的是背景图片
文字为最后