小程序分享海报绘制神器 - Painter
由于最近接触到商务类型的小程序开发较多,其中必不可少的一个功能就是小程序分享海报的绘制,海报绘制无非就是将元素在 canvas 上绘制并生成图片,常用的方法有 Wxml2Canvas 及 Painter。由于 Wxml2Canvas 的局限性较大,而且绘制出来的效果比较一般,如果较为简单的海报可以尝试使用,本文着重分享一下 Painter 以及使用方法。
Painter 的原理相当于我们把需要出现在画板的元素列出来传给 Painter,它就会调用 Pen 去将元素一一绘制出来。Painter 支持绘制的格式有 text(文本)、image(图片)、rect(矩形)、qrcode(二维码)。
并且 Painter 的强大在于它不仅可支持圆角、阴影、边框、渐变色的绘制,还可支持旋转(rotate)、分辨率调整,功能十分强大,可满足业务中的大部分需求。相关文档及安装方式:https://github.com/Kujiale-Mobile/Painter
Painter 中的元素基本都是以绝对定位形式存在的,但也可支持相对定位,操作起来也不麻烦,只需要给相对元素设置一个 id,后续元素即可根据该元素进行相对偏移。至于元素的层级关系,由于 Painter 中没有 z-index 用于控制层级,所以采用的方式是出现在后面的元素则层级较高。
下面简单给一个 demo,方便读者理解:
// wxml 文件 // drawPosterData 相当于画板上的元素,需要手动配置 // widthPixels 为生成的图片的像素宽度,如不传则根据模版动态生成 // sharePosterDone 当 canvas 绘制完毕时会触发该钩子函数,通过读取 res.detail.path 可获取生成图片的临时存储路径 // tips: 该组件会占用一定空间,可根据实际布局将该组件隐藏。本项目中将其宽高都设置为 0,position 改为 absolute,达到隐藏效果 <painter-2d palette="{{drawPosterData}}" bind:imgOK="sharePosterDone" widthPixels="1080" class="hidden" />
palette 配置 demo:
export const initPosterConfig = function(data) { const config = Object.create(null) config.background = '#000000' config.width = '540rpx' config.height = '958rpx' config.views = [ // background image { type: 'image', url: 'https://cloud-minapp-37887.cloud.ifanrusercontent.com/1lJ5j1YODUdcYLH3.jpg', css: { width: '100%', height: '100%', top: '0', }, }, // cover image { type: 'rect', css: { width: '394.3rpx', height: '302.3rpx', top: '196rpx', left: '76rpx', rotate: '7', color: '#FFFFFF', shadow: '0px 10px 15px rgba(119, 7, 9, 0.25)', }, }, { type: 'image', url: data.cover_image, css: { width: '371.78rpx', height: '279.76rpx', top: '207.44rpx', left: '87.44rpx', rotate: '7', mode: 'scaleToFit', }, }, // user info { type: 'image', url: data.created_by.avatar, css: { width: '76rpx', height: '76rpx', borderRadius: '100%', top: '542rpx', left: '104rpx', }, }, { type: 'text', text: data.created_by.nickname, css: { top: '554rpx', left: '196rpx', color: '#606060', fontSize: '21rpx', lineHeight: '30rpx', fontWieght: 'bold', // width: '200rpx', // maxLines: '1', }, }, // rank { type: 'text', text: 'No.' + `${data.serial_number}`.padStart(5, 0), css: { top: '586rpx', left: '198rpx', fontSize: '22rpx', lineHeight: '30rpx', color: '#D8D7D7', fontWeight: 'bold', }, }, // congratulation { type: 'text', text: data.congratulation.split(',').join('\n'), css: { top: '632rpx', left: '104rpx', fontSize: '40rpx', lineHeight: '50rpx', maxLines: '2', color: '#BC8D92', }, }, // tips { type: 'text', text: '识别二维码进入活动\n为她点赞', css: { top: '796rpx', left: '104rpx', fontSize: '18rpx', lineHeight: '30rpx', maxLines: '2', color: '#606060', }, }, // 分享二维码 { type: 'image', url: data.qrcode, css: { width: '124rpx', height: '124rpx', right: '22rpx', bottom: '32rpx', borderRadius: '100%', borderWidth: '4rpx', borderColor: '#FFFFFF', }, }, ] return config }
至于 config 的配置,根据设计稿来完成就行啦。绘制完成后拿到临时存储路径,用个 image 标签将图片展示即可。图片保存请参考微信官方文档 wx.saveImageToPhotosAlbum。
放几个 demo 展示效果: