在小程序界里,生成图片分享到朋友圈这个功能,是如此得光芒耀眼,以至于各个小程序都趋之若鹜地前来跪倒在她的石榴裙下。不幸的是,微信爸爸并没有提供给我们很好很便捷的相关工具;恰恰相反,屏幕截屏的功能被残忍丢进历史的垃圾桶,只留下一个Canvas组件以及围绕在其周围的深渊巨坑们。
所以我们准备了一套名为Painter的工具, 为开发者提供一种简单实用的“绘制”图片的解决思路,让开发者可以自由地生成自己想要的图片文件。
github传送门: github.com/Kujiale-Mob…
如果直接使用canvas进行绘图,那绝对是很酸爽的一次体验,除了失控的代码,还有无数的天坑。先来列举一下canvas 中踩过的坑以及我们的解决(或绕过)的方法。
canvas的坑painter从实现上来讲,是用了小程序的canvas作为载体来实现以上功能的。而canvas有很多著名的坑。有的坑,我们小心翼翼地绕了过去;有的坑,我们还是痛快淋漓地一脚踩了下去……
在微信版本6.6.6的某些ios机型上,canvas的clip()方法不能被restore。导致在这些机型上无法进行切圆角的操作。迫于无奈在开发中我们不得已抛弃了这些机型,用了一个if语句将这些机器的切圆角功能阉割了。。。
小程序的canvas提供了measuretText()方法,暂时只支持测量文本宽度,无法知道文字的具体高度。因此一些元素对齐的需求无法做到很漂亮。
在绘制图片的时候,有几率会发生很神奇的表现,即canvas绘图的时候位置出现整体偏差,造成最后生成的图片有残缺。这种情况大多数时候发生在onLoad中调用painter的情况下。我们处理的方法是对图片的宽和高比例进行检测,一旦出现异常,就重新绘制一遍。
canvas不能绘制网络图片。canvas.drawImage(url)方法,给url传入一个网络链接,在模拟器上表现完美,然而在真机上无法绘制。我们在Painter中引入了一套自己的网络图片下载后绘制的机制,并在其中加入了LRU存储管理机制。
canvas是原生组件,始终位于视图的最上层,z-index设置对其无效。这个就不多说了。。很多人应该都踩过。
canvas要进行绘制,则canvas组件必须真实地被写在页面上,而且其wx:if不能为false。不过,允许把canvas组件放置在屏幕之外,如设置position:fixed;left:750rpx;。这一方法是可以解决5,6两点问题的黑科技
Painter的功能如图所示
通过右边的类似于css又有点像json但其实上它是个js的寥寥几行代码,我们绘制出了左边的这样的图形,包含了背景图片、文字、图片、二维码这四种常用的元素。
Painter阅读完代码,绘制成图片以后,会将图片的链接返回给我们。此时,我们可以将图片上传、保存到本地或者显示在屏幕上。
它可以很方便地定制所需要的图片,还可以自由动态地给图片更换风格。
此外,小程序canvas.drawImage()方法在真机上不能绘制网络图片。而Painter 可以解决这个问题,如果有绘制网络图片的需求也可以考虑使用Painter。
Painter其它优势
painter可以下载网络图片到本地,并对下载到本地的网络内容进行LRU管理。目前小程序允许的最大本地储存为10m,我们默认painter可使用的本地存储为6m,超出时会对本地存储进行清理。如果需要自定义,可以在/painter/lib/downloader.js中修改MAX_SPACE_IN_B属性。
目前子 view 的 css 属性支持 object 或 array。允许将几个view公用的css属性提取出来。
由于palette 是以 js 承载的 json,所以你可以在每一个属性中很方便的加上自己的逻辑。也可以把某些属性单独提取出来,让多个 palette 共用,做到模块化。
使用 demo下载demo项目使用submodule的方式进行管理,因此在clone时需要运行
git clone https://github.com/Kujiale-Mobile/Painter.git --recursiveclone完成后可以看到目录。其中,/pages/example中存放的是使用示例,/components/painter就是我们所引入的功能组件。此外还有一个palette目录,里面存放是我们所需要绘图代码。实际工作时,painter会调取card.js里的信息,在图片上绘制出相应的图形,就像一支画笔在调色板上调制蘸取了颜料,然后在画布上创作一样。
将Painter引入到自己的项目