作者 | 结一

为了吸引更多的用户,设计好一个分享海报还是很有必要的。而小程序要生成一个海报还是有点坑的,下面分享下我们打卡小程序的一些经验。

分享海报的效果图如下:

制作要求:

  • 海报以弹窗形式展现,各种手机型号都可以正常显示

  • 海报的内容由背景图、日期、随机的名言警句、活动的二维码及用户的参加活动的信息

  • 海报保存的图片大小为 iphone 6 的两倍图(750 * 1334)

由于看到的弹窗图片与保存的图片是两种大小,所以一开始看了些网上的其他教程,建议是搞两个 canvas 一个大的一个小的。实际过程中,采用了一个大的 canvas ,让其偏离视窗显示区域(不可见)并生成临时文件,弹窗的图片再使用 img 组件,引入临时文件,设置其高度;而保存的时候则直接下载临时文件。

虽然是实现了,但是后来在优化的过程中,这个方案也重新设计了。下面具体介绍下优化过的方案:

  • 优先使用一个 canvas 绘制二维码;

  • 弹窗的图片即为一个 canvas;

  • 分享的图片为该 canvas 导出的大图片;

  • 为了达到最佳效果,名言警句的换行录入时就处理好。

设计弹窗的图片比例

由于最后海报的图片大小为 iphone 8 的两倍图(750 * 1334),所以这里弹窗的图片也即是 canvas 的大小,设计为对应的尺寸的某个比例。

弹窗图片的高度 = 视窗的高度 - 上下留白 - 按钮的高度 - 图片与按钮的距离弹窗图片的高度 = 100vh - 40rpx * 2 - 50rpx - 15rpx
// iPhone 8 的尺寸标准为 750px * 1334px弹窗图片的宽度 /  弹窗图片的高度 = 750 / 1334弹窗图片的宽度 = (750 / 1334) * 弹窗图片的高度

由于像素只能是整数,所以这样绘制出来的图片可能底部会有1px的空白,所以在设置高度的时候可以再减掉 1px,这不会影响视觉效果。

绘制背景图

如果是网络图片,绘制背景图之前一定要先下载该图片,可通过 wx.getImageInfo 或 wx. downloadFile 下载图片,下载成功后将其塞进临时地址,然后使用 wx canvas 的 drawImage 绘制。注意如果地址是 base64 的话, gif 是不行的。

// 预先下载图片preLoadImg(url, taskId) {    url = /^https/.test(url) ? url : `https:${url}`;    wx.getImageInfo({      src: url,      success(res) {        // 把图片存下        app.globalData[`tempImg${taskId}`] = res.path;      },      fail(err) {        console.log(err);      },    });  },

绘制二维码

绘制二维码换了好几个库,每个在安卓下面生成的二维码都会频现失败。查了好些资料,说是安卓绘制的时候要设置个 setTimeout,于是最终选择了weapp-qrcode,修改了其绘制的函数,增加了setTimeout(还真别说,加上二维码绘制就成功了)。

