绘制海报工具简述
- 创建绘制海报
canvas
矩形方法,内置了图片绘制,圆角矩形绘制,换行字体绘制等方法。 - 接近原生开发体验,上手快,只需考虑业务逻辑,而不用考虑其他问题。
- 拥有良好的语法架构,不会在绘制
uni/wx
矩形时陷入回调地狱。 - 支持原生小程序,与
uniapp
多端应用。当是环境为原生小程序时,自动切换为性能更好的type2d
绘制方式。 - 将复杂的逻辑组合为简单的方法,扩展性强,可使用
use|useCtx
引入扩展。 - 支持
typescript
,支持vue3
模板,具体使用参考 useDrawPoster。
api文档:uni-draw-poster
npm 安装插件
npm i --save-dev uni-draw-poster
开启对该插件的uni条件编译(重要)
// vue.config.jsmoduleexports = transpileDependencies: 'uni-draw-poster';
1. 创建海报绘制工具
<!-- #ifdef MP-WEIXIN --><!-- #endif --><!-- #ifndef MP-WEIXIN --><!-- #endif -->
// 注意:如果使用HBuilder引入, 需要引入 '@/js_sdk/draw-poster'async { // 传入选择器, 初始化绘制工具(注意, 不需要传入#符号) 当微信小程序时, 将自动启用type2d绘制 const dp = await DrawPoster }
2. 设置画布尺寸
// 设置长高为100px的矩形宽高dpcanvaswidth = 100dpcanvasheight = 100
3. 绘制任意内容
// 绘制背景与文字dp// 绘制图片内容dp
值得注意的是, draw
方法会自动的执行ctx.save/ctx.restore
, 不需要人为操纵绘画栈.
dp// 相当于ctx/* ... */ctx
4. 进行绘制
dp.draw
并不会马上绘制,只是将该任务添加到了任务栈,需要使用dp.awaitCreate
函数进行绘制,该函数在绘制完毕后将弹出所有任务。
dp.awaitCreate
在非2d
绘画中,执行绘画任务完毕后,将自动执行ctx.draw
方法,并在draw绘画才算异步结束。
dpdp// 由于每个任务都有可能会有异步的绘制任务, 所以得需要使用await等待绘制const result = await dp;// 绘制成功将返回每个任务的绘制状况组成的数组console; // draw绘制状况: [true]
5. 生成图片本地地址
如需要保存为图片时,可以使用dp.createImgUrl
进行创建图片本地地址,在由wx
或uni
的api
进行保存。
dpconst result = await dp;const posterImgUrl = await dp;console; // [true]console; // ...tmp...
你也可以不使用dp.awaitCreate
方法,当调用dp.createImagePath
时会自动检测任务列表,如果有则执行绘制任务后在创建地址。
dp// 跳过drawPoster.awaitCreate直接生成地址const posterImgUrl = await dp;console;
绘制扩展 API
drawPoster
在创建时,会自动的向ctx(画笔)
添加/覆盖扩展方法,以便构建海报矩形。
dp
绘制图片(ctx.drawImage)
ctx.drawImage(url, x, y, w, h)
drawPoster
绘制图片与原生绘制不相同,ctx.drawImage
内部已经内置了downloadFile
,只需要传入本地/网络地址即可。支持2d
与非2d
绘制,绘制方式一致。需要await等待绘制。
注意:当绘制环境为H5时,uniapp使用本地图片绘画时不要用尺寸较大的图片,不然会在创建图片时生成失败。
dp
参数 | 描述 |
---|---|
url | 网络图片地址,或本地/static 中图片路径。 |
x,y | 图片的左上角的坐标。 |
width,height | 图片的大小。 |
换行字体(ctx.fillWarpText)
ctx.fillWarpText(options)
传入配置对象,绘制换行字体,以下为可配置项。
interface FillWarpTextOpts // 绘制字符串, 必传项 text: string; // 绘制最长高度, 默认100px maxWidth?: number; // 绘制行高, 默认取当前字体的默认宽度 lineHeight?: number; // 绘制行数量, 默认限制为2层 layer?: number; // 绘制x轴, 默认0 x?: number; // 绘制y轴, 默认0 y?: number; // 设置换行字符, 默认为空, 如设置, maxWidth|layer 将会失效 splitText?: string; // 是否不马上进行绘制 notFillText?: boolean;// 当 `notFillText` 为 `true` 时,则不进行绘制,该函数将返回一个绘制信息队列// 用于代表每行字体所对应的绘制信息, 以下是返回的结构信息,你可以用于计算该// 换行字体的宽度,也你可以使用array.forEach与ctx.fillText进行绘制。 text: string y: number x: number // ....
圆角矩形(ctx.fillRoundRect)
ctx.fillWarpText(x, y, w, h, r)
dp
参数 | 描述 |
---|---|
x,y | 矩形的左上角的坐标。 |
width,height | 矩形的大小。 |
r | 矩形的弧度半径。 |
圆角矩形边框(ctx.strokeRoundRect)
ctx.strokeRoundRect(x, y, w, h, r)
参数 | 描述 |
---|---|
x,y | 矩形的左上角的坐标。 |
width,height | 矩形的大小。 |
r | 矩形的弧度半径。 |
圆角图片(ctx.drawRoundImage)
ctx.drawRoundImage(url, x, y, w, h, r)
dp;
参数 | 描述 |
---|---|
url | 网络图片地址,或本地/static 中图片路径。 |
x,y | 图片的左上角的坐标。 |
width,height | 图片的大小。 |
r | 图片的弧度半径。 |
绘制二维码(ctx.drawQrCode)
生成二维码扩展,源码使用了 uQRCode 并改动了一下,该文件比较大,所以作为扩展插件使用,使用时得先引入插件。
// 注意:如果使用HBuilder引入, 需要引入 '@/js_sdk/draw-poster'// 引入绘制二维码插件DrawPoster async { const dp = await DrawPoster dpcanvaswidth = 200; dpcanvasheight = 200 ctx;}
参数 | 类型 | 必填 | 说明 |
---|---|---|---|
x | number | 否 | 水平方向偏移长度 |
y | number | 否 | 垂直方向偏移长度 |
text | String | 是 | 二维码内容 |
size | Number | 否 | 画布尺寸大小,请与 <canvas/> 所设 width , height 保持一致(默认:354 ) |
margin | Number | 否 | 边距,二维码实际尺寸会根据所设边距值进行缩放调整(默认:0 ) |
backgroundColor | String | 否 | 背景色,若设置为透明背景, fileType 需设置为 'png' , 然后设置背景色为 'rgba(255,255,255,0)' 即可(默认:'#ffffff' ) |
foregroundColor | String | 否 | 前景色(默认:'#000000' ) |
errorCorrectLevel | Number | 否 | 纠错等级,包含 errorCorrectLevel.L 、errorCorrectLevel.M 、errorCorrectLevel.Q 、errorCorrectLevel.H 四个级别,L : 最大 7% 的错误能够被纠正;M : 最大 15% 的错误能够被纠正;Q : 最大 25% 的错误能够被纠正;H : 最大 30% 的错误能够被纠正。 |
全局实例 API
绘画构建(DrawPoster.build)
DrawPoster.build(string|object)
初始化构建绘制工具,传入查询字符串与配置对象,当配置字符串时,则直接查询该字符串的canvas
,当配置对象时,object.selector
则为必选项,以下是options
的配置项,需要注意的是,返回值为Promise
,返回绘制构建对象dp
。
/** DrawPoster.build 构建配置 */interface DrawPosterBuildOpts // 查询字符串(必须), 注意不要写错对应canvas id, 不需要传入#符号 selector: string; // 选取组件范围 componentThis?: any; // 类型为2d绘制, 默认开启, 在微信小程序的时候动态加载 type2d?: boolean; // 是否在绘制的过程中, 显示加载框, 默认关闭 loading?: boolean // 当存在绘制图片时, 等待绘画完毕的时间(毫秒),仅在App中生效 drawImageTime?: 100 // 加载提示文字 loadingText?: '绘制海报中...' // 创建图片加载提示文字 createText?: '生成图片中...'
多绘画构建(DrawPoster.buildAll)
DrawPoster.buildAll(Array<string|object>)
构建多个绘画工具,传入build函数中参数string | options构成的数组,返回多个绘制工具组成的对象。key为canvasId,value为构建对象。
挂载全局扩展(DrawPoster.use)
DrawPoster.use(object)
传入挂载配置对象,添加全局扩展方法,一般可用于海报绘制模板的封装,在不同页面有一样的海报模板时可以有效的减少代码量,使用方式如下。
一、在任意位置添加扩展(建议放在main.js
中执行)
// 全局添加绘制个人海报的扩展实现DrawPoster
二、页面中使用自定义扩展
async { const dp = await DrawPoster dpcanvaswidth = 100; dpcanvasheight = 100 const posterImg = await dp}
挂载绘制扩展(DrawPoster.useCtx)
DrawPoster.useCtx(object)
传入挂载配置对象,添加全局绘制扩展方法,用于自定义绘制方法的定义,使用方式如下。
一、在任意位置添加扩展(建议放在main.js
中执行)
// 全局添加绘制二维码的绘画扩展实现DrawPoster;
二、绘制中使用自定义扩展
dp
绘制节点(dp.canvas)
dp.canvas | dp.canvas.width | dp.canvas.height | ...
dp.canvas
为全局的绘制根节点,在微信小程序中拥有独享API
。在其他端将作为全局宽高容器使用。当dp.createImagePath
未传入参数时,默认使用 dp.canvas.width | dp.canvas.height
创建图片,以下是dp.canvas
对象中存在的api
与属性。
interface Canvas width: number; height: number; // 剩余参数为微信小程序独享API,只有微信小程序才拥有的API // 具体参考微信小程序文档:https://developers.weixin.qq.com/miniprogram/dev/api/canvas/Canvas.html
创建绘制(dp.draw)
dp.draw(async callback(ctx))
绘制器, 接收执行器函数, 添加到绘制容器中,可改装为异步函数处理图片绘制,也可以为同步函数。
全局画笔(dp.ctx)
dp.ctx
全局绘制画笔,特殊情况可以使用,推荐只使用dp.draw
函数进行绘制。
等待绘制(dp.awaitCreate)
dp.awaitCreate()
异步绘制绘制器堆栈,成功后清空绘制器容器,返回成功堆栈状况的数组(boolean[]
)。
停止绘画(dp.stop)
dp.stop()
停止当前绘画栈,调用后将停止dp.awaitCreate |dp.createImagePath
的执行。
创建图片(dp.createImagePath)
dp.createImagePath(options)
创建当前canvas
绘制后的本地图片地址,如绘制器堆栈未清空时,会自动调用dp.awaitCreate()
清空堆栈。createImagePath
会根据 canvas.width
与 canvas.height
进行创建图片。如果你想自定义参数,awaitCreate
方法可以接受一个配置对象,返回图片地址,以下为可配置项。
interface CreateImagePathOptions x?: number; y?: number; width?: number; height?: number; destWidth?: number; destHeight?: number;
常见问题
微信小程序手机浏览空白
微信小程序绘制如果有图片绘制,手机浏览需要在后台添加downloadFile
域名,并需要重启开发者工具。
微信小程序无法真机调试
https://developers.weixin.qq.com/community/develop/doc/000eece1640d608df21bb19055b000
H5 端图片裁剪异常
H5 端绘制两个以上的ctx.drawRoundImage
圆角图片时,创建的本地base64
显示异常,建议当环境是h5
时,将圆角图片限制为一个,或者uni
动态编译展示img
标签。
绘制完毕后没有效果
注意DrawPoster.build
无法检测你所选择canvasId
的是否正确,所以一定要确保与canvas-id
和html
中的canvas
相同,在小程序端,由于会自动切换为type2d
,必须得加上动态编译。
<!-- #ifdef MP-WEIXIN --><!-- #endif --><!-- #ifndef MP-WEIXIN --><!-- #endif -->
绘制多个图片加载慢
如果觉得多个图片绘制await
加载慢,可以使用Promise.all
将一部分不需要处理图层覆盖的图片进行同步绘制。
dp;
需要注意的是:ctx.drawRoundImage
不可以放在Promise.all
当中,由于ctx.drawRoundImage
内部会调用ctx.clip
方法,在Promise.all
中会与其他图片绘制产生冲突。从而导致圆角失效。
我的博客:Mr.Mao'blog
联系方式:951416545@qq.com