在uni-app中使用Painter生成小程序海報(bào)簡(jiǎn)單示例
安裝Painter
從GitHub下載Painter組件:https://github.com/Kujiale-Mobile/Painter
將painter文件夾復(fù)制到uni-app項(xiàng)目的components
目錄下
配置頁(yè)面
在需要使用海報(bào)的頁(yè)面的pages.json
中配置
{ "path": "pages/share/index", "style": { "navigationBarTitleText": "分享海報(bào)", "usingComponents": { "painter": "/components/painter/painter" } } }
在頁(yè)面中使用Painter
<template> <!-- 海報(bào)詳情 --> <view class="wrap"> <!-- 引入 Painter 組件,隱藏繪制層 --> <painter :palette="posterData" @imgOK="onImgOK" @imgErr="onImgErr" style="position: absolute; left: -9999rpx;" /> <!-- 顯示生成的海報(bào) --> <image v-if="imagePath" :src="imagePath" show-menu-by-longpress mode="aspectFill" style="width: 90%; height: 1200rpx;margin-left: 5%;" /> </view> </template> <script> import { getPosterConfigDetail, saveAgentPoster } from '@/api/home.js' export default { data() { return { userName: "", // 動(dòng)態(tài)用戶名稱 phoneNumber: "", // 動(dòng)態(tài)電話號(hào)碼 qrcodeBase64: "", // 從接口獲取的 Base64 小程序碼 posterData: {}, // Painter 配置數(shù)據(jù) imagePath: "", // 生成的海報(bào)路徑 posterImageUrl: "", //海報(bào)背景圖 oldUserName: "",//上次繪制海報(bào)時(shí)的用戶名 oldPhoneNumber: "", posterName: '', mainImageId: '', posterCode: '', templateId: '' } }, onLoad(option) { // id為海報(bào)模板 this.id = option.id this.init() }, methods: { init() { // 后臺(tái)使用初始信息生成微信小程序碼 const posterConfigDetail = await getPosterConfigDetail({ id: this.id }) this.userName = res.data.userName this.phoneNumber = res.data.mobile this.posterCode = res.data.posterCode this.templateId = res.data.id this.posterImageUrl = res.data.posterImageUrl this.posterName = res.data.posterName this.qrcodeBase64 = res.data.wxCodeContent this.oldUserName = this.userName this.oldPhoneNumber = this.phoneNumber this.generatePoster() }, // 生成海報(bào)配置 async generatePoster() { const posterConfig = { width: "750rpx", height: "1334rpx", background: "#ffffff", views: [ // 背景圖 { type: 'image', url: `${this.posterImageUrl}`, css: { width: '750rpx', height: '1334rpx' } }, { type: "text", text: `聯(lián)系人:${this.userName}`, // 直接注入數(shù)據(jù) css: { fontSize: "32rpx", bottom: "250rpx", left: "250rpx" } }, { type: "text", text: `手機(jī)號(hào):${this.phoneNumber}`, css: { fontSize: "28rpx", bottom: "200rpx", left: "250rpx" } }, { type: "image", url: `data:image/png;base64,${this.qrcodeBase64}`, css: { width: "200rpx", height: "200rpx", bottom: "350rpx", left: "275rpx" } } ] }; this.posterData = posterConfig; console.log(this.posterData, ' this.posterData') // 手動(dòng)觸發(fā)繪制 this.$forceUpdate() }, // 生成海報(bào)成功 onImgOK(e) { this.imagePath = e.detail.path; } </script>
預(yù)覽、保存圖片到相冊(cè)
<template> <!-- 海報(bào)詳情 --> <view class="wrap"> <!-- 引入 Painter 組件,隱藏繪制層 --> <painter :palette="posterData" @imgOK="onImgOK" @imgErr="onImgErr" style="position: absolute; left: -9999rpx;" /> <!-- 顯示生成的海報(bào) --> <h1 style="text-align: center;font-size: 40rpx;margin: 20rpx 0;color:#3ccc97;">{{posterName}}</h1> <image v-if="imagePath" :src="imagePath" show-menu-by-longpress mode="aspectFill" style="width: 90%; height: 1200rpx;margin-left: 5%;" /> <view class="uni-form"> <view class="uni-form-item uni-column"> <view class="title">聯(lián)系人: </view> <input class="uni-input" placeholder="請(qǐng)輸入聯(lián)系人" v-model="userName"></input> </view> <view class="uni-form-item uni-column"> <view class="title">手機(jī)號(hào)碼: </view> <input class="uni-input" type="number" maxlength="11" v-model="phoneNumber" placeholder="請(qǐng)輸入手機(jī)號(hào)碼"></input> </view> <view class="uni-form-item uni-column"> <view class="title">海報(bào)標(biāo)題: </view> <input class="uni-input" v-model="posterName" placeholder="請(qǐng)輸入海報(bào)標(biāo)題"></input> </view> </view> <!-- 觸發(fā)生成的按鈕 --> <view class="" style="padding-bottom: 60rpx;overflow: hidden;width: 100%"> <button class="btnStyle" @click="previewImg">預(yù)覽</button> <button class="btnStyle" @click="generateShare">生成并分享</button> <button class="btnStyle" @click="saveToAlbum">保存到相冊(cè)</button> </view> </view> </template> <script> import { getPosterConfigDetail, saveAgentPoster } from '@/api/home.js' export default { data() { return { userName: "", // 動(dòng)態(tài)用戶名稱 phoneNumber: "", // 動(dòng)態(tài)電話號(hào)碼 qrcodeBase64: "", // 從接口獲取的 Base64 小程序碼 posterData: {}, // Painter 配置數(shù)據(jù) imagePath: "", // 生成的海報(bào)路徑 posterImageUrl: "", //海報(bào)背景圖 oldUserName: "",//上次繪制海報(bào)時(shí)的用戶名 oldPhoneNumber: "", posterName: '', mainImageId: '', posterCode: '', templateId: '' } }, onLoad(option) { this.token = uni.getStorageSync('token') // id為海報(bào)模板 this.id = option.id this.init() }, created() { }, methods: { init() { // 后臺(tái)使用初始信息生成微信小程序碼 const posterConfigDetail = await getPosterConfigDetail({ id: this.id }) this.userName = res.data.userName this.phoneNumber = res.data.mobile this.posterCode = res.data.posterCode this.templateId = res.data.id this.posterImageUrl = res.data.posterImageUrl this.posterName = res.data.posterName this.qrcodeBase64 = res.data.wxCodeContent this.oldUserName = this.userName this.oldPhoneNumber = this.phoneNumber this.generatePoster() }, asnyc previewImg() { const needStatus = await this.needRegenerate() if (needStatus) { await this.generatePoster() // 延遲0.5秒,等待頁(yè)面重繪 await this.delay(500) } wx.previewImage({ current: this.imagePath, urls: [this.imagePath] }) }, // 修改用戶信息后,重新生成小程序碼及海報(bào)編碼(生成并分享和保存到相冊(cè)會(huì)上傳數(shù)據(jù)到后臺(tái),可能會(huì)存儲(chǔ)多條數(shù)據(jù),以海報(bào)編碼做區(qū)分) async needRegenerate() { // 修改用戶信息后,重新生成小程序碼 if (this.userName != this.oldUserName || this.phoneNumber != this.oldPhoneNumber) { let that = this await new Promise((resolve, reject) => { getPosterConfigDetail({ id: this.id }).then(res => { if (res.code == 0) { that.posterCode = res.data.posterCode that.qrcodeBase64 = res.data.wxCodeContent that.oldUserName = that.userName that.oldPhoneNumber = that.phoneNumber } resolve() }).catch(e => { reject(e) }) }); return true } return false } // 生成海報(bào)配置 async generatePoster() { const posterConfig = { width: "750rpx", height: "1334rpx", background: "#ffffff", views: [ // 背景圖 { type: 'image', url: `${this.posterImageUrl}`, css: { width: '750rpx', height: '1334rpx' } }, { type: "text", text: `聯(lián)系人:${this.userName}`, // 直接注入數(shù)據(jù) css: { fontSize: "32rpx", bottom: "250rpx", left: "250rpx" } }, { type: "text", text: `手機(jī)號(hào):${this.phoneNumber}`, css: { fontSize: "28rpx", bottom: "200rpx", left: "250rpx" } }, { type: "image", url: `data:image/png;base64,${this.qrcodeBase64}`, css: { width: "200rpx", height: "200rpx", bottom: "350rpx", left: "275rpx" } } ] }; this.posterData = posterConfig; console.log(this.posterData, ' this.posterData') // 手動(dòng)觸發(fā)繪制 this.$forceUpdate() }, // 生成海報(bào)成功 onImgOK(e) { this.imagePath = e.detail.path; }, async delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }, // 生成并分享 async generateShare() { const needStatus = await this.needRegenerate() if (needStatus) { await this.generatePoster() // 延遲0.5秒,等待頁(yè)面重繪 await this.delay(500) } // 保存海報(bào)數(shù)據(jù) this.save() const that = this wx.showShareImageMenu({ path: that.imagePath, //圖片地址必須為本地路徑或者臨時(shí)路徑 success: (re) => { console.log(re, "分享成功") }, fail: (re) => { console.log(re, "分享失敗") } }); }, // 保存到相冊(cè) saveToAlbum() { const needStatus = await this.needReGenerate() if (needStatus) { await this.generatePoster() // 延遲0.5秒,等待頁(yè)面重繪 await this.delay(500) } // 保存海報(bào)數(shù)據(jù) this.save() const that = this uni.saveImageToPhotosAlbum({ filePath: that.imagePath, success: () => { uni.showToast({ title: '保存成功', icon: 'success' }); }, fail: (err) => { console.error('保存失敗:', err); if (err.errMsg.includes('auth')) { that.showAuthSetting('需要相冊(cè)權(quán)限才能保存圖片'); } else { uni.showToast({ title: '保存失敗', icon: 'none' }); } } }); }, // 顯示權(quán)限設(shè)置引導(dǎo) showAuthSetting(content) { uni.showModal({ title: '權(quán)限申請(qǐng)', content: content || '需要您授權(quán)權(quán)限才能繼續(xù)操作', confirmText: '去設(shè)置', success: (res) => { if (res.confirm) { uni.openSetting(); } } }); }, // 保存到后臺(tái) sync save() { saveAgentPoster({ mainImageId: this.mainImageId, posterCode: this.posterCode, posterName: this.posterName, templateId: this.templateId, }).then(res => { if (res.code == 0) { console.log("請(qǐng)求成功") } }) }, onImgErr(e) { console.log(e, '生成海報(bào)出錯(cuò)了') } } } </script> <style scoped lang="scss"> .wrap { width: 100vw; height: 100%; background-color: #f7f7f7; // position: relative; } .uni-form { background-color: #f7f7f7; width: 96%; margin-left: 2%; .uni-form-item { margin-top: 20rpx; background-color: #fff; .uni-input { color: #333; font-size: 30rpx; height: 81rpx; padding-left: 10rpx; // border: none; border-radius: 10rpx; } .title { font-size: 30rpx; color: #333; // font-weight: 600; line-height: 81rpx; margin-bottom: 20rpx; float: left; width: 150rpx; text-align: right; padding-left: 5rpx; } .u-button--square { color: #3ccc97 !important; } .u-input__content__field-wrapper__field { text-align: left !important; } } } .btnStyle { width: 28%; float: left; border-radius: 20rpx; height: 80rpx; line-height: 80rpx; margin-left: 4%; } </style>
總結(jié)
到此這篇關(guān)于在uni-app中使用Painter生成小程序海報(bào)的文章就介紹到這了,更多相關(guān)uni-app Painter生成小程序海報(bào)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Bootstrap CSS組件之按鈕組(btn-group)
這篇文章主要為大家詳細(xì)介紹了Bootstrap CSS組件之按鈕組(btn-group),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12transport.js和jquery沖突問(wèn)題的解決方法
這篇文章主要介紹了transport.js和jquery沖突問(wèn)題的解決方法,需要的朋友可以參考下2015-02-02前端頁(yè)面適配之postcss-px-to-viewport實(shí)現(xiàn)步驟
postcss-px-to-viewport是一個(gè)PostCSS插件,它可以將px單位轉(zhuǎn)換為視口單位(vw、vh?或?vmin),這篇文章主要給大家介紹了關(guān)于前端頁(yè)面適配之postcss-px-to-viewport的實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-03-03網(wǎng)頁(yè)爬蟲之cookie自動(dòng)獲取及過(guò)期自動(dòng)更新的實(shí)現(xiàn)方法
這篇文章主要介紹了網(wǎng)頁(yè)爬蟲之cookie自動(dòng)獲取及過(guò)期自動(dòng)更新的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-03-03實(shí)例詳解ECMAScript5中新增的Array方法
這篇文章主要介紹了實(shí)例詳解ECMAScript5中新增的Array方法的相關(guān)資料,需要的朋友可以參考下2016-04-04javascript實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入js與css等靜態(tài)資源文件的方法
這篇文章主要介紹了javascript實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入js與css等靜態(tài)資源文件的方法,基于回調(diào)函數(shù)實(shí)現(xiàn)該功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07