ctx.draw(false, function (e) {    setTimeout(() => { // 修改增加的        options.callback && options.callback(e)    }, 20);})

另:目前这些绘制小程序二维码的库都是在一个单独的新 canvas 中完成的,只要对源码稍作修改,就可以提供另一个接口,直接在一个现有的 canvas (表示 canvas 中一开始绘制了其他内容) 中绘制。

如果二维码扫不出来,则表示二维码绘制出了问题。但安卓微信 6.7.2 版本本身有个 bug,二维码本身是没有问题,它却不能识别。不过升级下微信版本就好了。

canvas 绘制完毕及下载

具体的绘制调用的都是 api,就不多说了。主要说下绘制完毕如何处理。先异步触发绘制完毕,该事件中将 canvas 显示出来,也即是小图。同时生成n倍分享图,并触发事件,该事件中将大图的缓存文件保存下来。然后到下载的时候使用。

// 绘制完毕处理ctx.draw(false, async () => {        // canvas 绘制好了触发 drawDone        setTimeout(() => {          this.triggerEvent('drawDone', this);        }, 100);// 生成用于分享的图,pixelRatio 为 倍数        const { canvasId, canvasWidth, canvasHeight, pixelRatio } = this.data;        const { tempFilePath } = await wxCanvasToTempFilePath(          {            x: 0,            y: 0,            width: canvasWidth,            height: canvasHeight,            destWidth: canvasWidth * pixelRatio, // 导出大小为 canvas 的 pixelRatio 倍            destHeight: canvasHeight * pixelRatio,            canvasId,          },          this        );        // 生成分享图完毕触发        this.triggerEvent('saveDone', tempFilePath);});
// 下载处理// 路径为上一步保存的分享图暂存图wx.saveImageToPhotosAlbum({      filePath: cardTempImgPath,      success() {        wx.showToast({          title: '保存成功', // 提示的内容,          icon: 'success', // 图标,          duration: 2000, // 延迟时间,          mask: true, // 显示透明蒙层,防止触摸穿透,        });      },      fail(err) {        console.log(err);        wx.showToast({          title: '保存失败', // 提示的内容,          icon: 'none', // 图标,          duration: 2000, // 延迟时间,          mask: true, // 显示透明蒙层,防止触摸穿透,        });      },    });

保存图片

  • 先要获取用户是否开启用户授权相册

  • 如果没有权限,则弹窗提示开通权限,如果有权限直接调用 saveImageToPhotosAlbum 接口保存图片

  • 如果弹窗提示接受开通权限,则调用 saveImageToPhotosAlbum 接口保存图片

  • 如果弹窗提示拒绝则再次弹窗是否去设置开通权限,如果是则进入设置权限

// 先尝试保存trySaveImg() {  const _this = this;  // 获取用户是否开启用户授权相册  wx.getSetting({    success(res) {      // 如果没有则获取授权      if (!res.authSetting['scope.writePhotosAlbum']) {        wx.authorize({          scope: 'scope.writePhotosAlbum',          success() {            _this.saveImg();          },          fail() {          // 如果用户拒绝过或没有授权,则再次打开授权窗口          // (ps:微信api又改了现在只能通过button才能打开授权设置,以前通过openSet就可打开,下面有打开授权的button弹窗代码)            wx.showModal({              title: '获取权限失败',              content: '是否打开设置页,允许小程序保存图片到你的相册',              success: () => {                wx.openSetting({                  success (sRes) {                    if (sRes.authSetting['scope.writePhotosAlbum']) {                      setTimeout(() => {                        _this.saveImg();                      }, 200);                    }                  },                });              },            });          },        });      } else {        // 有则直接保存        _this.saveImg();      }    },  });},// 正式保存saveImg() {  const { tempImgPath } = this.data;wx.showLoading({    title: '正在保存中...', // 提示的内容,    mask: true, // 显示透明蒙层,防止触摸穿透,  });wx.saveImageToPhotosAlbum({    filePath: tempImgPath,    success() {      wx.showToast({        title: '保存成功',        icon: 'success',        duration: 2000,        mask: true,      });    },    fail() {      wx.showToast({        title: '保存失败',         icon: 'none',        duration: 2000,        mask: true,      });    },  });},

性能注意

经实践测试整个绘制过程其实还是很快的,但是如果有保存临时文件操作( wx.canvasToTempFilePath ),那么这个操作一般得占一半时间左右。除此之外,有个 measureText api,用来测量文字的长度,这个在实现自动换行的时候用得到,但是比较耗性能。

微信小程序之分享海报生成相关推荐

  1. 微信小程序商品分享海报

    canva实现微信小程序商品分享海报 前言 使用canvas画布实现小程序分享海报功能 一.定义一个生成海报按钮 1.点击按钮生成海报 catchtap:handleShare 使用catch绑定阻止 ...

  2. 微信小程序实现分享海报

    实现前的注意事项: 1.使用的是微信小程序官方的canvas组件官方文档地址 2.在canvas中不能绘制网络图片,需要使用wx.getImageInfo({}),文档地址 注意最好在画布绘制之前对图 ...

  3. 终于搞定微信小程序canvas分享海报

    canvas drawer 做微信小程序中最好用的 canvas 绘图组件之一. 当前环境下,大家都非常需要分享到朋友圈这个功能,但是实现起来各有心酸(坑比较多),所以才有了如下的 canvas 绘图 ...

  4. 微信小程序-运用painter插件生成海报分享朋友圈--比canvas好用

    微信小程序-运用painter插件生成海报–比canvas好用 先放插件地址:https://github.com/Kujiale-Mobile/Painter 还有个可视化把海报生成代码的地址:ht ...

  5. Canvas绘图在微信小程序中的应用:生成个性化海报

    Canvas绘图在微信小程序中的应用:生成个性化海报 如极客时间的一些实现案例: 基础语法 Canvas本质是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素,默认大小为30 ...

  6. 微信小程序如何分享到朋友圈

    微信小程序之前的分享是不支持直接分享到朋友圈的,之前分享的处理方式一般都是通过canvas生成分享海报,然后将生成的海报图发送到朋友圈中来达到分享的目的.不过从基础库 2.11.3 开始,分享朋友圈的 ...

  7. android分享朋友圈功能,微信小程序实现分享至朋友圈的功能来啦

    微信小程序「分享至朋友圈」能力,终于来了!(之前,我相信大部分微信小程序的开发者都是用"分享卡片"的形式,手动调用wx.createCanvasContext生成一张图片,让用户生 ...

  8. 微信小程序实现分享至朋友圈的功能

    微信小程序实现分享至朋友圈的功能 微信小程序从基础库 2.11.3 开始,可将小程序页面分享到朋友圈.适用于内容型页面的分享,不适用于有较多交互的页面分享. 1 设置分享状态 小程序页面默认不可被分享 ...

  9. plsql developer无监听程序_微信小程序支持分享到朋友圈啦!技术解读跟我来

    千呼万唤始出来!微信小程序页面分享到朋友圈的功能,终于在安卓系统灰度测试了!目前只在安卓系统!只在安卓系统!只在安卓系统!iOS系统还没有办法体验. 首先,我们看一下官方文档的描述,解读一下小程序分享 ...

最新文章

  1. docker 容器无法使用中文 解决方案
  2. php微信撤回消息,78行Python代码实现现微信撤回消息功能
  3. flex组件使用【PopUpButton】
  4. Flask 框架下 Jinja2 模板引擎高层 API 类——Environment
  5. 编译mysql 5.7 源码安装常见问题
  6. Leetcode 266.回文排列
  7. EVENT:10228 trace application of redo by kcocbk
  8. 【备注】【C22】《云计算核心技术剖析》PDF 下载
  9. HTMLifier将scratch游戏打包为html文件
  10. python调用不起来chrome_python调用selenium打开chrome浏览器失败
  11. c语言蟠桃记程序,HDU2013 蟠桃记
  12. ModelAndView返回mav时,报404
  13. 宽带、专线等傻傻分不清楚——广域网协议
  14. (转)多媒体通话杂谈:SBC设备(边界会话控制器)全面剖析讲解
  15. 液晶拼接屏黑屏闪屏的处理方法
  16. 哈利·波特考试(c/c++)
  17. 特征工程—数据哑变量(独热编码)
  18. 【100个 Unity实用技能】☀️ | 修改Unity UI控件中默认字体配置
  19. 酷派手机丢失的文件丨如何才能恢复呢
  20. 工作随笔——入职一年半来的工作感受

热门文章

  1. 被遗忘权_继续–被遗忘的声明
  2. 京东前台PC首页系统技术详解
  3. python读取lst文件
  4. 【力扣】【初级算法】【数组10】有效的数独
  5. 我的专业作文300字计算机,我喜爱的职业300字
  6. java无法下载jnlp_java-JNLP下载期间FileNotFoundException
  7. Client network socket disconnected before secure TLS connection was established
  8. 数据扒一扒《隐秘的角落》到底怎么火的?
  9. 通过Vue+flvjs在HTML5中播放flv格式视频文件—demo及api
  10. 基于区块链的去中心化身份技术有哪些应用前景?