效果生成圖如下:
這篇文章主要是寫前端畫圖的東西,二維碼是從後臺直接獲取的。。。。
<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);
}
}
},