uni-app中把canvas做成组件的方式,在微信小程序不能正常显示

uni-app中把canvas做成组件的方式,在微信小程序不能正常显示

canvas直接放到页面中,微信小程序可以正常显示,但是做成组件,再导入组件就不行,无法显示图像,但是组件方式在H5中可以正常显示图形,请教大家可能是哪里的问题?

<template>  
  <view class="layout">  
    <view class="fill"></view>  
    <my-canvas :height="canvasHeight"></my-canvas>  
  </view>  
</template>  

<script setup>  
import { ref } from 'vue';  

const canvasHeight = ref(3200);  
</script>  

<style lang="scss" scoped>  
.layout {  
  display: flex;  
  flex-direction: column;  
  padding: 30rpx;  
  height: 100vh;  
  .fill {  
    height: 50%;  
    background: #ccc;  
  }  
}  
</style>  
<template>  
  <view class="container" :style="{ height: `${windowHeight}rpx`}">  
    <canvas  
      canvas-id="myCanvas"  
      :style="{ height: `${height}px` }"  
      @touchstart="handleTouchStart"  
      @touchmove="handleTouchMove"  
      @touchend="handleTouchEnd"  
    ></canvas>  
  </view>  
</template>  

<script setup>  
import { onLoad, onReady } from '@dcloudio/uni-app';  
import { onMounted, ref } from 'vue';  

const props = defineProps({  
  height: {  
    type: Number,  
    default: 3200,  
  },  
  windowHeight: {  
    type: Number,  
    default: 820,  
  },  
});  

const handleTouchStart = (e) => {  
  // 处理触摸开始事件  
};  

const handleTouchMove = (e) => {  
  // 处理触摸移动事件  
};  

const handleTouchEnd = (e) => {  
  // 处理触摸结束事件  
};  

onMounted(() => {  
  drawContent();  
});  

const drawContent = () => {  
  const ctx = uni.createCanvasContext("myCanvas");  
  const offsetY = 400;  
  // begin path  
  ctx.rect(10, offsetY + 10, 100, 30);  
  ctx.setFillStyle("yellow");  
  ctx.fill();  

  // begin another path  
  ctx.beginPath();  
  ctx.rect(10, offsetY + 40, 100, 30);  

  // only fill this rect, not in current path  
  ctx.setFillStyle("blue");  
  ctx.fillRect(10, offsetY + 70, 100, 30);  

  ctx.rect(10, offsetY + 100, 100, 30);  

  // it will fill current path  
  ctx.setFillStyle("red");  
  ctx.fill();  
  ctx.draw();  
  console.log('绘制完成');  
};  
</script>  

<style lang="scss" scoped>  
.container {  
  width: 100%;  
  overflow: auto;  
  box-shadow: inset 0 0 10px #ccc;  
  canvas {  
    width: 100%;  
  }  
}  
</style>

Image

相关链接 :


更多关于uni-app中把canvas做成组件的方式,在微信小程序不能正常显示的实战教程也可以访问 https://www.itying.com/category-93-b0.html

15 回复

这不是Bug,在小程序自定义组件中使用时,需要传递当前组件实例的。文档
在 options API 中就是 this
在 composition API 是使用 getCurrentInstance() 获取到的实例
针对问题中的代码给出的伪代码是:
import { getCurrentInstance } from ‘vue’
const instance = getCurrentInstance()
const drawContent = () => {
// …
const ctx = uni.createCanvasContext(‘myCanvas’, instance)
// …
}

更多关于uni-app中把canvas做成组件的方式,在微信小程序不能正常显示的实战教程也可以访问 https://www.itying.com/category-93-b0.html


经过测试,确实如此,这个是只有canvas在组件中使用才要这么用吗?我用别的自定义组件没有类似问题

我使用vue2的按这么做,也解决了,感谢

