likes
comments
collection
share

2022最新小程序分享海报图完美方案

作者站长头像
站长
· 阅读数 26

前言

大家都知道小程序分享海报图的好处,不然也不会找到这篇文章,但是都苦于没有一套完善、通用、易用的方案,你能搜到的文章也都是一知半解,零零碎碎,我这人最受不了的就是没有章法,今天这篇文章将会彻底解决这个问题。

工欲善其事必先利其器,我要自己撸一个工具,这次不仅要解决,还要完美地解决,用了它,产品上午提出需求要做个分享海报,我们下午吃个饭的功夫就能搞出来,别不信,我来告诉你怎么做到。

CanvasDrawer

没错,这就是这个工具的名字,翻译过来就是Canvas抽屉,为什么不叫CanvasPoster? 因为它的功能不止可以绘制海报,这个我们后面再说。

我们先看一下该工具可以实现的效果:

2022最新小程序分享海报图完美方案

引入工具后,实现这个海报的代码没有超过100行,因为你只需要告诉工具你要绘制的图片或文字的位置,大小,颜色,其他都不用操心,怎么样,有没有引起你的兴趣?

接下来,我带你一步一步了解它,了解之后应用自然也不在话下了。

功能特点

  1. 支持绘制图片

    • 支持可选是否自动切成圆角图片
    • 支持圆角模式下设置边框宽度,以及边框颜色

      该选项针对你要生成二维码的场景极其有用

  2. 支持绘制文本

    • 支持批量绘制文本
    • 支持绘制单行动态文本,并可以自定义文本左右间距

      暂不支持动态文本换行,后续会考虑加入此功能

    • 支持自定义文本颜色、字号、字重、对齐方式

      例如上图中的“共省下69.86元”文案,69.86是动态获取的数据,可能存在6.6的情况,也可能存在6666.66的情况,文本的长度是不确定的,但是不用担心,工具内会自动计算好文本的长度,按你提供的间距自动渲染好位置。

  3. 支持绘制图形

    • 可以绘制简单的圆和矩形,复杂的图形使用图片更好,没必要花费额外的性能去自己绘制
  4. 使用canvas2d实现,支持同层渲染且性能更佳

那么我们如何使用?

使用方法

安装

npm install mp-canvas-drawer --save

先在页面或组件的wxml中添加canvas组件,宽高照你的实际设计稿宽高定义就行,px的话一般就是375的稿,rpx就是750的稿。

<canvas type="2d" id="myCanvas" class="canvas" style="width: {{width}}rpx; height: {{height}}rpx" ></canvas>

在页面或组件中导入,并且初始化

import W2P from 'mp-canvas-drawer'; // W2P是wxml to poster 的缩写,你也可以自己起名

onLoad(){
  this.w2p = new W2P('#myCanvas', this, { bgColor: '#ffffff', radius: 32 });
  this.w2p.init().then(() => {
      this.drawSharePoster(); // 初始化完成后就可以开始画了
  });
}

工具类接受以下参数:

new W2P(canvasId, instance, container, designWindowWidth);
参数说明是否必填
canvasId告知工具要绘制哪个canvas组件
instance页面或组件的实例对象,即this,在页面中使用时可以不传,会默认取wx.createSelectorQuery参见,组件中使用时必传,因为要获取这个实例上的canvas组件
container海报图容器参数,该参数是一个对象,可以设置背景颜色和圆角 {bgColor, radius}
container.bgColor背景颜色,默认'#ffffff'
container.radius添加圆角,默认0
designWindowWidth设计稿尺寸, 默认750,即使用rpx为单位,推荐使用rpx,可以自动适配机型,如果你是375的稿子自己将值乘2就可以了。

开始绘制海报

