?小程式canvas生成海報
由于 wx.createCanvasContext() 介面不再維護,因此,我們將記錄新舊介面生成海報的兩種方法,
先上效果圖

目前展現的是圖片等元素組成、以輪播圖形式展示的頁面,為提高性能,采用按下保存海報按鈕,再執行canvas生成海報,保存到本地相冊這樣一個操作,話不多說,來干!
?舊介面 wx.createCanvasContext
介面檔案
① 寫一個canvas物件
<canvas canvas-id="share" style="width:480px;height:854px;"></canvas>
注意,這里只需給他加上 canvas-id 等下即可獲取到該物件, hide類主要是將 此畫布隱掉,讓他不要出現在我們的頁面中,由于canvas的特殊性,我們采用最最最簡單的辦法,將它定位到螢屏之外即可,
.hide{
position:fixed;
left:9000px;
}
② 圖片臨時地址準備
接下來,我們就可以著手準備在畫布上畫上我們的海報,
首先、海報上有圖片,注意,網路圖片地址是不能直接被畫上去的,要先轉為臨時地址,
當然若是本地圖片,直接采用該地址即可,無需進行臨時地址獲取,
ImgUrlToTmp方法
利用微信的 getImageInfo 介面,實作臨時地址獲取,
// 獲取海報圖片和二維碼臨時地址
ImgUrlToTmp(){
var that = this;
wx.showLoading({
title: '拼命生成中...',
});
wx.getImageInfo({
src: that.data.img_url,
success(res) {
console.log("模板圖片臨時路徑:" + res.path);
that.setData({
hbpath: res.path
},()=>{
console.log(that.data.code_url)
wx.getImageInfo({
src: that.data.code_url,
success(res) {
console.log("二維碼臨時路徑:" + res.path);
that.setData({
codepath: res.path
},()=>{
that.createNewImg()
})
},
fail(e){
console.log(e)
}
})
})
},
fail(e){
console.log(e)
}
})
},
③ canvas畫布
等我們將圖片地址準備好后,接下來,就正式進入我們的繪畫階段,上述可見呼叫了 createNewImg 方法
sharePage
//將canvas轉換為圖片保存到本地,然后將圖片路徑傳給image圖片的src
createNewImg: function () {
var that = this;
// 畫畫布
var context = wx.createCanvasContext("share");
var width = that.data.widths
var height = that.data.heights
context.clearRect(0, 0, width , height);
context.setFillStyle("#fff")
context.fillRect(0, 0, width, height)
context.save();
// 畫海報
var path = that.data.hbpath;
// console.log(path)
context.drawImage(path, 0, 0, width, height * 0.8);
// 畫二維碼
var codepath = that.data.codepath;
context.drawImage(codepath, 15, height * 0.83 , 100 , 100);
// 畫話
var t1 = "長按掃碼";
var title = "J1ay ' blogs";
var tishi = "每一個想要學習的念頭,那有可能是未來的你在向你求救,";
context.setFillStyle('#333');
context.setFontSize(13)
context.fillText(t1, 130, height * 0.872);
context.font = 'normal bold 13px sans-serif';
context.fillText(title, 130, height * 0.9);
context.setFillStyle('#999');
context.font = 'normal 10px sans-serif';
context.fillText(tishi, 130, height * 0.93);
context.draw()
setTimeout(() => {
that.toSave(); // 需要延遲一下,等待畫布繪畫完畢,否則將是空白
}, 500);
},
canvasToTempFilePath轉換
// 打包海報
toSave() {
let that = this
wx.canvasToTempFilePath({
x : 0,
y: 0,
canvasId: 'share',
width: that.data.widths,
height: that.data.heights ,
destWidth: that.data.widths * wx.getSystemInfoSync().pixelRatio,
destHeight: that.data.heights * wx.getSystemInfoSync().pixelRatio,
success: function (res) {
let canvasToTempFilePath = res.tempFilePath // 回傳的圖片地址保存到一個全域變數里
that.saveShareImg(canvasToTempFilePath)
},
fail: function (error) {
console.log(error)
}
})
},
④ 保存到本地相冊
// 保存到系統相冊
saveShareImg: function (canvasToTempFilePath) {
wx.getSetting({
success(res) {
wx.hideLoading({
success: (res) => {},
fail: (res)=>{
console.log(res)
}
})
// 無權限
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none'
})
}
})
},
fail (){
wx.showModal({
title: '提示',
content: '請設定允許訪問相冊,否則將無法使用該功能',
showCancel: false,
success (res) {
if (res.confirm) {
console.log('用戶點擊確定')
wx.openSetting({
success (res) {
// console.log(res.authSetting)
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'error'
})
}
})
},
fail(err){
console.log(err)
}
})
} else if (res.cancel) {
console.log('用戶點擊取消')
}
}
})
}
})
}
else{
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
wx.showToast({
title: '保存成功',
icon: 'success',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'error'
})
}
})
}
},
fail() {}
});
},
?新介面 createSelectorQuery
介面檔案
① 掛載一個canvas 物件
其實是類似的, 首先也是 掛載一個canvas 物件,注意,這里需要 指定 type 屬性以及id
<canvas type="2d" id="share" style="width:480px;height:854px;"></canvas>
下一步也是同舊介面,就不重復闡述了,
畫布方法改變
重點來了!!如何利用新的介面實作畫布繪畫,尤其是畫圖片這部分,踩坑太多,最終頂著血的教訓成功了,,
代碼如下:
//將canvas轉換為圖片保存到本地,然后將圖片路徑傳給image圖片的src
createNewImg: function () {
var that = this;
// 畫畫布
wx.createSelectorQuery()
.select('#share')
.fields({
node: true,
size: true, })
.exec(function (res) {
console.log(res)
const canvas = res[0].node
const context = canvas.getContext('2d')
const width = res[0].width
const height = res[0].height
context.restore();
const dpr = wx.getSystemInfoSync().pixelRatio
canvas.width = width * dpr
canvas.height = height * dpr
context.scale(dpr, dpr)
context.clearRect(0, 0, width , height);
context.fillStyle = 'white'
context.fillRect(0, 0, width, height)
context.save();
// 畫海報 為什么要這樣呢?為了防止該圖片還未加載出來就畫了圖導致畫的一片空白!
// 網上也有很有人采用 onl oad方法,但是在除錯多次失敗后,放棄,如下方案可行
var path = that.data.hbpath;
const hbPromise = new Promise((resolve, reject) => {
const hb = canvas.createImage()
hb.onload = () => {
resolve(hb)
}
hb.onerror = () => {
reject(new Error(`fail to fetch image form: ${path}`))
}
hb.src = https://www.cnblogs.com/Jlay/p/path
})
hbPromise.then(img => {
context.drawImage(img, 0, 0, width, height * 0.8)
})
// 畫二維碼
var codepath = that.data.codepath;
const codePromise = new Promise((resolve, reject) => {
const code = canvas.createImage()
code.onload = () => {
resolve(code)
}
code.onerror = () => {
reject(new Error(`fail to fetch image form: ${codepath}`))
}
code.src = codepath
})
codePromise.then(img => {
context.drawImage(img, 15, height * 0.83 , 100 , 100)
})
// 畫話
var t1 ="長按掃碼";
var title = "J1ay ' blogs";
var tishi = "每一個想要學習的念頭,那有可能是未來的你在向你求救,";
context.fillStyle = '#333';
context.fillText(t1, 130, height * 0.872);
context.font = 'normal bold 13px sans-serif';
context.fillText(title, 130, height * 0.9);
context.fillStyle = '#999';
context.font = 'normal 10px sans-serif';
context.fillText(tishi, 130, height * 0.93);
context.stroke();
context.save();
setTimeout(() => {
that.toSave(canvas);
}, 1000);
});
},
畫布保存轉為地址
基本一致,就是多加了個 canvas 屬性, 也就是將 canvas 物件傳進去即可
下方利用像素點轉化,可以提升海報的高清度
// 打包海報
toSave(canvas) {
console.log(canvas)
let that = this
wx.canvasToTempFilePath({
x : 0,
y: 0,
canvasId: 'share',
canvas: canvas,
width: that.data.widths,
height: that.data.heights ,
destWidth: that.data.widths * wx.getSystemInfoSync().pixelRatio,
destHeight: that.data.heights * wx.getSystemInfoSync().pixelRatio,
success: function (res) {
let canvasToTempFilePath = res.tempFilePath // 回傳的圖片地址保存到一個全域變數里
// console.log(res)
that.saveShareImg(canvasToTempFilePath)
},
fail: function (error) {
console.log(error)
}
})
},
保存到相冊方案也不多說啦,
來看一下保存海報的效果圖

