思路
- 暫時還沒找的好的快速生成方案,只能通過代碼一步一步畫
- 繪制內容分類:文本、長段文本、本地圖片、echarts圖表
- 涉及功能:echarts臨時圖片路徑獲取、 長段文字處理、canvas繪制、canvas臨時圖片路徑獲取、授權判斷、canvas臨時圖片保存至手機相冊、圖片全屏展示等
wxml與wxss
頁面布局:fixed全屏、mask遮罩、canvas海報內容、button保存圖片按鈕
資料:canvasType是否顯示、canvasH高度、canvasW寬度
<view class="poster" wx:if="{{canvasType}}">
<view class="mask" catchtap="cancelPoster"></view>
<canvas class='canvas' style='height:{{canvasH}}px;width:{{canvasW}}px;' id="myCanvas" canvas-id="myCanvas"/>
<button size="mini" bindtap="saveImage" type="primary"> 保存圖片</button>
</view>
.poster {
position: fixed;
left: 0;
top: 0;
height: 100%;
width: 100%;
background-color: transparent;
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
align-items: center;
z-index: 1999;
}
.poster .mask{
position: absolute;
background-color: #00000080;
height: 100%;
width: 100%;
z-index: 2199;
}
.poster .canvas{
position: absolute;
margin-top: 5%;
background-color: #fff;
border: 1px solid #41BDF9;
border-radius: 20rpx;
z-index: 2299;
}
.poster button[size=mini] {
position: absolute;
bottom: 10%;
z-index: 2299;
margin-top: 50rpx;
background-color: #41BDF9;
}
繪制相關js
本文canvas繪制使用的const ctx = wx.createCanvasContext('myCanvas'),開發工具中會提示新版本已廢棄(效果如下圖),但是可忽略,不影響,(新版調了半天一直沒調成功,先不研究了)

