微信小程序朋友圈分享图片生成方案实现

在小程序界里,生成图片分享到朋友圈这个功能,是如此得光芒耀眼,以致于各个小程序都趋之若鹜地前来跪倒在她的石榴裙下。不幸的是,微信爸爸并无提供给咱们很好很便捷的相关工具;偏偏相反,屏幕截屏的功能被残忍丢进历史的垃圾桶,只留下一个Canvas组件以及围绕在其周围的深渊巨坑们。css

因此咱们准备了一套名为Painter的工具, 为开发者提供一种简单实用的“绘制”图片的解决思路,让开发者能够自由地生成本身想要的图片文件。前端

github传送门:github.com/Kujiale-Mob…ios

若是直接使用canvas进行绘图,那绝对是很酸爽的一次体验,除了失控的代码,还有无数的天坑。先来列举一下canvas 中踩过的坑以及咱们的解决(或绕过)的方法。git

canvas的坑

painter从实现上来说,是用了小程序的canvas做为载体来实现以上功能的。而canvas有不少著名的坑。有的坑,咱们当心翼翼地绕了过去;有的坑,咱们仍是痛快淋漓地一脚踩了下去……github

  1. 在微信版本6.6.6的某些ios机型上,canvas的clip()方法不能被restore。致使在这些机型上没法进行切圆角的操做。迫于无奈在开发中咱们不得已抛弃了这些机型,用了一个if语句将这些机器的切圆角功能阉割了。。。
  2. 小程序的canvas提供了measuretText()方法,暂时只支持测量文本宽度,没法知道文字的具体高度。所以一些元素对齐的需求没法作到很漂亮。
  3. 在绘制图片的时候,有概率会发生很神奇的表现,即canvas绘图的时候位置出现总体误差,形成最后生成的图片有残缺。这种状况大多数时候发生在onLoad中调用painter的状况下。咱们处理的方法是对图片的宽和高比例进行检测,一旦出现异常,就从新绘制一遍。
  4. canvas不能绘制网络图片。canvas.drawImage(url)方法,给url传入一个网络连接,在模拟器上表现完美,然而在真机上没法绘制。咱们在Painter中引入了一套本身的网络图片下载后绘制的机制,并在其中加入了LRU存储管理机制。
  5. canvas是原生组件,始终位于视图的最上层,z-index设置对其无效。这个就很少说了。。不少人应该都踩过。
  6. canvas要进行绘制,则canvas组件必须真实地被写在页面上,并且其wx:if不能为false。不过,容许把canvas组件放置在屏幕以外,如设置position:fixed;left:750rpx;。这一方法是能够解决5,6两点问题的黑科技

Painter的功能

如图所示shell

经过右边的相似于css又有点像json但其实上它是个js的寥寥几行代码,咱们绘制出了左边的这样的图形,包含了背景图片、文字、图片、二维码这四种经常使用的元素。json

Painter阅读完代码,绘制成图片之后,会将图片的连接返回给咱们。此时,咱们能够将图片上传、保存到本地或者显示在屏幕上。canvas

它能够很方便地定制所须要的图片,还能够自由动态地给图片更换风格。小程序

此外,小程序canvas.drawImage()方法在真机上不能绘制网络图片。而Painter 能够解决这个问题,若是有绘制网络图片的需求也能够考虑使用Painter。微信小程序

Painter其它优点

  1. painter能够下载网络图片到本地,并对下载到本地的网络内容进行LRU管理。目前小程序容许的最大本地储存为10m,咱们默认painter可以使用的本地存储为6m,超出时会对本地存储进行清理。若是须要自定义,能够在/painter/lib/downloader.js中修改MAX_SPACE_IN_B属性。

  2. 目前子 view 的 css 属性支持 object 或 array。容许将几个view公用的css属性提取出来。

  3. 因为palette 是以 js 承载的 json,因此你能够在每个属性中很方便的加上本身的逻辑。也能够把某些属性单独提取出来,让多个 palette 共用,作到模块化。

使用

demo下载

demo项目使用submodule的方式进行管理,所以在clone时须要运行

git clone https://github.com/Kujiale-Mobile/Painter.git --recursive
复制代码

clone完成后能够看到目录。其中,/pages/example中存放的是使用示例,/components/painter就是咱们所引入的功能组件。此外还有一个palette目录,里面存放是咱们所须要绘图代码。实际工做时,painter会调取card.js里的信息,在图片上绘制出相应的图形,就像一支画笔在调色板上调制蘸取了颜料,而后在画布上创做同样。

将Painter引入到本身的项目

你能够直接将demo里的painter复制粘贴到本身的项目下,固然也能够更为优雅地运行一下这个代码:

git submodule add https://github.com/Kujiale-Mobile/PainterCore.git painter
复制代码

它会将Painter工具放置在你当前的目录下。咱们推荐的作法是把它放在你的components下。

引入组件

像其它的组件同样,在须要引入Painter的页面.json文件中添加:

"usingComponents":{
  "painter":"/components/painter/painter"
}
复制代码

组件调用

在页面的xml文件中调用painter组件,并传入pallete规则的数据,以及绘制结束之后的回调。

<painter palette="{{data}}" bind:imgOK="onImgOK" bind:imgErr="onImgErr"/>
复制代码

palette便是咱们的调色板数据,以json形式根据必定规范建立,详细信息请移步下文。

