Taro中使用html2Canvas和wxml-to-canvas

Taro中使用html2Canvaswxml-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. 具体的页面中引入使用。要使用原生小程序的组件,那就必须通过definePageConfigusingComponents属性注册

    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和微信小程序),这两个库都是针对性的。

相关推荐
前端李易安2 小时前
Web常见的攻击方式及防御方法
前端
PythonFun2 小时前
Python技巧:如何避免数据输入类型错误
前端·python
hakesashou2 小时前
python交互式命令时如何清除
java·前端·python
天涯学馆2 小时前
Next.js与NextAuth:身份验证实践
前端·javascript·next.js
HEX9CF2 小时前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
ConardLi2 小时前
Chrome:新的滚动捕捉事件助你实现更丝滑的动画效果!
前端·javascript·浏览器
ConardLi3 小时前
安全赋值运算符,新的 JavaScript 提案让你告别 trycatch !
前端·javascript
凌云行者3 小时前
使用rust写一个Web服务器——单线程版本
服务器·前端·rust
华农第一蒟蒻3 小时前
Java中JWT(JSON Web Token)的运用
java·前端·spring boot·json·token
积水成江3 小时前
关于Generator,async 和 await的介绍
前端·javascript·vue.js