由于最近接触到商务类型的小程序开发较多,其中必不可少的一个功能就是小程序分享海报的绘制,海报绘制无非就是将元素在 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 展示效果:
请发表评论