NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.48k stars 4.79k forks source link

Taro.canvasToTempFilePath报错“fail canvas is empty” #10023

Closed LYNN-CHEN closed 2 years ago

LYNN-CHEN commented 3 years ago

相关平台

微信小程序

小程序基础库: 2.19.0 使用框架: React

复现步骤

附上对应片段的代码(使用的是React Hooks进行开发)

    const ctx = Taro.createCanvasContext('myCanvas');
    drawText(ctx, 20, 'test1测试1', '#000', 25, 25)
    ctx.draw(
      true,
      Taro.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success(res) {
          console.log('path', res.tempFilePath)
          setTempFilePath(res.tempFilePath)
        },
        fail(err) {
          console.log('error', err)
          Taro.showToast('图片生成失败!')
        }
      })
    );

<Canvas type="33" style={{ width: '400px', height: '550px' }} class="myCanvas" canvasId="myCanvas"></Canvas>

期望结果

成功保存图片并打印出图片地址

实际结果

errMsg: "canvasToTempFilePath: fail canvas is empty"

环境信息

  Taro CLI 3.3.1 environment info:
    System:
      OS: macOS 10.15.7
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 14.17.0 - /usr/local/bin/node
      Yarn: 1.22.10 - /usr/local/bin/yarn
      npm: 6.14.13 - /usr/local/bin/npm
    npmPackages:
      @tarojs/cli: 3.3.1 => 3.3.1 
      @tarojs/components: 3.3.1 => 3.3.1 
      @tarojs/mini-runner: 3.3.1 => 3.3.1 
      @tarojs/react: 3.3.1 => 3.3.1 
      @tarojs/runtime: 3.3.1 => 3.3.1 
      @tarojs/taro: 3.3.1 => 3.3.1 
      @tarojs/webpack-runner: 3.3.1 => 3.3.1 
      babel-preset-taro: 3.3.1 => 3.3.1 
      eslint-config-taro: 3.3.1 => 3.3.1 
      react: ^17.0.0 => 17.0.2 
      taro-ui: ^3.0.0-alpha.3 => 3.0.0-alpha.10 
    npmGlobalPackages:
      typescript: 4.3.5

补充信息

尝试设置函数第二个参数为this.$scope等 但均无法支持

Chen-jj commented 3 years ago

@LYNN-CHEN 直接使用原生 API 试试,如果还有问题,提供一下完整的 Demo

LYNN-CHEN commented 3 years ago

@LYNN-CHEN 直接使用原生 API 试试,如果还有问题,提供一下完整的 Demo

使用原生API之后仍然有一样的问题 这里是demo的GitHub仓库地址:https://github.com/LYNN-CHEN/taro-cavas-demo

marsDes commented 3 years ago

Taro3 +vue3

  onMounted(() => {
    const ctx = Taro.createCanvasContext('canvas')  // null
    setTimeout(()=>{
      const ctx = Taro.createCanvasContext('canvas') 
    },100) // 正常
 })

nextTick 也没用只能 定时器

LuXinZ commented 3 years ago

你换一种写法试一下 可以

Taro.createSelectorQuery()
          .select('#canvas')
          .fields({
            node: true,
            size: true,
          })
          .exec(res => {
            // 这里的res[0].node 是获取到的canvas节点

            resolve(res[0].node);
            let ctx =  res[0].node.getContext('2d'); // ctx 是canvas实例
          });
// 节点标签这样写
<Canvas id="canvas" type="2d"/>
Chen-jj commented 2 years ago

@LYNN-CHEN 直接使用原生 API 试试,如果还有问题,提供一下完整的 Demo

使用原生API之后仍然有一样的问题 这里是demo的GitHub仓库地址:https://github.com/LYNN-CHEN/taro-cavas-demo

@LYNN-CHEN 文档有写,draw 回调中再调用:

image

Chen-jj commented 2 years ago

Taro3 +vue3

  onMounted(() => {
    const ctx = Taro.createCanvasContext('canvas')  // null
    setTimeout(()=>{
      const ctx = Taro.createCanvasContext('canvas') 
    },100) // 正常
 })

nextTick 也没用只能 定时器

@marsDes 使用 onReady

image