業務場景
在微信中 小程序無法分享到朋友圈,目前大部分的解決方案都是,canvas動態繪制 生成圖片后,保存到用戶相冊,用戶進行分享照片到朋友圈,朋友圈打開圖片后識別二維碼進入小程序,達到分享目的
github源碼鏈接
https://github.com/richard1015/canvas
微信IDE代碼預覽
https://developers.weixin.qq.com/s/DBZhf8mB7qaD
海報需求設計圖分析
圖1分析: 可以看到海報 要求寬750 高1218(當然了數據是動態的,高度肯定不會固定值,需要我們動態去計算)
圖2分析:矩形框 寬高為固定值 320 背景顏色#fff 圓角10
圖3分析:矩形框 上半部分 寬320 高125 背景顏色#f7f7f7
代碼邏輯實現
1.模板邏輯 wxml添加canvas公用組件
<!--pages/index/index.wxml-->
<view class='index'>
<!-- 公用canvas share -->
<import src="../common/canvasShare.wxml" />
<template data="{{shareCanvasItem}}" is="canvas-share" />
<!-- content 內容預顯示 begin -->
<view class='content'>
<view class='content_header'>
<view class='left' bindtap='toChoiceBank'>
<text>中國銀行(測試數據)</text>
</view>
</view>
<view class='content_item'>
...此處省略
</view>
</view>
<!-- content end -->
<import src="../common/footerShare.wxml" />
<template is="footer-share" />
</view>
復制代碼
2.canvas公用模板設計
<template name="canvas-share">
<!-- <view style='width:0px;height:0px;overflow:hidden;opacity: 0;'> -->
<canvas style="height:{{shareCanvasItem.Height}}px !important;" class='shareCanvas' canvas-id="shareCanvas" binderror="canvasIdErrorCallback"></canvas>
<!-- </view> -->
</template>
復制代碼
3.js 邏輯實現
// 調用公用組件
let {
CanvasUtil,
util
} = getApp();
// 測試數據引入
const testData= require('../../test.js');
Page({
/** * 頁面的初始數據 */
data: {
shareCanvasItem: {
Height: 5000
},//初始canvas高度,設置背景黑,此高度必須大於 動態生成內容高度,否則 無法全面覆蓋背景
items: [],
},
onLoad: function() {
this.getList();
},
//獲取列表數據
getList() {
var self = this;
// purchasePrice 匯買價
// cashPrice 鈔買價
// sellingPrice 匯賣價
// banknotePrice 鈔賣價
//賦值過濾健全item
self.setData({
items: testData
});
},
/* 分享事件 */
share: function() {
console.log('分享');
var self = this;
let titleTemp = `今日中行外匯牌價`;
let tips = '*以上為保存時間的牌價,成交價格以實際交易為准';
// 獲取設備寬高
var res = wx.getSystemInfoSync();
var canvasWidth = res.windowWidth;
var canvasHeight = self.data.shareCanvasItem.Height;
// 獲取canvas的的寬 自適應寬(設備寬/750) px
var Rpx = (canvasWidth / 750).toFixed(2);
//上邊距
var paddingTop = Rpx * 20;
//左邊距
var paddingLeft = Rpx * 20;
//右邊距
var paddingRight = Rpx * 20;
//當前編寫高
var currentLineHeight = Rpx * 33;
var context = wx.createCanvasContext('shareCanvas');
//全局背景顏色默認填充
context.setFillStyle('#333333');
context.fillRect(0, 0, canvasWidth, canvasHeight);
//字體顏色
context.setFillStyle('#999999');
context.setTextAlign('center');
context.font = `${(Rpx * 36).toFixed(0)}px PingFangSC-Regular`;
//內容行邊距計算
currentLineHeight += Rpx * 36;
//標題文本 繪制
context.fillText(titleTemp, canvasWidth / 2, currentLineHeight);
context.setTextAlign('left');
//內容行邊距計算
currentLineHeight += Rpx * 34;
//item白色背景 矩形左右邊距
let padingLeftRightRect = Rpx * 40,
rectRadius = Rpx * 10, //圓角10
rectWidth = Rpx * 320, //寬
rectHeight = Rpx * 320, //高
topRectHeight = Rpx * 125; //美元上部分
self.data.items.forEach((item, index) => {
//保存上次繪制圖,進行本次操作
// context.save();
//每兩次進行換行邏輯
if (index > 1 && index % 2 === 0) {
//行高換行
currentLineHeight += rectHeight + Rpx * 40;
//邊距重置
padingLeftRightRect = Rpx * 40;
}
//局部 y currentLineHeight
//局部 x padingLeftRightRect
// 偶數為 left 處理邏輯 奇數為right 處理邏輯
//left
if (index % 2 === 0) {
} else {
//right 坐標 = 加矩形寬 + 中間距30
padingLeftRightRect += rectWidth + Rpx * 30;
}
//矩形顏色設置
context.setFillStyle('#ffffff');
//調用繪制圓角矩形
CanvasUtil.drawRoundedRect(context, padingLeftRightRect, currentLineHeight, rectWidth, rectHeight, rectRadius, true);
//矩形上變背景顏色生成
context.setFillStyle('#f7f7f7');
//調用繪制圓角矩形
CanvasUtil.drawRoundedRect(context, padingLeftRightRect, currentLineHeight, rectWidth, topRectHeight, rectRadius, true);
//幣種字體顏色
context.setFillStyle('#333333');
context.font = `${(Rpx * 34).toFixed(0)}px PingFangSC-Regular`;
//幣種文本繪制
context.fillText(item.chName, padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34);
//幣種英文繪制
context.fillText(item.abridge, padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
//繪制幣種圖案
context.drawImage(`/currencyImg/${item.iconName}`, padingLeftRightRect + Rpx * 226, currentLineHeight + Rpx * 35, Rpx * 64, Rpx * 64);
//價格字體顏色
context.setFillStyle('#666666');
context.font = `${(Rpx * 26).toFixed(0)}px PingFangSC-Regular`;
context.fillText('鈔買價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 70, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
context.fillText('匯買價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 110, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
context.fillText('鈔賣價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 150, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
context.fillText('匯賣價', padingLeftRightRect + Rpx * 26, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 190, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
//價格值字體顏色
context.setFillStyle('#333333');
//鈔買價
context.fillText(item.cashPrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 70, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
// 匯買價
context.fillText(item.purchasePrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 110, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
//鈔賣價
context.fillText(item.banknotePrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 150, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
//匯賣價
context.fillText(item.sellingPrice, padingLeftRightRect + Rpx * 204, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 190, currentLineHeight + Rpx * 30 + Rpx * 34 * 2 + Rpx * 10);
//操作完成后恢復上次值
// context.restore();
});
//行高換行
currentLineHeight += rectHeight + Rpx * 40;
//字體顏色
context.setFillStyle('#999999');
context.setTextAlign('center');
context.font = `${(Rpx * 28).toFixed(0)}px PingFangSC-Regular`;
//領取提示文本 繪制
context.fillText(tips, canvasWidth / 2, currentLineHeight);
//行高換行
currentLineHeight += Rpx * 30;
//qrcode生成圖片
context.drawImage('/imgs/qrcode.png', paddingLeft, currentLineHeight, canvasWidth - paddingLeft - paddingRight, Rpx * 200);
context.setTextAlign('left');
//字體顏色
context.setFillStyle('#EEC62E');
context.font = `${(Rpx * 32).toFixed(0)}px PingFangSC-Regular`;
//領取提示文本 繪制
context.fillText('測試canvas', paddingLeft + Rpx * 43, currentLineHeight + Rpx * 90);
//字體顏色
context.setFillStyle('#999999');
context.font = `${(Rpx * 28).toFixed(0)}px PingFangSC-Regular`;
//領取提示文本 繪制
context.fillText('出境游、炒匯必備神器', paddingLeft + Rpx * 43, currentLineHeight + Rpx * 130);
//內容行高控制
currentLineHeight += Rpx * 220;
//設置最終canvas高度
self.setData({
shareCanvasItem: {
Height: currentLineHeight
}
});
//繪制完成
context.draw();
//調用公共組件保存圖片
util.saveImg();
},
/** * 生命周期函數--監聽頁面初次渲染完成 */
onReady: function() {},
/** * 生命周期函數--監聽頁面顯示 */
onShow: function() {},
/** * 生命周期函數--監聽頁面隱藏 */
onHide: function() {},
/** * 生命周期函數--監聽頁面卸載 */
onUnload: function() {},
/** * 頁面上拉觸底事件的處理函數 */
onReachBottom: function() {},
/** * 用戶點擊右上角分享 */
onShareAppMessage: function(res) {}
})
復制代碼