微信小程序Canvas 2D自定义生成转发图片_ice breaker的博客-程序员秘密

技术标签: 小程序  

前言

小程序原先转发给别人,要不是一张图片,要不是就是截屏,不是很自定义化。

我们要每个用户在不同的页面,转发的内容都不一样,这当然可以直接从服务端实时生成这样 5:4 的图片做转发,毕竟好处是避免了兼容性问题

本示例将会用另外一种思路,从客户端实时生成分享图片,并进行转发。

技术调查

微信小程序中 以 wx.createCanvasContext 为代表的 CanvasContext (v1)

都从基础库 2.9.0 开始,停止维护了

所以我们就使用更加贴近 mdn 上 Canvas 来代替 (v2)

这里简称停止维护的版本为 v1, Canvas 版本为 v2

值得注意的是

v2 版本中还有一个 wx.createOffscreenCanvas

它也可以使用 OffscreenCanvas.getContext('2d') 这样的 api

不过它的最低版本为 2.16.1

到今天 (2021/05/05) 大部分人用的版本还是 2.16.1 (2.17.0 还在灰度)

所以说,从兼容性的角度出发, 使用 OffscreenCanvas 是有很大风险的

而且我出于好奇实验使用了一下,bug 也是一大堆 issue

开始吧

ps: canvas api 不熟的 mdn 上看看

绘图前言

  • rpx 这种单位换算问题 , wx.getSystemInfoSync 获取一下屏幕宽,做个换算就行
  • 小程序中的 canvas 2d 不能把它设置 style:display:none ,不然转化成图片时会空白 , 我们可以把它移出可视界面。
  • 层级问题,canvas 和 svg 一样都是后面的覆盖前面的,所以我们可以使用 对zIndex 进行排序,来决定每个 function 的执行顺序

绘图 ing

  • 圆角矩形可以使用 arc api 来解决

  • 圆角图片可以使用 clip + drawImage

比如在这里因为我们需要使用微信的头像

所以需要把 图片的域名 在后台配置一下

这里贴一段 uni 下,在 ctx 中绘制圆角头像的代码

async addAvatar() {
    
      // 下载到本地
      const [err, res] = await uni.getImageInfo({
    
        src: avatarUrl
      })
      const {
     path, type } = res
      const img = canvas.createImage()
      img.src = path
      // 直接设置 width height 是不生效
      const offsetX = 20 * dpr
      const offsetY = 20 * dpr
      const r = (50 * dpr) / 2
      const circle = {
    
            x: offsetX + r,
            y: offsetY + r,
            r: r
          }
      // 这样写是因为最后绘制的时候是执行一个 ()=> Promise<any>
      // 这样可以确保生成的时候,图片已经 onload了
      await new Promise((resolve, reject) => {
    
        img.onload = () => {
    
          ctx.save()
          // 切圆角
          ctx.beginPath()
          ctx.arc(circle.x, circle.y, circle.r, Math.PI * 2, false)
          ctx.clip()
          // 画成指定的长和高
          ctx.drawImage(img, offsetX, offsetY, 50 * dpr, 50 * dpr)
          ctx.restore()
          resolve()
        }
        img.onerror = event => {
    
          reject(event)
        }
      })
    }

图片的丰富度 -> svg 的引入

在上面,我们已经把图片的,渐变,排版,文字,依赖的图片全部绘制上去了

然而这时候我们想加一些丰富度,但是不想使用本地图片去那种,缝合的事情,毕竟这样也有失水准。

这时候我们自然而然的想到了 SVG-to-canvas parser

目前在 npm 主要有 fabric / canvg 这些

这里我选用的是 基于 canvgsvg2canvas

这样我们在 iconfont 就可以挑选一些 svg 下载下来,然后通过 converter 就可以直接转换成 canvas js code 使用了。

当然,转化实际上是不完美的,定位和大小,我们可以改造绘制的 draw function

在其中加入

ctx.translate(x, y)
ctx.scale(dpr / 2, dpr / 2)

颜色什么当然都可以作为参数

这样,我们的 svg 就顺利的加了上去

onShareAppMessage 转发

onShareAppMessage 是支持 promise 的,不过 promise 三秒内不 resolve , 会自动 fallback

onShareAppMessage 文档

这时候,我们就可以写出下列代码

onShareAppMessage() {
    
  const createPromise = async () => {
    
      try {
    
        this.shareBtnLoading = true
        // 获得图片的临时路径
        const loaclPath = await aWayToGetCanvasTempFilePath()

        return {
    
          title: 'hello, i am icebreaker',
          path: 'resolve path',
          imageUrl: loaclPath
        }
      } catch (e) {
    
        console.warn(e)
      } finally {
    
        this.shareBtnLoading = false
      }
  }
  return {
    
    title: 'fallback title',
    promise: createPromise(),
    path: 'fallback path',
    imageUrl: 'fallback imageUrl'
  }
}

