Skip to content

使用 snapshot 组件实现截图功能

前言

小程序对某一页面或者指定组件截图是一个老大难的问题,如果是出一个海报图片,还能用我之前提到的 Painter 组件自定义一个模板实现。

但如果要对一个动态渲染的组件截图,需要先获取组件 DOM 信息,使用 canvas 组件渲染后再截取,很容易出现渲染样式错位,组件信息缺失等问题。

而微信新出的 Skyline 渲染引擎里的 snapshot 组件,可以很方便的实现截图功能。

环境

Hbuilder X v3.99

微信小程序基础库 v3.4.0

实现

认识 Skyline 渲染引擎

什么是 Skyline 渲染引擎

Skyline 渲染引擎示例

Skyline 环境要求

从上面三个文档,我们能得出以下几点:

  • Skyline 渲染引擎并不成熟和稳定,需要最新的小程序基础库支持,并且还缺失很多旧有 API 的支持。
  • 从官方示例来看,事实上 Skyline 更偏向用来补强,补全旧引擎在动画、地图、截图等方面的不足。

所以我们现在最好是在有特殊需求的页面使用 Skyline 渲染引擎,其他页面还是使用旧引擎。

开启 Skyline 渲染引擎支持

Skyline 渲染引擎是要手动开启的,分为两种模式,全局开启和指定页面开启。

公用配置

manifest.json 文件中添加如下配置:

json
"mp-weixin": {
  // 开启按需加载,必填
  "lazyCodeLoading": "requiredComponents",
  "rendererOptions": {
    "skyline": {
      // 默认开启 block 布局,必填
      "defaultDisplayBlock": true,
      // 关闭 AB 测试,直接在生产环境应用
      "disableABTest": true,
      // 安卓SDK 版本范围,默认支持 3.0.1 - 15.255.255
      "sdkVersionBegin": "3.0.1",
      "sdkVersionEnd": "15.255.255"
    }
  }
}

pages.json 文件中添加如下配置:

json
"pages": [
  {
    "path": "页面路径",
    "style": {
      // 自定义导航栏,必填
      "navigationStyle": "custom",
      // 切换组件框架,必填
      "componentFramework": "glass-easel",
      // 禁止页面滚动,必填
      "disableScroll": true
    }
  }
]

全局开启

manifest.json 文件中添加如下配置:

json
"mp-weixin": {
  // 开启 skyline 渲染,必填
  "renderer": "skyline",
}

指定页面开启

pages.json 文件中添加如下配置:

json
"pages": [
  {
    "path": "页面路径",
    "style": {
      // 开启 skyline 渲染,必填
      "renderer": "skyline",
    }
  }
]

使用 snapshot 组件

使用 snapshot 组件包裹想要截图的组件:

html
<snapshot id="my-snapshot">
  <!-- 需要截取的组件 -->
</snapshot>

调用 snapshot 组件的 takeSnapshot 方法,保存返回的 tempFilePath 指向的文件即可:

js
// 截取图片
function takeSnapshot() {
  uni
    .createSelectorQuery()
    .select("#shot-report-post")
    .node()
    .exec((res) => {
      console.log(res);
      const node = res[0].node;
      node.takeSnapshot({
        // type: 'file' 且 format: 'png' 时,可直接导出成临时文件
        type: "file",
        format: "png",
        success(shotRes) {
          // shotRes 内的 tempFilePath 为临时文件路径
          console.log("takeSnapshot success:", shotRes);
        },
        fail(shotRes) {
          console.log("takeSnapshot fail:", shotRes);
        },
        complete(shotRes) {
          console.log("takeSnapshot complete:", shotRes);
        },
      });
    });
}

// 调用分享组件
function showShareImageMenu(res) {
  wx.showShareImageMenu({
    path: res.tempFilePath,
    success: (shareRes) => {
      console.log("showShareImageMenu success:", shareRes);
      uni.hideLoading();
      uni.showToast({
        title: "操作成功",
        icon: "success",
      });
    },
    fail(shareRes) {
      console.log("showShareImageMenu fail:", shareRes);
      uni.hideLoading();
      uni.showToast({
        title: "操作取消",
        icon: "error",
      });
    },
    complete(shareRes) {
      console.log("showShareImageMenu complete:", shareRes);
      _that.toQueryOrderReport();
    },
  });
}

总结

snapshot 组件使用起来非常简单,但是需要注意以下几点:

  • Skyline 渲染引擎有些 css 样式不支持,以及计算方式与旧引擎存在差异,使用时需要注意样式的兼容。
  • 如果截图的组件超过了屏幕可视范围,需要使用 scroll-view 组件包裹,因为 Skyline 渲染引擎的启用就要禁止页面滚动,相对的 onPullDownRefresh 方法也无法触发。
  • 目前 Skyline 渲染引擎的帧数好像最大为 60 帧,有高刷需求的慎重使用。
  • 生产要使用,必须关闭 AB 测试。

总的来说,体验很好,目前也没遇见什么大的问题,已经上线生产环境。

Released under the MIT License.