lime-painter
是一个专为 UniApp 设计的插件,用于优雅地生成海报,并支持下载海报图片。它支持在多个平台中使用,并且提供了盒子、文字、图片、二维码等配置选项,允许开发者根据项目需求按照UI设计稿对海报进行高度还原。本文将介绍如何使用 lime-painter
插件在 UniApp 中实现海报的生成及下载。
技术栈:uni-app、Vue3(3.4.21)、TypeScript(4.9.5)、wot-design-uni(1.2.26)、UnoCSS(0.58.9)、pyh-nv
运行环境:微信小程序
平台兼容性
- 非uni_modules方式:🈚️
-
基本用法
-
方式1:Template形式
- 提供
l-painter-view
、l-painter-text
、l-painter-image
、l-painter-qrcode
四种类型组件- 通过
css
属性绘制样式,与 style 使用方式保持一致。(这里需要注意并非所有原生CSS样式都能生效,下面配置项会介绍可传的样式。)
<l-painter>
//如果使用Template出现顺序错乱,可使用`template` 等所有变量完成再显示
<template v-if="show">
<l-painter-view
css="background: #07c160; height: 120rpx; width: 120rpx; display: inline-block"
></l-painter-view>
<l-painter-view
css="background: #1989fa; height: 120rpx; width: 120rpx; border-top-right-radius: 60rpx; border-bottom-left-radius: 60rpx; display: inline-block; margin: 0 30rpx;"
></l-painter-view>
<l-painter-view
css="background: #ff9d00; height: 120rpx; width: 120rpx; border-radius: 50%; display: inline-block"
></l-painter-view>
<template>
</l-painter>
-
方式2:JSON配置形式
- 在 json 里四种类型组件的
type
为view
、text
、image
、qrcode
- 通过
board
设置海报所需的 JSON 数据进行绘制或ref
获取组件实例调用组件内的render(json)
<l-painter :board="poster"/>
const poster = ref({
css: {
// 根节点若无尺寸,自动获取父级节点
width: '750rpx',
},
views: [
{
css: {
background: '#07c160',
height: '120rpx',
width: '120rpx',
display: 'inline-block',
},
type: 'view',
},
{
css: {
background: '#1989fa',
height: '120rpx',
width: '120rpx',
borderTopRightRadius: '60rpx',
borderBottomLeftRadius: '60rpx',
display: 'inline-block',
margin: '0 30rpx',
},
views: [],
type: 'view',
},
{
css: {
background: '#ff9d00',
height: '120rpx',
width: '120rpx',
borderRadius: '50%',
display: 'inline-block',
},
views: [],
type: 'view',
},
],
})
-
配置项
-
Props参数说明
-
CSS
-
事件Events及暴露函数 Expose
实现步骤
-
poster子组件
-
template中编写页面代码
<template>
<wd-popup
v-model="show"
position="bottom"
:z-index="999"
custom-style="background: transparent;"
@close="handleClose"
>
<view class="center flex-col">
<view v-if="show" class="poster">
<l-painter
ref="poster"
css="width: 530rpx;"
:custom-style="`filter: blur(10px);background: rgba(0,0,0,0.4);background-image: url(${info.actInfoImg});background-size: cover;`"
pathType="url"
performance
style="width: 530rpx"
:is-canvas-to-temp-file-path="true"
@fail="painterFail"
@done="painterDone"
@success="painterSuccess"
>
<l-painter-view css="background: #fff;padding: 23rpx 30rpx;margin: 30rpx;">
<l-painter-text
:text="info.actName"
css="font-size: 27rpx; color: #000; line-height: 38rpx; margin-top: 23rpx; line-clamp: 1;"
/>
<l-painter-view css="display: flex; justify-content: space-between; margin-top: 11rpx;">
<l-painter-text
:text="`2024.12.15 19:30 周日`"
css="font-size: 23rpx; color: #777F86; line-height: 27rpx;margin-bottom: 23rpx;"
/>
</l-painter-view>
<l-painter-image
:src="info.actInfoImg"
css="object-fit: cover; object-position: 50% 50%; width: 412rpx; height: 549rpx;border-radius: 15rpx;"
/>
<l-painter-view
css="border-top: 1rpx solid #BCC5CD; margin-top: 23rpx;"
></l-painter-view>
<l-painter-view
css="padding-top: 17rpx; display: flex; justify-content: space-between;"
>
<l-painter-view>
<l-painter-view css="margin-top: 10rpx;">
<l-painter-text
text="保存图片到相册"
css="font-size: 19rpx; color: #777F86; line-height: 27rpx;"
/>
</l-painter-view>
<l-painter-view css="margin-top: 10rpx;">
<l-painter-text
text="扫码可见"
css="font-size: 19rpx; color: #777F86; line-height: 27rpx;"
/>
</l-painter-view>
</l-painter-view>
<l-painter-view css="padding: 7rpx; background: #FFFFFF; border-radius: 7rpx;">
<l-painter-qrcode
css="width: 69rpx; height: 69rpx;"
:text="postCode"
></l-painter-qrcode>
</l-painter-view>
</l-painter-view>
</l-painter-view>
</l-painter>
</view>
<view class="main">
<view class="footer">
<view
class="w-100% h-80rpx bg-#eb1818 color-#fff flex center backdrop-blur-10rpx"
@tap="downloadPoster"
>
保存图片
</view>
</view>
</view>
</view>
</wd-popup>
</template>
-
编写script脚本,保存海报图片地址
海报渲染成功时事件会返回生成图片的地址。注意:需要l-painter组件设置参数:is-canvas-to-temp-file-path="true"
const posterTempFilePath = ref<string>('')
const painterSuccess = (path) => {
posterTempFilePath.value = path
}
其他一些交互上的细节,如生成中、生成失败、关闭海报等。
const painterFail = (e) => {
uni.hideLoading()
uni.showToast({
title: `生成失败,请重试: ${e}`,
icon: 'none',
})
}
const painterDone = () =>{
uni.hideLoading()
}
const handleClose = () => {
show.value = false
}
watch(
() => show.value,
(val) => {
if (val) {
uni.showLoading({ title: '海报生成中', mask: true })
} else {
posterTempFilePath.value = ''
}
},
)
-
保存海报图片到本地
注意本次是在微信小程序上运行,不适用H5下载的情况。
const downloadPoster = () => {
uni.saveImageToPhotosAlbum({
filePath: posterTempFilePath.value,
success(res) {
uni.showToast({
title: '已保存到相册',
icon: 'success',
duration: 2000,
})
},
fail: (err) => {
uni.showToast({
title: `保存失败: ${JSON.stringify(err)}`,
icon: 'none',
})
},
})
}
实现效果
点击顶部导航栏分享按钮,开始生成海报:
编辑
允许保存图片到相册:
编辑
保存图片成功:
编辑
细节注意
- 当需要设置海报背景毛玻璃效果时,不能通过传参css设置filter,因为该插件所支持的CSS样式有限。若需要自定义样式,需要在l-painter传参数custom-style。注意:该参数样式作用于canvas 父view元素。
- 虽然在custom-style上设置filter目前视觉效果还可以,但是下载图片会发现海报丢失细节。建议在css参数中设置的背景图即为毛玻璃效果后的图片。或者用渐变背景色替代。
- 二维码
text
属性是需要生成二维码的文本 - 使用网络图片时:小程序需要去公众平台配置 downloadFile 域名,H5 需要决跨域问题
- 更多细节可查看插件详情:海报画板 - DCloud 插件市场
以上就是使用lime-painter生成海报的介绍啦^-^