輪播圖實作
接下來來看一下輪播圖實作, 微信開發者工具中直接有個組件 swiper
介面檔案
這里 利用
currentIndex == index判斷當前選中項,從而改變選中的樣式再加個滑動的影片即可
<view >
<swiper circular bindchange="changeHB" previous-margin="100rpx" next-margin="100rpx" >
<block wx:for="{{ shareImgs }}" wx:for-item="item" wx:key="index" >
<swiper-item >
<view >
<!-- 海報分享 -->
<view >
<image style="width:100%;height:100%" src="https://www.cnblogs.com/Jlay/p/{{item.img_url}}" />
</view>
<!-- 二維碼 -->
<view >
<view >
<image style="width: 100rpx;height:100rpx;" src="https://www.cnblogs.com/Jlay/p/{{item.code_url}}" />
</view>
<view >
<text>長按掃碼</text>
<text style="font-weight:bold">J1ay ' blogs</text>
<text style="font-size: 14rpx;color: #999999;line-height: 20rpx;">每一個想要學習的念頭,那有可能是未來的你在向你求救,</text>
</view>
</view>
</view>
</swiper-item>
</block>
</swiper>
</view>
具體代碼如下:
github地址
gitee地址
圖片素材來源網路,侵權刪
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/297741.html
標籤:Html/Css
上一篇:什么是promise
