欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

小程序如何生成海報分享朋友圈 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

小程序如何生成海報分享朋友圈

發(fā)表時間:2021-1-5

發(fā)布人:葵宇科技

瀏覽次數(shù):52

項目需求寫完有一段時間了,但是還是想回過來總結(jié)一下,一是對項目的回顧優(yōu)化等,二是對坑的地方做個記錄,避免以后遇到類似的問題。

需求

利用微信強大的社交能力通過小程序達到裂變的目的,拉取新用戶。

生成的海報如下

需求分析

1、利用小程序官方提供的api可以直接分享轉(zhuǎn)發(fā)到微信群打開小程序

2、利用小程序生成海報保存圖片到相冊分享到朋友圈,用戶長按識別二維碼關(guān)注公眾號或者打開小程序來達到裂變的目的

實現(xiàn)方案

一、分析如何實現(xiàn)

相信大家應(yīng)該都會有類似的迷惑,就是如何按照產(chǎn)品設(shè)計的那樣繪制成海報,其實當時我也是不知道如何下手,認真想了下得通過canvas繪制成圖片,這樣用戶保存這個圖片到相冊,就可以分享到朋友圈了。但是要繪制的圖片上面不僅有文字還有數(shù)字、圖片、二維碼等且都是活的,這個要怎么動態(tài)生成呢。認真想了下,需要一點一點的將文字和數(shù)字,背景圖繪制到畫布上去,這樣通過api最終合成一個圖片導(dǎo)出到手機相冊中。

二、需要解決的問題

1、二維碼的動態(tài)獲取和繪制(包括如何生成小程序二維碼、公眾號二維碼、打開網(wǎng)頁二維碼)

2、背景圖如何繪制,獲取圖片信息

3、將繪制完成的圖片保存到本地相冊

4、處理用戶是否取消授權(quán)保存到相冊

三、實現(xiàn)步驟

這里我具體寫下圍繞上面所提出的問題,描述大概實現(xiàn)的過程

①首先創(chuàng)建canvas畫布,我把畫布定位設(shè)成負的,是為了不讓它顯示在頁面上,是因為我嘗試把canvas通過判斷條件動態(tài)的顯示和隱藏,在繪制的時候會出現(xiàn)問題,所以采用了這種方法,這里還有一定要設(shè)置畫布的大小。

<canvas canvas-id="myCanvas" style="width: 690px;height:1085px;position: fixed;top: -10000px;"></canvas>

②創(chuàng)建好畫布之后,先繪制背景圖,因為背景圖我是放在本地,所以獲取 <canvas> 組件 canvas-id 屬性,通過createCanvasContext創(chuàng)建canvas的繪圖上下文 CanvasContext 對象。使用drawImage繪制圖像到畫布,第一個參數(shù)是圖片的本地地址,后面兩個參數(shù)是圖像相對畫布左上角位置的x軸和y軸,最后兩個參數(shù)是設(shè)置圖像的寬高。

const ctx = wx.createCanvasContext('myCanvas')

ctx.drawImage('/img/study/shareimg.png', 0, 0, 690, 1085)

③創(chuàng)建好背景圖后,在背景圖上繪制頭像,文字和數(shù)字。通過getImageInfo獲取頭像的信息,這里需要注意下在獲取的網(wǎng)絡(luò)圖片要先配置download域名才能生效,具體在小程序后臺設(shè)置里配置。

獲取頭像地址,首先量取頭像在畫布中的大小,和x軸Y軸的坐標,這里的result[0]是我用promise封裝返回的一個圖片地址

let headImg = new Promise(function (resolve) {
wx.getImageInfo({
src: `${app.globalData.baseUrl2}${that.data.currentChildren.headImg}`,
success: function (res) {
resolve(res.path)
},
fail: function (err) {
console.log(err)
wx.showToast({
title: '網(wǎng)絡(luò)錯誤請重試',
icon: 'loading'
})
}
})
})

let avatarurl_width = 60, //繪制的頭像寬度
avatarurl_heigth = 60, //繪制的頭像高度
avatarurl_x = 28, //繪制的頭像在畫布上的位置
avatarurl_y = 36; //繪制的頭像在畫布上的位置

ctx.save(); // 先保存狀態(tài) 已便于畫完圓再用
ctx.beginPath(); //開始繪制
//先畫個圓 前兩個參數(shù)確定了圓心 (x,y) 坐標 第三個參數(shù)是圓的半徑 四參數(shù)是繪圖方向 默認是false,即順時針
ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
ctx.clip(); //畫了圓 再剪切 原始畫布中剪切任意形狀和尺寸。一旦剪切了某個區(qū)域,則所有之后的繪圖都會被限制在被剪切的區(qū)域內(nèi)
ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推進去圖片