// 绘制分享海报
async drawSharePoster(){
    // 绘制背景图,填写图片资源,起始点坐标(x, y),宽高
    await this.w2p.drawImage('https://.../a.png', 0, 0, 618, 868);
    
    const adjustTimes = await geAdjustTimes(); // 这里只是举例,使用时动态数据建议提前获取
    
    /* 绘制具有动态文本的行 */
    this.w2p.drawDynamicTextsRow({
      texts: ['2022年,油价经历', adjustTimes, '次调整'], // 该行要绘制的文本
      originX: 48,  // 该行起始x坐标,即文本距离海报容器左边框的距离
      // 以下参数既可作为通用参数,也可作为个性化参数,填写个性化参数后会覆盖通用参数值
      originY: 239, // 该行起始y坐标,即文本距离海报容器上边框的距离
      textMargin: 10, // 文本左间距(从第二个文本开始生效)
      size: 28, // 该行字体大小
      bold: 600, // 文字字重
      color: '#470D00', // 该行文字颜色
    });
    
    /* 绘制动态文本行,并且个性化插入文本 */
    this.w2p.drawDynamicTextsRow({
        texts: [
          { text: '我在XXXX共加油' },
          // 数字样式个性化突出
          { text: useTimes, color: '#F44505', size: 44, originY: 369 },
          { text: '次' },
        ],
        originX: 48, originY: 380, textMargin: 10, size: 28, color: '#470D00'
    });
    
    // 绘制静态文本
    // 参数依次为:文本 | x | y | 字号 | 颜色 | 字重 | 水平对齐方式可选left(不传默认)、center、right| 垂直对齐方式可选top(默认)、middle、bottom
    this.w2p.drawText('长按扫码', 172, 552, 28, '#000000', 600, 'left', 'top' );
    
    // 批量绘制文本
    const texts = [
      { text: '长按扫码', x: 172, y: 552, size: 28, bold: 500, color: '#000000' },
      { text: '查看你的城市油价排名', x: 172, y: 592, size: 28, bold: 600, color: '#eeeeee' },
    ];
    this.w2p.drawTexts(texts);
    
    // 给图片绘制边框(二维码场景常用)
    // 参数依次为:图片链接 | x | y | 宽 | 高 | 是否切成圆形 | 圆形模式下边框宽度| 圆形模式下边框颜色
    await this.w2p.drawImage('https://.../qrcode.png', 48, 516, 104, 104, true, 20, '#ffffff');
    
    // 绘制简单的圆形
    // 参数依次为:x | y | 半径 | 颜色 | 样式可选填充fill(默认)、线stroke
    this.w2p.drawCircular(123, 456, 20, color = '#ffffff', 'fill')

    // 绘制简单的矩形
    // 参数依次为:x | y | 宽 | 高 | 圆角默认0 | 颜色 | 样式可选填充fill(默认)、线stroke
    this.w2p.drawRect(123, 456, 40, 40, 6, color = '#666666', 'stroke')

}

添加二维码边框后效果如图:

2022最新小程序分享海报图完美方案

注意: 如果你使用750的设计稿,那你传给工具的所有参数都要是以750位基准的rpx值

到这里,这个工具的绘制功能就讲完了,是不是迫不及待想去试一试了,别急,前面只是说了它的canvas绘制能力,还有一部分配套功能可以让你再少写些代码。

如果仅绘制不需要分享场景的话,那你掌握上面那些就足够用了。

绘制海报的目的就是要让用户分享出去,所以必然少不了把图片保存到相册的流程。

import W2P from 'mp-canvas-drawer';

onLoad(){
  wx.showLoading({ title: '请稍等...', mask: true });
  this.w2p = new W2P('#myCanvas', { bgColor: '#ffffff', radius: 32 }, this);
  this.w2p.init().then(() => {
      this.drawSharePoster(); // 初始化完成后就可以开始画了
      // 元素画完后,调用canvasExport方法把画布导出,之后就可以调用saveImage让用户把图片保存到相册了。
      // 注意导出完成之后再允许用户操作保存

      this.w2p.canvasExport().then(() => wx.hideLoading());
  });
}

然后给你的按钮添加事件,用户点击时调用this.w2p.saveImage(),该方法也会返回Promise,你可以在保存成功或失败后做些什么。

  this.w2p.saveImage()
   .catch(() => {...})
   .then(() => {...});

例如toast告知用户结果?这个不需要你来做,工具内已经做好了相应提示,成功时会提示 “保存成功”,失败时会提示“保存失败,请重试”,当然如果你不想要这个提示,可以这样写

this.w2p.saveImage({customSuccToast: true, customFailToast: true})
   .catch(() => {...}) // 然后你就可以自己写失败时或成功时的toast了
   .then(() => {...});

还没完,保存图片到相册需要用户进行授权,这个工具也帮你做了:

在保存时它会先查询有没有授权,授权过则保存图片,如果没有授权会拉起授权弹窗,如果用户同意则保存图片。

如果用户拒绝则展示弹窗再提示一下“监测到您没有授权保存到相册权限,无法使用该功能,是否去授权?”,如果用户点击确定会跳转到授权页授权,用户再次点击保存按钮时就会获取到新的权限状态了。

2022最新小程序分享海报图完美方案

以后再遇到分享海报需求再也不用愁了,半小时搞定它!感兴趣的同学可自行查看js版本源码