功能很簡單 直接上代碼
html
canvas 定義畫板 構造海報 .preview 生成海報圖瀏覽 模板框
css
核心代碼 js
// pages/all/index.js
Page({
/**
* 頁面的初始數據
*/
data: {
currentLineHeight: 0,
previewHidden: true
},
onLoad(){
this.createCanvasContext()
},
createCanvasContext() {
let that =this
var expiration = wx.getStorageSync("index_data_expiration"); //拿到過期時間
var timestamp = Date.parse(new Date()); //拿到現在時間
// access_token 過期時間
if (wx.getStorageSync('access_token') && expiration > timestamp) {
console.log(wx.getStorageSync('access_token'))
that.accessToken(wx.getStorageSync('access_token'))
} else {
wx.request({
url: 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret',
method: 'get',
success: function (ress) {
wx.setStorageSync("access_token", ress.data.access_token)
var timestamp = Date.parse(new Date());
var expiration = timestamp + ress.data.expires_in
console.log(ress.data.access_token)
wx.setStorageSync("expires_in", expiration)
that.accessToken(ress.data.access_token)
},
fail: function (res) {
console.log(res)
}
})
}
},
accessToken(access_token) {
let that = this
let winWidth = wx.getSystemInfoSync().windowWidth; // 獲取當前設備的可視寬度
let winHeight = wx.getSystemInfoSync().windowHeight; // 獲取當前設備的可視高度
that.setData({
winWidth: winWidth,
winHeight: winHeight
})
let data = {
page: 'pages/hotinfo/hotinfo',
scene: '12'
}
wx.request({
url: 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' + access_token,
method: 'POST',
data: data,
// dataType: 'json',
responseType: 'arraybuffer', //將返回數據 按文本解析修改為arraybuffer
success: function (res) {
console.log(res)
// 利用writeFile bese64圖片存本地文件使用
var imgPath = wx.env.USER_DATA_PATH + '/tabhome' + 'ewm' + '.png';
var fs = wx.getFileSystemManager();
fs.writeFileSync(imgPath, res.data, "base64");
const ctx = wx.createCanvasContext('shareImg')
var Rpx = (winWidth / 375).toFixed(2);
ctx.setFillStyle('#fff')
ctx.fillRect(0, 0, winWidth, 800)
ctx.drawImage('../../' + res[0].path, 0, 0, winWidth, 228 * Rpx)
var currentLineHeight = 228 * Rpx + 10;
ctx.setTextAlign('left')
ctx.setFillStyle('#2E2F2F')
ctx.setTextAlign('left')
let contentTitle = '世界之大無奇不有,只有不斷努力划水才能實現更加有珍貴的,你想要渾渾噩噩的日子,日子才會渾渾噩噩的對待你'
var chr = contentTitle.split(""); //這個方法是將一個字符串分割成字符串數組
var temp = "";
var row = [];
for (var a = 0; a < chr.length; a++) {
if (ctx.measureText(temp).width < winWidth / 2 - 10) {
temp += chr[a];
} else {
a--;
row.push(temp);
temp = "";
}
}
row.push(temp);
//如果數組長度大於2 則截取前兩個
if (row.length > 2) {
var rowCut = row.slice(0, 2);
var rowPart = rowCut[1];
var test = "";
var empty = [];
for (var a = 0; a < rowPart.length; a++) {
if (ctx.measureText(test).width < winWidth / 2 - 10) {
test += rowPart[a];
} else {
break;
}
}
empty.push(test);
var group = empty[0] + "..." //這里只顯示兩行,超出的用...表示
rowCut.splice(1, 1, group);
row = rowCut;
}
ctx.font = 'normal bold 18px sans-serif';
for (var b = 0; b < row.length; b++) {
currentLineHeight += Rpx * 30;
ctx.fillText(row[b], 15, currentLineHeight);
}
currentLineHeight += 80 * Rpx
ctx.drawImage('../../' + 'assets/coupon_gold.png', 20, currentLineHeight, 60 * Rpx, 60 * Rpx)
currentLineHeight += 35 * Rpx
ctx.fillText('健健康康', 90 * Rpx, currentLineHeight);
ctx.drawImage(imgPath, winWidth - 120 * Rpx, currentLineHeight - 70, 100 * Rpx, 100 * Rpx)
currentLineHeight += 100 - 40 * Rpx
ctx.stroke()
ctx.draw()
that.setData({
currentLineHeight: currentLineHeight
})
})
}
},
save: function () {
var that = this;
//獲取相冊授權
wx.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
that.savaImageToPhoto();
}
})
} else {
that.savaImageToPhoto();
}
}
})
},
/**
* 生成分享圖
*/
share: function () {
var that = this
wx.showLoading({
title: '努力生成中...'
})
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: this.data.winWidth,
height: this.data.currentLineHeight,
destWidth: this.data.winWidth,
destHeight: this.data.currentLineHeight,
canvasId: 'shareImg',
success: function (res) {
console.log(res.tempFilePath);
that.setData({
preurl: res.tempFilePath,
previewHidden: false,
})
wx.hideLoading()
},
fail: function (res) {
console.log(res)
}
})
},
savaImageToPhoto: function () {
let that = this;
wx.showLoading({
title: '努力生成中...'
})
wx.canvasToTempFilePath({
x: 0,
y: 0,
width: that.data.winWidth,
height: that.data.winHeight - 70,
destWidth: that.data.winWidth,
destHeight: that.data.winHeight - 70,
canvasId: 'shareImg',
success: function (res) {
console.log(res)
wx.hideLoading()
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success(res) {
wx.showModal({
content: '圖片已保存到相冊',
showCancel: false,
confirmText: '知道啦',
confirmColor: '#72B9C3',
success: function (res) {
if (res.confirm) {
console.log('用戶點擊確定');
that.setData({
hidden: true
})
}
}
})
}
})
},
fail: function (res) {
console.log(res)
}
})
},
})
(https://api.weixin.qq.com接口只能后端請求 不然上線后會出問題 我這邊只供體驗參考)
本地圖片路徑錯誤繪制會失敗
1.通過小程序api 接口 https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret (get)
獲取 token值 時效兩個小時
2.再通過api 接口 https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=access_token 獲取自定義參數的小程序碼 (POST)
01.scene 為要攜帶的參數 最高32位 具體看小程序api文檔 接口返回的格式為 arraybuffer
02.請求是注意 參數修改 responseType: 'arraybuffer', //將返回數據 按文本解析修改為arraybuffer
03.通過api wx.arrayBufferToBase64() 將數據轉為bese64 例:
let URL ='data:image/png;base64,' + wx.arrayBufferToBase64(res.data)
04.小程序canvas bese64圖片 模擬器可正常顯示 真機操作則無效 因canvas圖片不支持base64
處理方法為利用writeFile bese64圖片存本地文件使用 例:
var imgPath = wx.env.USER_DATA_PATH + '/tabhome' + 'ewm' + '.png';
var fs = wx.getFileSystemManager();
fs.writeFileSync(imgPath, res.data, "base64");
wx.env.USER_DATA_PATH 為微信提供無需在意 '/tabhome' 為本頁面路徑 ewm為自定義
writeFileSync內的imgPath為自定義的文件路徑 (本地路徑)
writeFileSync內的res.data 為獲取到的arraybuffer值
writeFileSync內的base64 為數據類型
imgPath拿到的 就是本地的圖片路徑 可直接使用到項目中
3.利用wx.createCanvasContext創建畫板 進行繪畫 文字太多 自動換行兩行省略處理 圖片路徑一定要正確 不然只會看到空白的canvas
4.利用wx.canvasToTempFilePath() 將canvas截取生成圖片 區域可自定義 具體請看官方文檔
5.wx.saveImageToPhotosAlbum 保存圖片到手機相冊
6.注意canvas圖片如果是網絡圖片 要通過 getImageInfo / downloadFile 先下載再使用
流程:
通過canvas提前繪制海報
再通過wx.canvasToTempFilePath() 截取繪制好的海報
最后通過wx.saveImageToPhotosAlbum 保存圖片到手機相冊
這樣就大功告成了
