在uni-app中使用Painter生成小程序海报简单示例
作者:GalenZhang888
这篇文章主要介绍了在uni-app中使用Painter生成小程序海报的相关资料,Painter支持文本、图片、矩形、qrcode 类型的view绘制,文中通过代码介绍的非常详细,需要的朋友可以参考下
安装Painter
从GitHub下载Painter组件:https://github.com/Kujiale-Mobile/Painter
将painter文件夹复制到uni-app项目的components
目录下
配置页面
在需要使用海报的页面的pages.json
中配置
{ "path": "pages/share/index", "style": { "navigationBarTitleText": "分享海报", "usingComponents": { "painter": "/components/painter/painter" } } }
在页面中使用Painter
<template> <!-- 海报详情 --> <view class="wrap"> <!-- 引入 Painter 组件,隐藏绘制层 --> <painter :palette="posterData" @imgOK="onImgOK" @imgErr="onImgErr" style="position: absolute; left: -9999rpx;" /> <!-- 显示生成的海报 --> <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: "", // 动态用户名称 phoneNumber: "", // 动态电话号码 qrcodeBase64: "", // 从接口获取的 Base64 小程序码 posterData: {}, // Painter 配置数据 imagePath: "", // 生成的海报路径 posterImageUrl: "", //海报背景图 oldUserName: "",//上次绘制海报时的用户名 oldPhoneNumber: "", posterName: '', mainImageId: '', posterCode: '', templateId: '' } }, onLoad(option) { // id为海报模板 this.id = option.id this.init() }, methods: { init() { // 后台使用初始信息生成微信小程序码 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() }, // 生成海报配置 async generatePoster() { const posterConfig = { width: "750rpx", height: "1334rpx", background: "#ffffff", views: [ // 背景图 { type: 'image', url: `${this.posterImageUrl}`, css: { width: '750rpx', height: '1334rpx' } }, { type: "text", text: `联系人:${this.userName}`, // 直接注入数据 css: { fontSize: "32rpx", bottom: "250rpx", left: "250rpx" } }, { type: "text", text: `手机号:${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') // 手动触发绘制 this.$forceUpdate() }, // 生成海报成功 onImgOK(e) { this.imagePath = e.detail.path; } </script>
预览、保存图片到相册
<template> <!-- 海报详情 --> <view class="wrap"> <!-- 引入 Painter 组件,隐藏绘制层 --> <painter :palette="posterData" @imgOK="onImgOK" @imgErr="onImgErr" style="position: absolute; left: -9999rpx;" /> <!-- 显示生成的海报 --> <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">联系人: </view> <input class="uni-input" placeholder="请输入联系人" v-model="userName"></input> </view> <view class="uni-form-item uni-column"> <view class="title">手机号码: </view> <input class="uni-input" type="number" maxlength="11" v-model="phoneNumber" placeholder="请输入手机号码"></input> </view> <view class="uni-form-item uni-column"> <view class="title">海报标题: </view> <input class="uni-input" v-model="posterName" placeholder="请输入海报标题"></input> </view> </view> <!-- 触发生成的按钮 --> <view class="" style="padding-bottom: 60rpx;overflow: hidden;width: 100%"> <button class="btnStyle" @click="previewImg">预览</button> <button class="btnStyle" @click="generateShare">生成并分享</button> <button class="btnStyle" @click="saveToAlbum">保存到相册</button> </view> </view> </template> <script> import { getPosterConfigDetail, saveAgentPoster } from '@/api/home.js' export default { data() { return { userName: "", // 动态用户名称 phoneNumber: "", // 动态电话号码 qrcodeBase64: "", // 从接口获取的 Base64 小程序码 posterData: {}, // Painter 配置数据 imagePath: "", // 生成的海报路径 posterImageUrl: "", //海报背景图 oldUserName: "",//上次绘制海报时的用户名 oldPhoneNumber: "", posterName: '', mainImageId: '', posterCode: '', templateId: '' } }, onLoad(option) { this.token = uni.getStorageSync('token') // id为海报模板 this.id = option.id this.init() }, created() { }, methods: { init() { // 后台使用初始信息生成微信小程序码 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秒,等待页面重绘 await this.delay(500) } wx.previewImage({ current: this.imagePath, urls: [this.imagePath] }) }, // 修改用户信息后,重新生成小程序码及海报编码(生成并分享和保存到相册会上传数据到后台,可能会存储多条数据,以海报编码做区分) 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 } // 生成海报配置 async generatePoster() { const posterConfig = { width: "750rpx", height: "1334rpx", background: "#ffffff", views: [ // 背景图 { type: 'image', url: `${this.posterImageUrl}`, css: { width: '750rpx', height: '1334rpx' } }, { type: "text", text: `联系人:${this.userName}`, // 直接注入数据 css: { fontSize: "32rpx", bottom: "250rpx", left: "250rpx" } }, { type: "text", text: `手机号:${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') // 手动触发绘制 this.$forceUpdate() }, // 生成海报成功 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秒,等待页面重绘 await this.delay(500) } // 保存海报数据 this.save() const that = this wx.showShareImageMenu({ path: that.imagePath, //图片地址必须为本地路径或者临时路径 success: (re) => { console.log(re, "分享成功") }, fail: (re) => { console.log(re, "分享失败") } }); }, // 保存到相册 saveToAlbum() { const needStatus = await this.needReGenerate() if (needStatus) { await this.generatePoster() // 延迟0.5秒,等待页面重绘 await this.delay(500) } // 保存海报数据 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('需要相册权限才能保存图片'); } else { uni.showToast({ title: '保存失败', icon: 'none' }); } } }); }, // 显示权限设置引导 showAuthSetting(content) { uni.showModal({ title: '权限申请', content: content || '需要您授权权限才能继续操作', confirmText: '去设置', success: (res) => { if (res.confirm) { uni.openSetting(); } } }); }, // 保存到后台 sync save() { saveAgentPoster({ mainImageId: this.mainImageId, posterCode: this.posterCode, posterName: this.posterName, templateId: this.templateId, }).then(res => { if (res.code == 0) { console.log("请求成功") } }) }, onImgErr(e) { console.log(e, '生成海报出错了') } } } </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>
总结
到此这篇关于在uni-app中使用Painter生成小程序海报的文章就介绍到这了,更多相关uni-app Painter生成小程序海报内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!