寬高設定
const height = wx.getSystemInfoSync().windowHeight//系統高度
const width = wx.getSystemInfoSync().windowWidth//系統寬度
const rpxtopx = width / 750 //rpx轉px系數
Page({
data: {
canvasW: width * 0.8, //畫布寬度
canvasType: false,
},
//點擊遮罩層推出海報顯示
cancelPoster() {
this.setData({
canvasType: false
})
}
})
點擊按鈕后開始繪制
async bindShare() {
wx.showLoading({
title: '圖片正在生成'
})
// echarts單個圖表的寬高,本文是實際寬高轉換為px并縮小至70%,可根據自身設定
const chart = {
w: (width - 30 * rpxtopx) * 0.7,
h: 450 * rpxtopx * 0.7
}
// 畫布高度根據自身繪制內容設定
this.setData({
canvasH: 180 + 2 * chart.h + 10,
canvasType: true
})
// 繪制
await this.drawShareImage(chart)
wx.hideLoading();
},
繪制函式
具體canvas繪制api引數見微信小程式開發檔案
async drawShareImage(chart) {
// 獲取echarts圖表臨時路徑
const chart1 = await this.getChartImage("#chart1")
const chart2 = await this.getChartImage("#chart2")
// console.log(chart1,chart2)
const text1 = “短文本”
const text2 = “長文本長文本長文本長文本長文本長文本長文本長文本長文本長文本長文本長文本長文”
// 獲取繪圖背景關系, 引數為canvas-id
const ctx = wx.createCanvasContext('myCanvas')
// 繪制本地目錄下的圖片
ctx.drawImage("../../resource/minicode.jpg", this.data.canvasW-70, 20, 50, 50);
// 繪制echarts圖表1
ctx.setFontSize(14)//設定字體大小,忽略編輯器橫線提示
ctx.fillText(text1, 20, 40)//繪制短文本
ctx.drawImage(chart1, 20, 80, chart.w, chart.h);//繪制臨時檔案路徑的圖片
ctx.save();
// 繪制echarts圖表2
ctx.fillText('XXX', 20, 100 + chart.h)
ctx.drawImage(chart2, 20, 120 + chart.h, chart.w, chart.h);
ctx.save();
// 長段文字自動換行,按行截取
ctx.setFontSize(12)
const chr = text2.split("")
let temp = ""
let row = [] //每行文字資料
let rownum=0
for (let a = 0; a < chr.length; a++) {
//最多顯示兩行,多于時...代替
if (rownum >= 2) {
row[1]+="..."
break;
}
//判斷該行文字繪制長度是否超過需求寬度(本文設定為chart.w - 20)
if (ctx.measureText(temp).width < (chart.w - 20)) {
temp += chr[a]
} else {
a--;//防止字符丟失
row.push(temp)
temp = ""
rownum++
}
}
row.push(temp)
// 繪制每行文字
for (let b = 0; b < row.length; b++) {
//注意高度每行增加,否則會重疊在一行
ctx.fillText(row[b], 20, 140 + 2 * chart.h + b * 20, chart.w - 20);
}
//繪制
ctx.draw()
},
echarts圖表臨時檔案路徑獲取
試過使用echarts.js的api生成url,總是為空,后放棄該方法
// 獲取echarts臨時檔案路徑,需要修改原始碼ec-canvas.js
getChartImage(id) {
return new Promise((resolve, reject) => {
//id示例,"#id",ec-echarts的canvas-id
const ec = this.selectComponent(id)
ec.canvasToTempFilePath({
success: res => {
// console.log(res)
resolve(res.tempFilePath)
},
fail: res => {
console.log("fail:", res)
reject()
}
})
})
},
如果獲取到為空,則修改ec-canvas目錄下ec-canvas.js
canvasToTempFilePath(opt) {
if (this.data.isUseNewCanvas) {
// 新版
const query = wx.createSelectorQuery().in(this)
query
.select('.ec-canvas')
.fields({
node: true,
size: true
})
.exec(res => {
const canvasNode = res[0].node
opt.canvas = canvasNode
wx.canvasToTempFilePath(opt)
})
} else {
// 注釋掉原來的代碼
// 舊的
// if (!opt.canvasId) {
// opt.canvasId = this.data.canvasId;
// }
// ctx.draw(true, () => {
// wx.canvasToTempFilePath(opt, this);
// });
// TODO,自己修改部分
if (!opt.canvasId) {
opt.canvasId = this.data.canvasId;
}
const system = wx.getSystemInfoSync().system
if (/ios/i.test(system)) {
ctx.draw(true, () => {
wx.canvasToTempFilePath(opt, this);
});
} else { //針對安卓機型異步獲取已繪制圖層
ctx.draw(true, () => {
//斷點列印依舊不會執行setTimeout(() => {wx.canvasToTempFilePath(opt, this);}, 1000);}});
ctx.draw(true);
setTimeout(() => { //延遲獲取
wx.canvasToTempFilePath(opt, this);
}, 1000);
})
}
}
},
保存至相冊相關js
用戶點擊保存圖片按鈕
//獲取已繪制好的canvas的臨時檔案路徑
saveImage() {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: (res) => {
const tempFilePath = res.tempFilePath
// 判斷是否授權保存到相冊
this.checkAuthSetting(tempFilePath)
},
fail: () => {}
})
},
判斷是否授權保存到相冊
checkAuthSetting(tempFilePath){
wx.getSetting({
success:(res)=>{
//是否已授權
if (res.authSetting['scope.writePhotosAlbum']) {
//已授權直接保存
this.saveImageToPhotosAlbum(tempFilePath)
}
//未授權請求授權
else if (res.authSetting['scope.writePhotosAlbum'] === undefined) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success: ()=>{
//授權后保存
this.saveImageToPhotosAlbum(tempFilePath)
},
fail: ()=>{
wx.showToast({
title: '您沒有授權,無法保存到相冊',
icon: 'none'
})
}
})
}
//用戶拒絕授權后,無法再直接調起請求授權,需要用戶自己去設定
else {
wx.openSetting({
success: (res)=>{
if (res.authSetting['scope.writePhotosAlbum']) {
//用戶設定后保存
this.saveImageToPhotosAlbum(tempFilePath)
} else {
wx.showToast({
title: '您沒有授權,無法保存到相冊',
icon: 'none'
})
}
}
})
}
}
})
},
保存至相冊,提示分享,全屏顯示圖片
saveImageToPhotosAlbum(tempFilePath) {
//保存
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success: (res) => {
//提示用戶已保存
wx.showModal({
content: '圖片已保存,分享一下吧',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: (res) => {
//用戶分享后
if (res.confirm) {
let arr = [];
arr.push(tempFilePath);
//全屏顯示已保存圖片
wx.previewImage({
urls: arr,
current: arr
})
}
},
fail: (res) => {}
})
},
fail: () => {
}
})
},
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/385566.html
標籤:其他
上一篇:安裝中國蟻劍