获得图片的临时路径,可以使用 wx.canvasToTempFilePath api

这个api是 画布 v1 版本 和 v2版本通用的

不过 v1 版本传入的是 canvas-id

v2 则是 canvas 组件实例

生成速度

在不同的 dpr 下,时间都很快 真机在 300ms 左右 远小于 3000ms 自动 fallback 的限制

效果视频

视频链接

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33020601/article/details/116427358

智能推荐

谈谈“熵”_AlvinTech14的博客-程序员秘密

原博客: http://www.8btc.com/entropy熵(Entropy)在物理学中用于度量一个热力学系统的无序或混乱程度(参考热力学第二定律),当它被引入到信息论(计算机科学)时,则被用来衡量信息的不确定性(不可预测性),简单的说也就是“随机性”。假设有一枚“理想”的硬币(抛出正面和反面的几率相等),每一次抛硬币都是独立的、不可预测的,其结果不是正面

给出三角形的三边长,求三角形面积_己知三獊形三迈的长求三角形的面积_____-7的博客-程序员秘密

#include #include #include int main(){  printf("请输入三角形的三边长:\n");  float x,y,z,s,area;  scanf("%f,%f,%f",&x,&y,&z);  if(x+y>z&&x+z>y&&y+z>x){    s=(x+y+z)/2;    area=sqrt(s*(s-x)*(s-y

Kaggle(Gun Violence Data)—美国枪支暴力事件分析(1)和(2)_白糖炒栗子~的博客-程序员秘密

 Kaggle(Gun Violence Data)—美国枪支暴力事件分析(1) 数据来源为kaggle:https://www.kaggle.com/jameslko/gun-violence-data 主要分析13-18年美国枪支暴力事件的特征,以及使用时间序列预测下一年枪支暴力事件发生数量。主要用到以下数据包 Basemap是python中一个利用地图的库 plotly是开...

如何用python制作五子棋游戏_Python制作打地鼠小游戏_weixin_39998521的博客-程序员秘密

原文链接Python制作小游戏(二十一)​mp.weixin.qq.com效果展示打地鼠小游戏https://www.zhihu.com/video/1200492442610450432简介打地鼠的游戏规则相信大家都知道,这里就不多介绍了,反正就是不停地拿锤子打洞里钻出来的地鼠呗~首先,让我们确定一下游戏中有哪些元素。打地鼠打地鼠,地鼠当然得有啦,那我们就写个地鼠的游戏精灵类呗:'''地鼠'''...

Java构建树状结构_java 构建树状结构_A_Lonely_Smile的博客-程序员秘密

/** * 节点实体类 * @author Administrator * */public class Nodes { private String id; //父节点 private String pid; private String name; List&lt;Nodes&gt; childNodes; Nodes(String id,String ...

随便推点

OD快捷键说明与例子_芳华9166的博客-程序员秘密

DUMP窗口快捷键功能-------------------------------------------------------------------------------------------1:在DUMP窗口按“CTRL + 鼠标双击”,表示在ASM窗口显示选中的第一个字节开始地址的代码2:DUMP窗口按“CTRL +ENTER”表示复制从选中的第一个字节开始的一个DWO

数字图像处理 图象压缩_陈纪建的博客-程序员秘密

第十四章 图象压缩目录1.   引言2.   无损压缩2.1 行程编码(RLE)2.2 LZW编码2.3 Huffman编码3.   有损压缩3.1 量化3.2 预测编码3.3DCT编码3.4 其它变换编码作业1.  引言    图象压缩是通过删除图象数据中冗余的或者不必要的

css3之元素的缩放、渐变、旋转和平移_点点稻花香的博客-程序员秘密

本文主要讲解css3的一些比较突出的新增样式,例如元素的缩放,元素的渐变等。注意,css3的所有样式和元素只支持IE9和IE9以上的浏览器。

查询网络IP_cream_ljy115_是水啊!鲸鱼的博客-程序员秘密

随便写一下:在win系统下,使用ipconfig在ubuntu系统下,使用ifconfig有时需要检查主从机网络是否连接正常,使用ping +从机或主机ip对于ubuntu系统,我使用sudo poweroff来关机单独编译工作空间下的一个包时,使用catkin_make -DCATKIN_WHITELIST_PACKAGES="想编译包的名字"设置主从机的时候:export ROS_IP=主机IPexport ROS_HOSTNAME=`hostname -I` //代表..

C++中的"pure virtual function call"_weixin_30390075的博客-程序员秘密

前几天我们项目刚刚解决了一个pure virtual function call引起的stopship的bug,乘热打铁,学习总结一下。理论上的case当一个纯虚函数被调用到时,vc++的debug模式下会弹出这么一个对话框:然后就是crash了。在网上找了一下,发现已经有人对此作了详细的介绍:"Pure Virtual Function Called": An Explana...

推荐文章

热门文章

相关标签