在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-12
transport.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è)爬蟲(chóng)之cookie自動(dòng)獲取及過(guò)期自動(dòng)更新的實(shí)現(xiàn)方法
這篇文章主要介紹了網(wǎng)頁(yè)爬蟲(chóng)之cookie自動(dòng)獲取及過(guò)期自動(dòng)更新的實(shí)現(xiàn)方法,需要的朋友可以參考下2018-03-03
實(shí)例詳解ECMAScript5中新增的Array方法
這篇文章主要介紹了實(shí)例詳解ECMAScript5中新增的Array方法的相關(guān)資料,需要的朋友可以參考下2016-04-04
javascript實(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

