Skip to content

uniapp 入门实战 04: canvasToTempFilePath 解决 fail canvas is empty 报错


问题描述


概要内容

起因:一个vue页面组件都2645行,而且功能有多,实在太难维护,所以决定进行功能拆分重构。

https://cdn.jsdelivr.net/gh/yxw007/BlogPicBed@master//img/20211021093914.png

调整之前结构

  • PageScene.vue
html
<template>
  ...
  <!-- #ifdef APP-PLUS || H5 -->
    <canvas
      canvas-id="canvas"
      class="canvas"
      :style="{ width: canvasWidth, height: canvasHeight }"
    ></canvas>
    <!-- #endif -->

    <!-- #ifndef APP-PLUS || H5 -->
    <canvas
      canvas-id="canvas"
      id="canvas"
      class="canvas"
      :style="{ width: canvasWidth, height: canvasHeight }"
    ></canvas>
    <!-- #endif -->
  ...
</template>

调整之后结构

  • SceneRender.vue

    html
    <template>
      <div class="scene-Render">
      <!-- #ifdef APP-PLUS || H5 -->
        <canvas
          canvas-id="canvas"
          class="canvas"
          :style="{ width: canvasWidth, height: canvasHeight }"
        ></canvas>
        <!-- #endif -->
    
        <!-- #ifndef APP-PLUS || H5 -->
        <canvas
          canvas-id="canvas"
          id="canvas"
          class="canvas"
          :style="{ width: canvasWidth, height: canvasHeight }"
        ></canvas>
        <!-- #endif -->
     </div>
    </template>
    
    <script>
    ...
    export default {
     onShow(){
      let canvas = uni.createCanvasContext("canvas", this);
      canvas.setStrokeStyle("#00ff00");
        canvas.setLineWidth(5);
        canvas.rect(0, 0, 200, 200);
        canvas.stroke();
      canvas.draw(false, () => {
          setTimeout(() => {
            uni.canvasToTempFilePath({
              canvasId: "canvas",
              x: 0,
              y: 0,
              width: 200,
              height: 200,
              destWidth: 200,
              destHeight: 200,
              complete: (res) => {
                console.error(res);
              },
            });
          }, 500);
        });
     }
    }
    ...
    </script>

    问题出现:canvas绘制没有一点问题,但是uni.canvasToTempFilePath回调一直报错:canvasToTempFilePath: fail canvas is empty。

  • PageScene.vue

    html
    <template>
      ...
      <SceneRender></SceneRender>
      ...
    </template>

解决方法

经过各种尝试最终发现canvas标签的定义只能放到page页面中,uni.canvasToTempFilePath 才会转换成功。

  • SceneRender.vue

    html
    <template>
      <div class="scene-Render">
      ...
     </div>
    </template>
    
    <script>
    ...
    export default {
     data: {
      return {
       canvas: undefined
      }
     },
     methods: {
      init(cs){
       this.canvas = cs;
      }
     }
    }
    ...
    </script>
  • PageScene.vue

    html
    <template>
      ...
      <!-- #ifdef APP-PLUS || H5 -->
        <canvas
          canvas-id="canvas"
          class="canvas"
          :style="{ width: canvasWidth, height: canvasHeight }"
        ></canvas>
        <!-- #endif -->
    
        <!-- #ifndef APP-PLUS || H5 -->
        <canvas
          canvas-id="canvas"
          id="canvas"
          class="canvas"
          :style="{ width: canvasWidth, height: canvasHeight }"
        ></canvas>
        <!-- #endif -->
    
      <SceneRender ref="sceneRender"></SceneRender>
      ...
    </template>
    
    <script>
    ...
    export default {
     onShow(){
      this.$refs.sceneRender.init(uni.createCanvasContext("canvas", this));
     }
    }
    ...

参考文献

Released under the MIT License.