更新记录
1.1.0(2026-02-05) 下载此版本
✨ 新增功能
- 二维码集成:内置 weapp-qrcode.js 库,无需额外依赖
- 支持
colorDark和colorLight自定义二维码颜色 - 支持 L/M/Q/H 四种纠错等级配置
- 智能计算二维码版本和容量
- 二维码实例缓存机制,避免重复创建
- 支持
平台兼容性
uni-app(5.0)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | √ | √ | √ | - | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | - | - | - | - | - | - | - | - | - | - | - |
uni-app x(4.87)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
cl-fastPoster
告别手动计算坐标,用 JSON 配置一键生成高清海报
基于 JSON 配置驱动的 Canvas 海报生成组件,支持流式布局
核心亮点: 传统 Canvas 绘图需要手动计算每个元素的 x、y 坐标,代码繁琐易出错。cl-fastPoster 采用类 CSS 的流式布局引擎,只需配置 JSON,自动完成坐标计算、二维码生成、高清导出,让海报生成像写配置文件一样简单。
✨ 特性
- 🎨 JSON 驱动 - 使用声明式 JSON 配置生成海报
- 📐 流式布局 - 类似 CSS 的相对定位和流式排版
- 📱 单位自适应 - 输入 rpx,自动转换 px,支持高清导出
- 🖼️ 异步资源 - 自动下载网络图片并缓存
- 📱 二维码集成 - 内置 weapp-qrcode.js,支持自定义颜色和纠错等级
- 🎯 高清导出 - 支持自定义 pixelRatio,导出 2x/3x 高清图片
- 🔄 框架兼容 - 支持 Vue2、Vue3、小程序、App
📦 安装
将 cl-fastPoster 文件夹复制到项目的 uni_modules 目录下。
🚀 快速开始
基础使用
<template>
<view>
<button @click="generatePoster">生成海报</button>
<image v-if="posterPath" :src="posterPath" mode="widthFix" />
<cl-fast-poster
ref="poster"
:list="posterConfig"
@success="onSuccess"
@error="onError"
/>
</view>
</template>
<script>
export default {
data() {
return {
posterPath: '',
posterConfig: [
{
type: 'container',
style: {
padding: 40,
backgroundColor: '#ffffff'
},
children: [
{
type: 'text',
content: 'Hello FastPoster!',
style: {
fontSize: 48,
color: '#333333',
fontWeight: 'bold'
}
}
]
}
]
};
},
methods: {
generatePoster() {
this.$refs.poster.generate();
},
onSuccess(path) {
this.posterPath = path;
console.log('海报生成成功:', path);
},
onError(err) {
console.error('海报生成失败:', err);
}
}
};
</script>
📖 API 文档
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| list | Array | [] | 海报配置数据 |
| canvasId | String | 'fast-poster-canvas' | Canvas ID |
| width | Number | 750 | 画布宽度(rpx) |
| height | Number | 1334 | 画布高度(rpx) |
| pixelRatio | Number | 2 | 导出图片像素比 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
| success | (path: string) | 生成成功,返回临时文件路径 |
| error | (error: Error) | 生成失败,返回错误信息 |
Methods
| 方法名 | 参数 | 说明 |
|---|---|---|
| generate | - | 开始生成海报 |
🎯 配置项详解
Element 类型
1. Container(容器)
{
type: 'container',
style: {
width: 750, // 宽度(rpx)
padding: 40, // 内边距(rpx),支持数组 [top, right, bottom, left]
backgroundColor: '#fff', // 背景颜色
borderRadius: 20, // 圆角(rpx)
flexDirection: 'column', // 布局方向:'column' | 'row'
marginTop: 20, // 外边距(rpx)
marginBottom: 20
},
children: [] // 子元素数组
}
2. Image(图片)
{
type: 'image',
src: 'https://example.com/image.jpg', // 图片地址(支持网络/本地)
style: {
width: 200, // 宽度(rpx)
height: 200, // 高度(rpx)
borderRadius: 100, // 圆角(rpx),设置为宽度一半可实现圆形
mode: 'aspectFill', // 裁剪模式
marginTop: 20
}
}
3. Text(文本)
{
type: 'text',
content: '这是一段文本',
style: {
fontSize: 32, // 字体大小(rpx)
color: '#333333', // 文字颜色
width: 600, // 文本容器宽度(rpx)
lineClamp: 2, // 最多显示行数,超出显示省略号
lineHeight: 48, // 行高(rpx)
fontWeight: 'bold', // 字重:'normal' | 'bold'
textAlign: 'left', // 对齐:'left' | 'center' | 'right'
marginTop: 20
}
}
4. QRCode(二维码)
{
type: 'qrcode',
content: 'https://example.com', // 二维码内容
style: {
width: 200, // 二维码大小(rpx)
height: 200, // 高度(通常与宽度相同)
colorDark: '#000000', // 前景色(二维码颜色)
colorLight: '#FFFFFF', // 背景色
correctLevel: 'H', // 纠错等级:'L' | 'M' | 'Q' | 'H'
marginTop: 20
}
}
纠错等级说明:
L:约 7% 的字码可被修正M:约 15% 的字码可被修正Q:约 25% 的字码可被修正H:约 30% 的字码可被修正(推荐,适合品牌 logo 覆盖)
🎨 完整示例
电商商品海报
const posterConfig = [
{
type: 'container',
style: {
width: 750,
backgroundColor: '#f5f5f5',
padding: 30
},
children: [
// 背景图
{
type: 'image',
src: 'https://example.com/bg.jpg',
style: {
width: 690,
height: 800,
borderRadius: 20,
marginBottom: 20
}
},
// 商品信息容器
{
type: 'container',
style: {
backgroundColor: '#ffffff',
padding: 30,
borderRadius: 20
},
children: [
// 头像和店铺名
{
type: 'container',
style: {
flexDirection: 'row',
marginBottom: 20
},
children: [
{
type: 'image',
src: 'https://example.com/avatar.jpg',
style: {
width: 80,
height: 80,
borderRadius: 40,
marginRight: 20
}
},
{
type: 'container',
children: [
{
type: 'text',
content: '店铺名称',
style: {
fontSize: 32,
color: '#333333',
fontWeight: 'bold',
marginBottom: 10
}
},
{
type: 'text',
content: '欢迎光临',
style: {
fontSize: 24,
color: '#999999'
}
}
]
}
]
},
// 商品标题
{
type: 'text',
content: '【新品】这是一个非常长的商品标题,可能会换行显示,超过两行会显示省略号',
style: {
fontSize: 36,
color: '#333333',
fontWeight: 'bold',
lineClamp: 2,
lineHeight: 52,
marginBottom: 20
}
},
// 价格
{
type: 'container',
style: {
flexDirection: 'row',
marginBottom: 30
},
children: [
{
type: 'text',
content: '¥',
style: {
fontSize: 32,
color: '#ff4444',
fontWeight: 'bold'
}
},
{
type: 'text',
content: '99.00',
style: {
fontSize: 56,
color: '#ff4444',
fontWeight: 'bold'
}
},
{
type: 'text',
content: '¥199.00',
style: {
fontSize: 28,
color: '#999999',
marginLeft: 20
}
}
]
},
// 分割线容器
{
type: 'container',
style: {
height: 1,
backgroundColor: '#eeeeee',
marginBottom: 30
}
},
// 二维码提示
{
type: 'container',
style: {
flexDirection: 'row'
},
children: [
{
type: 'container',
style: {
flex: 1
},
children: [
{
type: 'text',
content: '长按识别二维码',
style: {
fontSize: 28,
color: '#666666',
marginBottom: 10
}
},
{
type: 'text',
content: '立即购买',
style: {
fontSize: 32,
color: '#333333',
fontWeight: 'bold'
}
}
]
},
{
type: 'qrcode',
content: 'https://example.com/product/123',
style: {
width: 180,
height: 180,
colorDark: '#000000',
colorLight: '#FFFFFF',
correctLevel: 'H'
}
}
]
}
]
}
]
}
];
💡 核心原理
1. 单位系统
- 输入:rpx(响应式像素)
- 转换:
px = rpx * (systemInfo.windowWidth / 750) - 导出:
实际像素 = px * pixelRatio
2. 布局引擎
预计算阶段(Pre-layout)
├── 递归遍历 JSON 树
├── 计算每个元素的尺寸(width, height)
├── 计算相对坐标(x, y)
└── 生成布局树(Computed Tree)
绘制阶段(Draw)
├── 遍历布局树
├── 按计算好的坐标绘制
└── 导出高清图片
3. 流式布局
在 column 模式下:
- 每个元素的 Y 坐标 = 上一个元素底部 + 当前元素 marginTop
- 容器高度 = 所有子元素高度之和 + padding
4. 异步资源
- 收集所有网络图片 URL
- 使用
Promise.all批量下载 - 缓存到 localImageMap
- 绘制时使用本地路径
⚠️ 注意事项
- 高清导出:默认
pixelRatio=2导出 2 倍图,移动端推荐设置为 2-3 - 二维码内容:建议使用
correctLevel='H'确保扫码成功率 - 性能优化:大量图片时建议控制尺寸和质量,避免内存溢出
- 平台差异:不同平台的 Canvas API 可能有细微差异
- 文本测量:部分平台不支持
ctx.measureText,组件已做降级处理 - Canvas 尺寸:Canvas 物理尺寸为
逻辑尺寸 * pixelRatio,确保高清显示
🎯 高清图片导出
组件通过以下机制实现高清图片导出:
// 1. Canvas 物理尺寸使用高倍率
<canvas :width="canvasWidth * pixelRatio" :height="canvasHeight * pixelRatio" />
// 2. 导出时指定目标分辨率
uni.canvasToTempFilePath({
width: canvasWidth, // 逻辑像素截取
height: canvasHeight,
destWidth: canvasWidth * 2, // 输出 2 倍图
destHeight: canvasHeight * 2
})
推荐配置:
- 手机端:
pixelRatio: 2(默认) - 高端设备:
pixelRatio: 3 - 打印用途:
pixelRatio: 4
🔧 进阶使用
动态生成配置
methods: {
createPosterConfig(data) {
return [
{
type: 'container',
style: { padding: 30, backgroundColor: '#fff' },
children: [
{
type: 'text',
content: data.title,
style: { fontSize: 36, fontWeight: 'bold' }
},
{
type: 'image',
src: data.imageUrl,
style: { width: 690, height: 400, marginTop: 20 }
},
{
type: 'qrcode',
content: data.qrUrl,
style: {
width: 200,
height: 200,
colorDark: '#000000',
colorLight: '#FFFFFF',
correctLevel: 'H',
marginTop: 20
}
}
]
}
];
},
async loadDataAndGenerate() {
const data = await this.fetchProductData();
this.posterConfig = this.createPosterConfig(data);
await this.$nextTick();
this.$refs.poster.generate();
}
}
自定义二维码样式
// 黑色二维码(默认)
{
type: 'qrcode',
content: 'https://example.com',
style: {
width: 200,
height: 200,
colorDark: '#000000',
colorLight: '#FFFFFF',
correctLevel: 'H'
}
}
// 品牌色二维码
{
type: 'qrcode',
content: 'https://example.com',
style: {
width: 200,
height: 200,
colorDark: '#ff6b35', // 橙色前景
colorLight: '#fff9f5', // 浅橙背景
correctLevel: 'H'
}
}
保存到相册
methods: {
async savePoster() {
try {
await uni.saveImageToPhotosAlbum({
filePath: this.posterPath
});
uni.showToast({ title: '保存成功' });
} catch (err) {
console.error('保存失败:', err);
uni.showToast({ title: '保存失败', icon: 'none' });
}
}
}
🐛 常见问题
1. 二维码不显示?
- 检查
content是否为空 - 确认
width和height设置正确 - 查看控制台是否有 QRCode 错误日志
2. 图片模糊?
- 提高
pixelRatio(默认为 2,可设置为 3) - 确保原始图片分辨率足够高
- 检查 Canvas 尺寸是否正确
3. 第一次生成白屏?
- 已通过延迟初始化修复(100ms Canvas 初始化 + 500ms 导出延迟)
- 如仍有问题,可适当增加延迟时间
4. 内容被截断?
- 确保
canvasToTempFilePath的width/height使用逻辑像素 destWidth/destHeight使用物理像素(逻辑像素 * pixelRatio)
📚 技术栈
- 二维码生成:weapp-qrcode.js(内置)
- Canvas API:uni-app Canvas 2D 上下文
- 布局引擎:自研流式布局算法
- 图片处理:uni.downloadFile + uni.canvasToTempFilePath
📄 License
MIT

收藏人数:
下载插件并导入HBuilderX
下载示例项目ZIP
赞赏(0)
下载 7140
赞赏 33
下载 11213464
赞赏 1856
赞赏
京公网安备:11010802035340号