PosterRender 是什么
PosterRender
是一种专注于生成高质量海报图像的技术或工具
,常用于生成静态图片
,特别是适合用于营销、宣传和展示的图形设计
。它通常用于在服务端或客户端渲染复杂的图像
,包括文字、图形、图标、背景等,生成可供下载或直接使用的最终图片格式(如 PNG 或 JPEG)。
PosterRender 用来做什么
- 营销海报生成:
用于快速生成电商平台的商品促销海报、活动宣传海报等。 - 用户内容分享:
在社交媒体上分享的内容卡片、个人成就海报(如运动记录、学习记录等)。 - 模版化设计:
通过可配置的模板,快速生成批量的海报,适合规模化需求。 - 动态内容渲染:
根据用户数据动态生成个性化的海报,如公众号文章分享页、个人二维码推广图等。
PosterRender 的优点
- 高效性:
能快速生成高质量的图像,特别适合批量任务。 - 灵活性:
支持高度定制化设计,可以通过模板调整文字、颜色、布局等细节。 - 跨平台支持:
可以在服务端或客户端完成渲染,适合多种技术栈(如 Node.js、Python、前端浏览器)。 - 自动化:
可结合动态数据生成个性化内容,减少人工设计成本。 - 高质量输出:
支持高清图片输出,满足打印与显示需求。
PosterRender 的缺点
- 复杂性:
对于初学者来说,模板配置与设计可能存在一定学习成本。 - 性能依赖:
如果在服务端渲染,生成大量高分辨率图片可能消耗较多的计算资源;如果在客户端渲染,可能受限于设备性能。 - 开发成本:
自定义模板和动态渲染的实现需要一定的开发工作量。 - 实时性限制:
对于需要实时生成大量图片的场景(如高并发访问),可能需要额外优化或使用缓存机制。
PosterRender实例
- 实例是结合
taro+react
实现微信小程序分享商品 - 通过样式增加遮照,设置z-index 浮在页面上
- PosterRender list进行x,y轴坐标布局
// 父组件代码import type { QrcodeRenderRef } from '@/components/Qrcode/QrcodeRender';import QrcodeRender from '@/components/Qrcode/QrcodeRender';const ref = useRef<QrcodeRenderRef>(null);<QrcodeRender ref={ref} />
// 子组件代码
import type { ForwardRefRenderFunction } from 'react';
import { forwardRef, useCallback, useImperativeHandle, useRef, useState } from 'react';
import type { PosterRenderRef } from '@poster-render/taro-react';
import { PosterRender } from '@poster-render/taro-react';
import { View } from '@tarojs/components';
import Taro, { pxTransform } from '@tarojs/taro';
import classNames from 'classnames';import { getRoutineCode } from '@/services/promotion';import styles from './styles.modules.less';
//设置海报的宽度和高度
const SIZE = {width: 315,height: 365
};export interface QrcodeRenderRef {// 子组件暴露给父组件的方法open: () => Promise<void>;
}const QrcodeRender: ForwardRefRenderFunction<QrcodeRenderRef> = (_, ref) => {const posterRender = useRef<PosterRenderRef>(null);// const [qrcode, setQrcode] = useState('');const [rendered, setRendered] = useState(false);const [visible, setVisible] = useState(false);const [data, setData] = useState<Promotion.CodeInfo>();// 请求接口 获取要渲染的数据const handleShow = useCallback(async () => {Taro.showToast({title: '正在生成',icon: 'loading',mask: true});const res = await getRoutineCode();if (res?.status !== 200) {Taro.showToast({title: '生成失败,请重试',icon: 'none'});return;}setData(res?.data);setVisible(true);}, []);useImperativeHandle(ref,() => ({open: async () => {handleShow().then().catch();}}),[handleShow]);const onRender = useCallback(async () => {Taro.hideLoading();setRendered(true);}, []);const handleHide = useCallback(async () => {setVisible(false);setRendered(false);}, []);const handleSave = useCallback(() => {posterRender.current?.savePosterToPhoto();}, []);return (<><ViewcatchMoveclassName={classNames({[styles.qrcodeWrap]: true,[styles.qrcodeWrapShow]: rendered})}><View className={styles.masker} onClick={handleHide} /><View className={styles.container}><View className={styles.containerBox}>{visible && (<PosterRenderdisableRerenderref={posterRender}canvasId="taro-poster-render"renderType="image"canvasWidth={SIZE.width}canvasHeight={SIZE.height}debug={false}style={{width: pxTransform(SIZE.width),height: pxTransform(SIZE.height)}}showMenuByLongpressonRender={onRender}onLongTap={handleSave}onRenderFail={(err) => console.error('onRenderFail', err?.message)}onSave={(url) => {console.warn('onSave', url);Taro.showToast({title: '保存成功',icon: 'none',duration: 2000});}}onSaveFail={(err) => console.error('onSaveFail', err?.message)}list={[{type: 'rect',x: 0,y: 0,width: SIZE.width,height: SIZE.height,backgroundColor: '#fff',borderWidth: 7,radius: 16,borderColor: '#00C8C8'},{type: 'image',width: 240,height: 240,backgroundColor: '#333333',src: `${data?.url}`,x: 37,y: 47,radius: 120,mode: 'cover'},{type: 'text',x: (tw) => (SIZE.width - tw) * 0.5,y: 310,text: '长按识别或扫描二维码识别',fontSize: 14,color: '#999999',width: (tw) => tw,height: 19,lineHeight: 19}]}/>)}<View className={styles.desc}>扫描该二维码与您绑定推广关系</View><View onClick={handleSave} className={styles.close}>保存图片</View></View></View></View></>);
};export default forwardRef(QrcodeRender);
// styles.modules.css 代码
}
.qrcodeWrap {position: fixed;top: -100%;left: -200%;z-index: -1;align-items: center;justify-content: center;width: 100%;height: 100%;
}.qrcodeWrapShow {top: 0;left: 0;z-index: 9999999999;
}
.masker {position: absolute;top: 0;left: 0;width: 100%;height: 100%;background-color: rgba(0, 0, 0, 0.6);
}
.container {width: 100vw;height: 100vh;
}.containerBox {position: relative;top: 50%;width: 315px;//height: 503px;margin: 0 auto;transform: translateY(-50%);
}.desc {margin-top: 35px;color: #fff;font-weight: 400;font-size: 14px;font-style: normal;line-height: normal;text-align: center;
}.close {position: absolute;left: 50%;display: flex;align-items: center;justify-content: center;width: 249px;height: 40px;margin-top: 30px;color: #fff;font-weight: 500;font-size: 18px;background-color: @primary-color;border-radius: 249px * 0.5;transform: translateX(-50%);
}