效果生成图如下:
这篇文章主要是写前端画图的东西,二维码是从后台直接获取的。。。。
<view class="share-pop-box {{showSharePop?'show':'hide'}}">
<view class="share-pop-bg"></view>
<view class="poster-box">
<canvas style="width:100%;height: 400px;position:fixed;top:-1000px;left:0px;" canvas-id="mycanvas" disable-scroll="true"/>
<image src="{{imagePath}}" class="imgPoster"/>
</view>
<view class="share-pop">
<view class="share-box">
<button open-type="share" class="save-btn">
<image src="../../../dist/image/sharepro.png" mode="widthFix"/>
<view class="share-txt">分享好友或群聊</view>
</button>
</view>
<view class="save-box">
<button class="save-btn" bindtap="savePoster">
<image src="../../../dist/image/saveimg.png" mode="widthFix"/>
<view class="share-txt">保存朋友圈图</view>
</button>
</view>
</view>
</view>
</template>
注意:
POST 参数需要转成 JSON 字符串,不支持 form 表单提交。
接口只能生成已发布的小程序的二维码
调用分钟频率受限(5000次/分钟),如需大量小程序码,建议预生成
//第一步获取二维码。。。
wx.showLoading({
title: '生成中',
mask: true,
});
wx.request({
url: app.globalData.gurl + '/f/qrcode',
data: {
scene: that.data.projectId,
page: 'page/index/projectDetail/projectDetail'
},
header: {
'Cookie': sessionid
},
method: 'GET',
dataType: 'json',
responseType: 'text',
success: (res) => {
console.log(res);
if (res.data.code == 0) {
that.setData({
codeImg: res.data.data,
})
that.createImg();
} else {
wx.showModal({
title: '提示',
content: res.data.msg,
showCancel: false,
cancelText: '取消',
cancelColor: '#000000',
confirmText: '确定',
confirmColor: '#3CC51F',
success: (result) => {
if (result.confirm) {
}
},
fail: () => { },
complete: () => { }
});
}
},
fail: () => { },
complete: () => { }
});
createImg: function () {
//绘制海报图
const that = this;
var logoUrl = that.data.poster.image3;
var projectName = that.data.poster.projectName;
var introduction = that.data.poster.introduction;
var imageUrl = that.data.poster.image1;
var codeUrl = that.data.codeImg;
let {
windowWidth
} = wx.getSystemInfoSync();
windowWidth = windowWidth * 0.75 //弹窗的宽度为75%
/***注意注意:图片一定要是https,不然真机下,wx.getImageInfo()不会执行***/
wx.getImageInfo({
src:logoUrl,
success: (res) =>{
//绘制logo
var context = wx.createCanvasContext("mycanvas");
context.setFillStyle("#FFFFFF");
/***注意注意,下面这一句一定要加上,不然最后保存的图片是黑色底,我踩了这个坑***/
context.fillRect(0, 0, windowWidth, 400);//(矩形左上角的 x 座标,矩形左上角的 y 座标,矩形的宽度,以像素计,矩形的高度,以像素计)
context.save(); // 先保存状态 已便于画完圆再用
context.beginPath(); //开始绘制
//1.将方形图片绘制成圆形图片
//先画个圆 前两个参数确定了圆心 (x,y) 座标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针
context.arc(windowWidth/2, 40, 30, 0, Math.PI * 2, false);
context.clip();//画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
context.drawImage(res.path, 0, 0, 200, 200); // 推进去图片
context.restore(); //恢复之前保存的绘图上下文
//2.绘制项目标题
context.setFontSize(18);
context.setFillStyle("#000000");
context.setTextAlign("center");
context.fillText(projectName, windowWidth/2, 95);
context.setFontSize(18);
context.setFillStyle("#000000");
context.setTextAlign("center");
context.fillText('诚招校园CEO', windowWidth/2, 123);
//3.绘制项目简介(canvas不会自动换行,换行问题有函数wordsWrap)
const txtWidth = context.measureText(introduction).width;
context.setFontSize(12);
context.setTextAlign('left');
context.setFillStyle("#333333");
this.wordsWrap(context, introduction, txtWidth, windowWidth*0.88, 16, 142, 18);
// 计算简介所占的高度
const titleHight = Math.ceil(txtWidth / windowWidth * 1.25) * 18;
wx.getImageInfo({
src:imageUrl,
success: (res1) =>{
context.setFillStyle("#FFFFFF");
context.drawImage(res1.path, 12, 135 + titleHight, windowWidth*0.91, 140);
context.setFillStyle("#333333");
context.setFontSize(12);
context.setTextAlign("left");
context.fillText('长按扫描二维码查看详情', 25, 315+titleHight);
wx.getImageInfo({
src:codeUrl,
success: (res2) =>{
context.setFillStyle("#FFFFFF");
// context.fillRect(0, 0, 375, 800);
context.drawImage(res2.path, 175, 285+titleHight, 60, 60);
context.setFillStyle("#FFFFFF");
context.draw();
context.save()
//将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
that.setData({
showSharePop:true
})
setTimeout(() => {
wx.canvasToTempFilePath({
x: 0,
y: 0,
canvasId: 'mycanvas',
fileType: 'jpg',
success: function(res) {
wx.hideLoading()
that.setData({
showSharePop:true,
imagePath: res.tempFilePath
})
wx.hideLoading();
console.log(res.tempFilePath);
},
fail: function(res) {
console.log(res.errMsg)
}
}, this)
}, 500)
}
})
}
})
}
})
},
//以下为借鉴的别人的函数。。。原文链接:https://www.jianshu.com/p/5f96a4f91b9c
wordsWrap(ctx, txt, txtWidth, maxWidth, startX, srartY, wordsHight) {
// canvas 标题超出换行处理
let lineWidth = 0;
let lastSubStrIndex = 0;
for (let i = 0; i < txt.length; i++) {
lineWidth += ctx.measureText(txt[i]).width;
if (lineWidth > maxWidth) {
ctx.fillText(txt.substring(lastSubStrIndex, i), startX, srartY);
srartY += wordsHight;
lineWidth = 0;
lastSubStrIndex = i;
}
if (i == txt.length - 1) {
ctx.fillText(txt.substring(lastSubStrIndex, i + 1), startX, srartY);
}
}
},