uni.createSelectorQuery()
.select(’#canvas’) // 在 WXML 中填入的 id
.fields({
node: true,
size: true
})
.exec((res) => {
console.log(res, ‘sssscacsacasc’)
const style = res[0]
把uni.createSelectorQuery() 替换为 this.createSelectorQuery() 就搞定了 具体可看 https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html

感谢反馈

要怎么才能实现canvas作为插件功能使用?需要等到下个版本修复才行吗

遇到同样的问题,封装成组件后,微信小程序绘图不显示,真机也不显示

遇到同样的问题,封装成组件后,微信小程序绘图不显示,真机也不显示

我也遇到相同的问题,有没有解决的方案吗

小程序用canvas 2d, 老版的canvas官方都不维护了。 https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html

<canvas type="2d" id="myCanvas"></canvas>

// canvas.js
Page({
onReady() {
const query = wx.createSelectorQuery()
query.select(’#myCanvas’)
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node
const ctx = canvas.getContext(‘2d’)

    const dpr = wx.getSystemInfoSync().pixelRatio  
    canvas.width = res[0].width * dpr  
    canvas.height = res[0].height * dpr  
    ctx.scale(dpr, dpr)  

    ctx.fillRect(0, 0, 100, 100)  
  })  

}
})

const ctx = uni.createCanvasContext(“myCanvas”,this);

这个坑踩了好多次

怎么我传了this,也不行呢

在uniapp中将canvas做成组件并在微信小程序中无法正常显示的主要原因包括以下几点‌: 1、没有写canvas-id‌:在自定义组件中,canvas标签必须指定canvas-id属性,否则无法正确创建和管理canvas上下文‌。 2‌、uni.createCanvasContext方法没有传入组件实例‌:在单独作为组件引入时,需要传入组件实例。在Vue 2中是this,在Vue 3中是getCurrentInstance()‌。canvas标签上写了type="2d"‌:在自定义组件中,不应使用type=“2d”,因为这会导致无法绘制图形‌。 3‌、没有在onReady或者onMounted生命周期里实例化canvas‌:确保在组件的生命周期钩子onReady或onMounted中实例化canvas,以确保画布正确初始化‌。 ‌解决方法‌: 确保canvas-id属性存在‌:在自定义组件的canvas标签中添加canvas-id属性。 ‌正确使用uni.createCanvasContext方法‌:根据Vue版本使用this或getCurrentInstance()来获取组件实例。 ‌移除type="2d"属性‌:在自定义组件的canvas标签中不要使用type=“2d”。 ‌在生命周期钩子中实例化canvas‌:确保在组件的onReady或onMounted生命周期钩子中实例化canvas。 通过以上步骤,可以有效解决uniapp中canvas组件在微信小程序中无法正常显示的问题。

(⊙o⊙)…
这张图要下载下来 canvasToTempFilePath,提示canvas为空,又获取不到了
errMsg: “canvasToTempFilePath:fail fail canvas is empty”

这个问题主要是由于微信小程序的canvas组件在自定义组件中的使用限制导致的。以下是关键点分析:

  1. 微信小程序中,自定义组件的canvas需要使用this.createSelectorQuery()来获取节点,而不是直接使用uni.createCanvasContext()

  2. 解决方案:

  • 在组件中使用this.createSelectorQuery()获取canvas节点
  • 或者改用微信小程序的<canvas type="2d">方式
  1. 修改建议:
const drawContent = () => {
  // 微信小程序环境
  if(uni.getSystemInfoSync().platform === 'devtools' || uni.getSystemInfoSync().platform === 'ios' || uni.getSystemInfoSync().platform === 'android'){
    const query = uni.createSelectorQuery().in(this)
    query.select('#myCanvas').fields({node: true, size: true}).exec((res) => {
      const canvas = res[0].node
      const ctx = canvas.getContext('2d')
      // 绘制逻辑...
    })
  } else {
    // H5等其他环境
    const ctx = uni.createCanvasContext("myCanvas")
    // 原有绘制逻辑...
  }
}
回到顶部