小程式的canvas繪圖的封裝
背景:由於小程式沒有直接分享到朋友圈的介面,但一些日常操作又需要用到分享到朋友圈等。於是,
只能採取“曲線救國”的路線,生成一張精美的卡片等,由使用者分享朋友圈。
1.關於canvas的一些坑
- 1.canvas元件在hidden情況下依然可以執行繪製操作,並且不佔據空間。
- 2.canvas元件在hidden情況下需要指定width和height,在hidden情況下,無法對canvas的width和height進行動態調整
- 3.要想動態調整canvas的width和height,需要使用wx:if="{{}}"來配合。 // 缺點是,繪製的時候canvas是顯示的
注:也就是使用控制條件,平時不顯示,在需要繪製的時候才顯示進行繪製圖片(可以放到頁面底部)
2.canvas的封裝
canvas繪製分享圖片的操作可能在一個專案中要用上好幾次,或者很多專案都需要用到。這時候我們就可以把它封裝
起來,到用的時候直接呼叫。也省的每次都編寫重複的程式碼,還可能出錯。
2.1 制定目標
我們對canvas相關操作進行封裝,其實是為了生成精美的分享圖片(其中可能涉及到文字和圖片的繪製)。
所以,目標我們有了。基於這個目標,我們大概需要如下屬性。
2.2 敲定引數
- 1.canvasId // string型別
- 2.offsetx // number型別。也就是wx.canvasToTempFile()中的x,這個x不一定是0,所以我們設為這個引數名。
- 3.offsety // number型別。同上
- 4.width // number型別。wx.canvasToTempFile()中的width
- 5.height // number型別。wx.canvasToTempFile()中的height
- 6.destWidth // number型別。wx.canvasToTempFile()中的destWidth
- 7.destHeight //number型別。wx.canvasToTempFile()中的destHeight
因為要繪製圖片或者文字。所以,除此之外,我們還需要,imgList和wordsList
- 8.imgList // array型別
- 9.wordsList // array型別
imgList中,每個資料都應是1個需繪製圖片的所有資訊,所以它應該是json資料格式的,即{},wordsList同理
那麼imgList就需要如下資料且都是必須傳入的(如果傳入圖片的話)
- 8.imgList // array型別
- 1.source // 圖片地址
- 2.x // 繪製的起點位置的x軸
- 3.y // 繪製的起點位置的y軸
- 4.width // 繪製的width
- 5.height // 繪製的height
同理,wordsList就需要如下資料,
- 9.wordsList // array型別
- 1.word // 即需要繪製的問題
- 2.x // 繪製的位置點x
- 3.y // 繪製的位置點y
- 同時可能還需要設定其他資訊,如下(非必須)
- 4.font // 要繪製的文字大小size,用於setFontSize()
- 5.textAlign // 文字的水平對齊方式,僅為 'left' 'center' 'right'
- 6.textBaseLine // 文字的縱向對齊方式,僅為 'top' 'bottom' 'middle' 'normal'
- 7.textColor // 文字的顏色
由於wordsList中存在非必須傳入的一些屬性,當不傳入時,那麼就可能會出現一些問題。於是設定一些
可以複用的引數,接著前面的wordsList下來
- 9.wordsList // array 型別
- 10.font // 全域性的font,不傳入時,預設為35
- 11.textAlign // 全域性的textAlign ,不傳入時,預設為center
- 12.textBaseLine // 全域性的textBaseLin,不傳入時,預設為middle
- 13.textColor // 全域性的textColor,不傳入時,預設為 black
至此,所需要的引數,基本敲定。但我們不可能在呼叫方法的時候傳入十幾個引數。所以,我們就把這些引數,
用{}包起來(也就是接收一個{}格式的引數),呼叫的時候把所有資料用{}包起來傳進來即可。
2.3函式封裝
新建js檔案,開始封裝函式
// data為{}格式資料,dosomething為回撥函式
function gk_draw(data,dosomething){
}
新建驗證函式,總共有3個。
- 1.分別是驗證{}第一層的資料,包含canvasId,offsetx,offsety,width...等
- 2.如果imgList存在,驗證其必填的資料是否填完
- 3.同理,驗證wordsList中必須要填的資料
// 驗證offsetx,offsety,width,height,destWidth,destHeightd等必填引數
function checkCanvasToTempFileData(data){
if ((!data.hasOwnProperty('offsetx')) || (typeof data.offsetx != 'number')){
return false
}
if ((!data.hasOwnProperty('offsety')) || (typeof data.offsety != 'number')) {
return false
}
if ((!data.hasOwnProperty('width')) || (typeof data.width != 'number')) {
return false
}
if ((!data.hasOwnProperty('height')) || (typeof data.height != 'number')) {
return false
}
if ((!data.hasOwnProperty('destWidth')) || (typeof data.destWidth != 'number')) {
return false
}
if ((!data.hasOwnProperty('destHeight')) || (typeof data.destHeight != 'number')) {
return false
}
return true
}
// 驗證imgList中的source,x,y,width,height等必填引數
function checkImgsInfo(info){
if ((!info.hasOwnProperty('source')) || (typeof info.source != 'string')){
return false
}
if ((!info.hasOwnProperty('x')) || (typeof info.x != 'number')) {
return false
}
if ((!info.hasOwnProperty('y')) || (typeof info.y != 'number')) {
return false
}
if ((!info.hasOwnProperty('width')) || (typeof info.width != 'number')) {
return false
}
if ((!info.hasOwnProperty('height')) || (typeof info.height != 'number')) {
return false
}
return true
}
// 驗證word,x,y等必填引數
function checkWordsInfo(info){
if ((!info.hasOwnProperty('x')) || (typeof info.x != 'number')) {
return false
}
if ((!info.hasOwnProperty('y')) || (typeof info.y != 'number')) {
return false
}
if ((!info.hasOwnProperty('word')) || (typeof info.word != 'string')) {
return false
}
return true
}
1.在gk_draw中加入data的驗證程式碼,如下
// 先顯示載入框
wx.showLoading({
title: '載入中...',
})
// 資料驗證
if (!checkCanvasToTempFileData(data)){
//報錯
console.error('fail to draw , some params can not be empty')
// 終止執行
return 'fail'
}
// 獲取必須引數
let mycanvasid = data.canvasId
let offsetx = data.offsetx
let offsety = data.offsety
let width = data.width
let height = data.height
let destWidth = data.destWidth
let destHeight = data.destHeight
2.驗證imgList和wordsList,因為canvas畫圖分享必然會繪製這兩者之一。
// 此處如果需要指定圖片格式可自行加入相關程式碼
// 及生成圖片質量等
let wordsList = []
let imgList = []
if (data.hasOwnProperty('wordsList') && (typeof data.wordsList == 'object')){// 如果存在文字陣列
wordsList = data.wordsList
}
if (data.hasOwnProperty('imgList') && typeof data.imgList == 'object') {// 如果存在圖片陣列
imgList = data.imgList
}
let wlen = wordsList.length
let ilen = imgList.length
// 兩者不能同時為空,事實上,絕大多數繪圖都會同時繪製這兩樣元素
if((wlen == 0) && (ilen == 0)){
console.error('fail to draw , wordsList(array) and imgList(array) can not be empty both')
return 'fail'
}
3.繪製圖片
// 建立ctx
let ctx = wx.createCanvasContext(mycanvasid, this)
// 這裡要先繪製圖片,因為先繪製文字的話,圖片會把文字覆蓋掉
if (ilen > 0){
for (let i = 0; i < ilen; i++) {
let theImgInfo = imgList[i]
//驗證資料
if (!checkImgsInfo(theImgInfo)){
console.error('fail to draw , some pramas of imgList can not be empty')
return 'fail'
}
// 開始繪製圖片
ctx.drawImage(theImgInfo.source, theImgInfo.x, theImgInfo.y, theImgInfo.width, theImgInfo.height)
}
}
4.繪製文字
if (wlen > 0){
// 初始化一些資料
let color = 'black'
if (data.hasOwnProperty('textColor') && (typeof data.textColor == 'string')) {
color = data.textColor
}
let font = 35
if (data.hasOwnProperty('font') && (typeof data.font == 'number')) {
font = data.font
}
let textAlign = 'center'
if (data.hasOwnProperty('textAlign') && (typeof data.textAlign == 'string')) {
textAlign = data.textAlign
}
let textBaseLine = 'middle'
if (data.hasOwnProperty('textAlign') && (typeof data.textBaseLine == 'string')) {
textBaseLine = data.textBaseLine
}
for(let i=0;i<wlen;i++){
let wordInfo = wordsList[i]
// 驗證資料
if (!checkWordsInfo(wordInfo)){
console.error('fail to draw , some pramas of wordsList can not be empty')
return 'fail'
}
// 設定具體渲染資訊
let mycolor = color
if (wordInfo.hasOwnProperty('textColor') && (typeof wordInfo.textColor == 'string')) {
mycolor = wordInfo.textColor
}
let myfont = font
if (wordInfo.hasOwnProperty('font') && (typeof wordInfo.font == 'number')) {
myfont = wordInfo.font
}
let myTextAlign = textAlign
if (wordInfo.hasOwnProperty('textAlign') && (typeof wordInfo.textAlign == 'string')) {
myTextAlign = wordInfo.textAlign
}
let myTextBaseLine = textBaseLine
if (wordInfo.hasOwnProperty('textAlign') && (typeof wordInfo.textBaseLine == 'string')) {
myTextBaseLine = wordInfo.textBaseLine
}
ctx.setFillStyle(mycolor)
ctx.setFontSize(myfont)
ctx.setTextAlign(myTextAlign)
ctx.setTextBaseline(myTextBaseLine)
// 開始繪製文字
ctx.fillText(wordInfo.word, wordInfo.x, wordInfo.y)
}
}
4.生成圖片
// 生成圖片
ctx.draw(true,function(){
wx.canvasToTempFilePath({
canvasId: mycanvasid,
x:offsetx,
y:offsety,
width:width,
height:height,
destWidth:destWidth,
destHeight:destHeight,
success:function(res){
// 繪製成功後,返回該圖片的地址,並執行回撥函式
dosomething(res.tempFilePath)
},
fail: function () {
// 匯出圖片錯誤
wx.showModal({
title: '匯出圖片時出錯',
content: '請重新嘗試!',
})
},
complete: function () {
wx.hideLoading()
}
}, this)
})
5.暴露介面
module.exports = {
gk_draw: gk_draw
}
6.使用
在要用的地方引入,如
// pages/result/result.js
const draw = require('../../utils/draw.js')
// 在需要的地方繪製
/**
* 生成圖片(介面版)
*/
createImg:function(){
let that = this
let backgroundImg = '/images/result.jpg'
let nickname = wx.getStorageSync('nickname')
let imgurl = wx.getStorageSync('imgurl')
let params = {
canvasId:'share',
textColor:'white',
offsetx:0,
offsety:0,
width:750,
height:1334,
destWidth:750,
destHeight:1334,
imgList:[
{
source: backgroundImg,
x:0,
y:0,
width:750,
height:1334
},
{
source: imgurl,
x: 92,
y: 80,
width: 652,
height: 690
},
],
wordsList:[
{
word:nickname,
font:50,
x: 375,
y:1209
}
]
}
draw.gk_draw(params,function(res){
// 注,這裡的res就是圖片地址了
that.setData({
resultimg:res
})
})
}
看看效果(截圖的,打下廣告)
完整版程式碼如下:
相關文章
- 小程式canvas居中剪裁繪製圖片Canvas
- 微信小程式 canvas 繪圖問題總結微信小程式Canvas繪圖
- 小程式利用Canvas繪製圖片和豎排文字Canvas
- 微信小程式 canvas圓角矩形的繪製微信小程式Canvas
- JS 第三方工具封裝經典案例(canvas動態繪圖)JS封裝Canvas繪圖
- canvas簡單封裝一個echarts實現不了的餅圖Canvas封裝Echarts
- 【封裝小技巧】is 系列方法的封裝封裝
- 微信小程式request請求的封裝微信小程式封裝
- 微信小程式 wx.request 的封裝微信小程式封裝
- canvas 繪製的圖片,進行上傳Canvas
- Canvas 繪製雷達圖Canvas
- canvas繪圖之鐘表Canvas繪圖
- 微信小程式元件封裝微信小程式元件封裝
- 微信小程式簡單封裝圖片上傳元件微信小程式封裝元件
- canvas在H5中的繪圖總結CanvasH5繪圖
- 小程式的填坑小技巧之CanvasCanvas
- 【封裝小技巧】列表處理函式的封裝封裝函式
- Canvas(3)---繪製餅狀圖Canvas
- 小程式非同步介面封裝,使用Promise,改良後的。非同步封裝Promise
- 微信小程式API互動的自定義封裝微信小程式API封裝
- 微信小程式wx.request的簡單封裝微信小程式封裝
- 【封裝小技巧】數字處理函式的封裝封裝函式
- 釘釘小程式 請求封裝封裝
- 小程式-網路請求封裝封裝
- 小程式API進行promise封裝APIPromise封裝
- Flutter Canvas學習之繪圖篇FlutterCanvas繪圖
- canvas繪製圖片drawImage學習Canvas
- 微火:Ai繪圖網站程式原始碼搭建,定製專屬的ai繪畫小程式AI繪圖網站原始碼
- 使用taro+canvas實現微信小程式的圖片分享功能Canvas微信小程式
- (乾貨)微信小程式元件封裝微信小程式元件封裝
- 微信小程式 request請求封裝微信小程式封裝
- 探究 canvas 繪圖中撤銷(undo)功能的實現方式Canvas繪圖
- 用Flutter的Canvas來自己繪製柱狀頻譜圖FlutterCanvas
- 原生Canvas繪製餅圖,我是不是被騙程式碼了Canvas
- canvas繪製動畫的技巧Canvas動畫
- canvas繪製不重合的圓Canvas
- 小程式開發前的準備工作之【深入封裝Component】封裝
- Zwibbler—前端Canvas繪圖工具使用記錄前端Canvas繪圖