這里舉個例子說下如何繪制文字,比如我要繪制如下這個“字”,需要動態(tài)獲取前面字數(shù)的總寬度,這樣才能設(shè)置“字”的x軸坐標,這里我本來是想通過measureText來測量字體的寬度,但是在iOS端第一次獲取的寬度值不對,關(guān)于這個問題,我還在微信開發(fā)者社區(qū)提了bug,所以我想用另一個方法來實現(xiàn),就是先獲取正常情況下一個字的寬度值,然后乘以總字數(shù)就獲得了總寬度,親試是可以的。

let allReading = 97 / 6 / app.globalData.ratio * wordNumber.toString().length + 325;
ctx.font = 'normal normal 30px sans-serif';
ctx.setFillStyle('#ffffff')
ctx.fillText('å­—', allReading, 150);

④繪制公眾號二維碼,和獲取頭像是一樣的,也是先通過接口返回圖片網(wǎng)絡(luò)地址,然后再通過getImageInfo獲取公眾號二維碼圖片信息

⑤如何繪制小程序碼,具體官網(wǎng)文檔也給出生成無限小程序碼接口,通過生成的小程序可以打開任意一個小程序頁面,并且二維碼永久有效,具體調(diào)用哪個小程序二維碼接口有不同的應(yīng)用場景,具體可以看下官方文檔怎么說的,也就是說前端通過傳遞參數(shù)調(diào)取后端接口返回的小程序碼,然后繪制在畫布上(和上面寫的繪制頭像和公眾號二維碼一樣的)

ctx.drawImage('小程序碼的本地地址', x軸, Y軸, 寬, 高)

⑥最終繪制完把canvas畫布轉(zhuǎn)成圖片并返回圖片地址

        wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function (res) {
canvasToTempFilePath = res.tempFilePath // 返回的圖片地址保存到一個全局變量里
that.setData({
showShareImg: true
})
wx.showToast({
title: '繪制成功',
})
},
fail: function () {
wx.showToast({
title: '繪制失敗',
})
},
complete: function () {
wx.hideLoading()
wx.hideToast()
}
})

⑦保存到系統(tǒng)相冊;先判斷用戶是否開啟用戶授權(quán)相冊,處理不同情況下的結(jié)果。比如用戶如果按照正常邏輯授權(quán)是沒問題的,但是有的用戶如果點擊了取消授權(quán)該如何處理,如果不處理會出現(xiàn)一定的問題。所以當用戶點擊取消授權(quán)之后,來個彈框提示,當它再次點擊的時候,主動跳到設(shè)置引導(dǎo)用戶去開啟授權(quán),從而達到保存到相冊分享朋友圈的目的。

// 獲取用戶是否開啟用戶授權(quán)相冊
if (!openStatus) {
wx.openSetting({
success: (result) => {
if (result) {
if (result.authSetting["scope.writePhotosAlbum"] === true) {
openStatus = true;
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false
})
wx.showToast({
title: '圖片保存成功,快去分享到朋友圈吧~',
icon: 'none',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none'
})
}
})
}
}
},
fail: () => { },
complete: () => { }
});
} else {
wx.getSetting({
success(res) {
// 如果沒有則獲取授權(quán)
if (!res.authSetting['scope.writePhotosAlbum']) {
wx.authorize({
scope: 'scope.writePhotosAlbum',
success() {
openStatus = true
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false
})
wx.showToast({
title: '圖片保存成功,快去分享到朋友圈吧~',
icon: 'none',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none'
})
}
})
},
fail() {
// 如果用戶拒絕過或沒有授權(quán),則再次打開授權(quán)窗口
openStatus = false
console.log('請設(shè)置允許訪問相冊')
wx.showToast({
title: '請設(shè)置允許訪問相冊',
icon: 'none'
})
}
})
} else {
// 有則直接保存
openStatus = true
wx.saveImageToPhotosAlbum({
filePath: canvasToTempFilePath,
success() {
that.setData({
showShareImg: false
})
wx.showToast({
title: '圖片保存成功,快去分享到朋友圈吧~',
icon: 'none',
duration: 2000
})
},
fail() {
wx.showToast({
title: '保存失敗',
icon: 'none'
})
}
})
}
},
fail(err) {
console.log(err)
}
})
}

總結(jié)

至此所有的步驟都已實現(xiàn),在繪制的時候會遇到一些異步請求后臺返回的數(shù)據(jù),所以我用promise和async和await進行了封裝,確保導(dǎo)出的圖片信息是完整的。在繪制的過程確實遇到一些坑的地方。比如初開始導(dǎo)出的圖片比例大小不對,還有用measureText測量文字寬度不對,多次繪制(可能受網(wǎng)絡(luò)原因)有時導(dǎo)出的圖片上的文字顏色會有誤差等。如果你也遇到一些比較坑的地方可以一起探討下做個記錄

相關(guān)案例查看更多

相關(guān)閱讀