绘制回调

bind:imgOK="onImgOK"
bind:imgErr="onImgErr"
复制代码

数据传入后,painter就会开始绘制,不管绘制成功或是失败,都能在相应的回调方法里获取相关的信息,如:

Pallette

说到底,Painter是一支画笔工具,具体要让这支画笔画什么东西,还得由咱们,天资聪颖的程序猿们,来告诉它。告诉它应该画什么,在哪里画,画的时候用什么姿式……等等。这须要用一些别的手段,由于科学的实验证实过,试图用普通话这门语言跟它进行沟通,是不会有任何效果的。

调色板属性

每一块调色板都它本身的总体属性,它通常规定了整个绘图范围的大小、样式、背景等

它处于整个json文件的最外层,须要指定如下几个属性:

属性 解释
background 背景,能够是颜色值,也能够是图片连接,支持本地图片连接和网络图片连接
width 宽度
height 高度
borderRadius 圆角
views 须要画在图上的其它元素,容许为空,但不容许省略

示例代码:

{
      background: 'https://qhyxpicoss.kujiale.com/2018/06/12/LMPUSDAKAEBKKOASAAAAAAY8_981x600.png',
      width: '654rpx',
      height: '400rpx',
      borderRadius: '20rpx',
      views: []
 }
复制代码

view属性

画完了调色板的总体属性之后,就能够向views中增长一些元素了。元素支持四种类型,用type字段进行区分分类。不一样种类的view又要求提供有不一样的数据,如image元素须要提供它的url,text元素须要提供text文字内容:

type content description 私有css属性
image url 图片资源地址,本地或网络
text text 文本元素,书写文字 fontSize:字体大小,color:文字颜色
rect 矩形 color:填充颜色
qrcode content 画二维码 background:背景颜色,默认为透明

除了各view的私有属性以外,view还有一些公共属性能够设置:

属性 做用
left, top, right, bottom 元素的位置
rotate 旋转角度,单位为360度的度
borderRadius 圆角,若是须要设置图片为原形,请设置该属性为宽或高的一半
align 元素在水平方向的对齐方式,与left配合使用,可设置为left, center, right,默认为left。
rotate

控制元素的旋转,以下图,将一行文字顺时针旋转了6度。

{
    type: 'text',
    text: '酷家乐 移动前端',
    css: {
     left: '20rpx',
     top: '50rpx',
     fontSize: '40rpx'
   },
},
复制代码

效果:

borderRadius

代码(圆形):

{
          type: 'image',
          url: this.cardInfo.avatar,
          css: {
            top: '48rpx',
            left: '448rpx',
            width: '192rpx',
            height: '192rpx',
            borderRadius:'96rpx',
          },
        },
复制代码

方角-->8rpx圆角-->圆形

align

这个属性值比较有意思,它被用来设置元素在水平方向的、相对于位置设置的对齐方式。

什么意思呢?

好比说你设置了某元素的left为100rpx,并设置align属性为left,那么该元素的左端就与100rpx对齐;若设置align为center,则该元素的中轴线与100rpx对齐。

在下面的例子中,三行文字的left都是230rpx,align分别为left, center, right。红线是横坐标为230rpx的轴线。

即,当设置了align属性的时候,left值表达的是元素属性中align的位置。

代码:

{
          type: 'text',
          text: '酷家乐 移动前端',
          css: {
            left: '330rpx',
            top: '100rpx',
            fontSize: '40rpx',
          },
        },
        {
          type: 'text',
          text: '酷家乐 移动前端',
          css: {
            left: '330rpx',
            top: '200rpx',
            fontSize: '40rpx',
            align: 'center'
          },
        },
        {
          type: 'text',
          text: '酷家乐 移动前端',
          css: {
            left: '330rpx',
            top: '300rpx',
            fontSize: '40rpx',
            align: 'right'
          },
        },
复制代码

有了这个属性,就能够设置元素的对齐形式,完成下面的布局要求了:

注意:align属性请和left属性配合使用,设置right值将形成错误。

align与rotate

当align属性与rotate属性同时存在时,元素的旋转表现是以元素的中心点为中心的。

尺寸单位

目前 Painter 中支持两种尺寸单位,px 和 rpx,表明的意思和小程序中一致。目前尚未很好地支持百分比的使用。

保存图片演示

得到图片的url后,能够设置一个点击按钮,点击保存到本地

onImgOK(e) {
    this.imagePath = e.detail.path;
  },

  saveImage() {
    wx.saveImageToPhotosAlbum({
      filePath: this.imagePath,
    })
  },
复制代码

按钮绑定saveImage方法,点击进行保存:

生成朋友圈分享图

最后,利用Painter工具能够生成不一样样式的朋友圈分享图(下图为微信小程序 酷咖名片 线上版部分截图)

结语

painter是酷家乐前端在小程序的实际开发中自制的一套工具,目前在朋友圈分享、皮肤模板替换等方面都在使用,以为用起来喜忧参半。开源出来你们分享。若是它能帮助到任何一我的,咱们都很是开心;咱们也很是欢迎并感谢提issure或pr,来告诉咱们一些咱们本身没有能想到的东西,或者帮助解决Painter 中的大大小小的坑:

再一次传送门:github.com/Kujiale-Mob…

相关文章
相关标签/搜索