Taro中使用html2Canvas和wxml-to-canvas

Taro中使用html2Canvas和wxml-to-canvas

建议页面中正常写taro的代码,用于页面的正常展示

举个🌰

html 复制代码
<div class="container" ref="h5Qrcode" >
  <view class="item-box red">
  </view>
  <view class="item-box green" >
    <text class="text">yeah!</text>
  </view>
  <view class="item-box blue">
    <image class="img" src="https://img0.baidu.com/it/u=4154833386,1880487480&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"></image>
  </view>
</div>

html2Canvas

使用非常简单,只需提供dom节点,但仍需注意两个重点

  1. 需要动态引入,需要判断环境,不能在小程序中引入

    typescript 复制代码
    import { isWeb } from '@/utils/is';
    
    // ...
    if (isWeb) {
      Taro.showLoading();
        try {
          const html2Canvas = require('html2canvas');
          html2Canvas(h5Qrcode.value).then((canvas) => {
            const imgBase64 = canvas.toDataURL('image/png');
            Taro.hideLoading();
            imgUrl.value = imgBase64.split(',')[1];
            handleSaveToAlbum();
          });
        } catch (_) {
          Taro.hideLoading();
        }
    }
  2. 该插件需要的是原始的dom节点。在taro中,如果通过<view>获取ref,会有差异,并不是原始的dom

    会报以下错误Error: Element is not attached to a Document

    这个通过view拿到的ref,虽然身上有$el属性,但通过实践得知,图片会出现问题。

    所以细心的你应该会说了,答案从一开始不就展现了吗,不写<view>而写<div>,没错,通过div,能拿到我们熟悉的原始dom

wxml-to-canvas

这是微信小程序官方推出的库,使用wxml的template和样式,转换为canvas,和html2canvas一样方便;但同时他也没有那么地方便。因为你除了正常画页面外,额外维护一套wxml和style,才能使用wxml-to-canvas

  1. 该库依赖于widget-ui,先安装依赖

    sh 复制代码
    npm i widget-ui

    然后想办法搞到wxml-to-canvas打包后的产物,我是通过安装wxml-to-canvas依赖,然后从node_module中复制出来的,当然你可以选择克隆git,然后运行打包命令。

    然后将这个小程序的产物放到我们的项目当中,同时要注意,如果你放在了分包中,那么只能在该分包下引入使用,其他地方想引用是不行的。所以我建议是放到主包中,因为很多地方要使用,当然,具体得看需求。

    假设我放到主包的component文件夹中

  2. 在config/index中增加配置

    javascript 复制代码
    const config = {
      designWidth(input) {
        if (input?.file?.replace(/\\+/g, '/').indexOf('@nutui') > -1) {
          return 375;
        }
        return 750;
      },
      ...
      mini: {
        ...
        compile: {
          exclude: [(modulePath) => modulePath.indexOf('component/Mini') >= 0],
        },
      }
    }

    设置好mini.compile.exclude,意思是匹配到路径包含component/Mini就忽略,不经过taro的编译,因为这个本来就是小程序的代码了。

  3. 具体的页面中引入使用。要使用原生小程序的组件,那就必须通过definePageConfig的usingComponents属性注册

    typescript 复制代码
    definePageConfig({
      navigationStyle: 'custom',
      usingComponents: {
        'wxml-to-canvas': '../../../component/Mini/wxmltocanvas/index',
      },
    });

    在template中使用

    html 复制代码
    <template>
    	<template v-if="!isWeb">
      	<wxml-to-canvas class="widget"></wxml-to-canvas>
    	</template>
    	<!-- 其他东西 -->
    </template>
  4. 编写wxml和style。根据文档提示,写好自己的东西

    typescript 复制代码
    const wxml = `<view class="container" >
      <view class="item-box red">
      </view>
      <view class="item-box green" >
        <text class="text">yeah!</text>
      </view>
      <view class="item-box blue">
          <image class="img" src="https://img0.baidu.com/it/u=4154833386,1880487480&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500"></image>
      </view>
    </view>
    `;
    const style = {
      container: {
        width: 300,
        height: 200,
        flexDirection: 'row',
        justifyContent: 'space-around',
        backgroundColor: '#ccc',
        alignItems: 'center',
      },
      itemBox: {
        width: 80,
        height: 60,
      },
      red: {
        backgroundColor: '#ff0000',
      },
      green: {
        backgroundColor: '#00ff00',
      },
      blue: {
        backgroundColor: '#0000ff',
      },
      img: {
        width: 80,
        height: 60,
      },
      text: {
        width: 80,
        height: 60,
        textAlign: 'center',
        verticalAlign: 'middle',
      },
    };
  5. 接着就是调用方法,渲染,获取图片等自定义操作了

    typescript 复制代码
    const widget: any = Taro.getCurrentInstance().page?.selectComponent?.('.widget');
    await widget.renderToCanvas({ wxml, style });
    // 生成图片
    const res = await widget.canvasToTempFilePath();
    const tempFilePath = res.tempFilePath;
    // 调用taro相关api下载tempFilePath;

结语

注意判断不同的平台(web和微信小程序),这两个库都是针对性的。

相关推荐
ZhengEnCi25 分钟前
12 种高级 UI 交互效果及对应 AI 提示词:从按压回弹到底部抽屉的物理感教学
前端·css·交互设计
IT_陈寒3 小时前
Redis大key删除为什么会导致服务卡顿?我的线上事故复盘
前端·人工智能·后端
用户2705077725244 小时前
MCP 最小 Server 实测:3 个 JSON-RPC 报错与修法
前端
用户499335025074 小时前
一人VIP账号多人共用:Web 代理里的会话共享怎么实现
前端
用户老李4 小时前
无线电自学教程 05:第一台收音机——从矿石机到 SDR
前端
IPIPD4 小时前
Node.js请求遇到503怎么重试?先解析Retry-After,再做有上限退避
前端
葡萄城技术团队4 小时前
dsh-spreadjs-editor 的集成链路:把 SpreadJS Designer 嵌进 Agent 工作台
前端
FlyWIHTSKY5 小时前
vue2和vue3有什么区别,用法上有哪些区别
前端·javascript·vue.js
码云之上5 小时前
10 颗一模一样的「Edit」:中后台 Web Agent 怎么找到对的那一行
前端·人工智能·浏览器
量化分析码农6 小时前
【Python量化多因子实战 04】因子暴露不是 alpha:市值与行业中性化实战
前端·后端