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

相关推荐
GIS程序媛—椰子14 分钟前
【Vue 全家桶】7、Vue UI组件库(更新中)
前端·vue.js
DogEgg_00120 分钟前
前端八股文(一)HTML 持续更新中。。。
前端·html
ZL不懂前端23 分钟前
Content Security Policy (CSP)
前端·javascript·面试
木舟100927 分钟前
ffmpeg重复回听音频流,时长叠加问题
前端
王大锤439137 分钟前
golang通用后台管理系统07(后台与若依前端对接)
开发语言·前端·golang
我血条子呢1 小时前
[Vue]防止路由重复跳转
前端·javascript·vue.js
黎金安1 小时前
前端第二次作业
前端·css·css3
啦啦右一1 小时前
前端 | MYTED单篇TED词汇学习功能优化
前端·学习
半开半落1 小时前
nuxt3安装pinia报错500[vite-node] [ERR_LOAD_URL]问题解决
前端·javascript·vue.js·nuxt