收藏
回答

关于微信小程序canvas的各种坑?

[自力更生自给自足的解决了这些问题,遇到同样问题的朋友可以参考参考]


1.用drawImage画线上图片在真机上显示不出来,模拟器上却可以显示(需要说明的是:drawImage画显示图片是需要获取到图片后才能开始画,并且获取的线上图片地址需要是https。)但是这些我都照做了可是真机上还是无法显示,为什么?我也试过下载到本地后画也没有用。

解决方法:

首先 ,我发现用canvas绘制线上图片时,必须先下载到本地,而且线上图片的地址必须是在配置的安全域名下,我遇到绘制不出的原因在于:没有等待图片完全下载好就绘制了,所以这里要考虑绘图顺序,可以用image的bindload事件或者downloadTask.onProgressUpdate来监听图片加载过程。


2.小程序的canvas没有裁剪的api,请问如何用canvas将图片画成圆形?

解决方法:

这个问题我是通过制作一张和头像图片一样大的中间有个圆形镂空(中间透明)的正方形图片绘制在头像上,在视觉上给头像做出圆形的效果。


3.`ctx.drawImage`绘制的画布,使用`ctx.clearRect`清除不了。

解决方法:

这个问题我没有解决。


4.模拟器上有个bug就是在画了图片后再画文字,文字会被覆盖,但是去真机上查看是没有问题的,文字可以正常显示。

解决方法:

这个问题是模拟器的bug。


5.为了让canvas不在页面显示,将canvas用view标签包起来后,给view设置了overflow=hidden和opacity=0的属性,是可以成功将canvas隐藏,但是在真机上测试时,一旦在这个隐藏的canvas上绘制图片,canvas又显示在屏幕上了。模拟器上是不会显示的。

解决方法:

由于canvas是原生的组件所以在模拟器上可以被隐藏,但是在真机上一直置于最上层,所以在真机上canvas一旦被绘制就一定会显示。我想了一个奇怪的方法,我在canvas的外层套了一个宽高正好一屏的view标签,然后将view的背景设置为黑色,再让canvas定位到屏幕的中间。这样看起来像是进入了图片预览。然后短暂延迟后通过 wx.canvasToTempFilePath生成图片后再调wx.previewImage。同时再用wx:if把canvas给销毁,用hidden把view给隐藏,页面每次进入的时候再还原初始值。以上是我根据我自己的需求想的折中办法,有相同情况的同学可以参考。(其实我想实现的最最效果是腾讯投票生成朋友圈二维码的那种,他们的canvas就没有显示在页面上,所以我猜想他们可能是在服务器端进行渲染后再传图给前端的)


6.canvas文字不能换行的问题

解决方法:

这个问题我是通过字符串截取的思路做的,固定每行的字数,为了美观用了ctx.setTextAlign('center')让每行字都水平居中对其。


ps:希望小程序官方能统一回答下这些问题,这几个问题中有些问题一直都有很多人问,可是没有一个好的回答,希望官方能有个好的解答谢谢啦!


最后一次编辑于  2017-08-30
回答关注问题邀请回答
收藏

39 个回答

  • Criiy
    Criiy
    2018-08-15

    问题5: canvas的margin-top: -100000px emmm不太文雅但是能解决这个问题

    2018-08-15
    有用 5
    回复
  • Mr姜
    Mr姜
    2019-03-20

    canvas 绘制的头像黑边如何去掉啊? 怎么会有黑边线呢?[图片]

    2019-03-20
    有用 1
    回复
  • 洛竹
    洛竹
    2018-04-27

    自己造了一遍轮子,将就着用。。。。


    使用方法:引入 wxPromise


    /**
     
       * 小程序 canvas 写字自动换行解决方案
     
       * @param  {[string]} text     [在画布上输出的文本]
     
       * @param  {[number]} x        [绘制文本的左上角x坐标位置]
     
       * @param  {[number]} y        [绘制文本的左上角y坐标位置]
     
       * @param  {[number]} column   [一行多少字,如果为0,则代表不自动换行]
     
       * @param  {[number]} maxWidth [需要绘制的最大宽度,可选]
     
       */
     
      wx.pro.fillText = (canvasContext,text,x,y,column,maxWidth) => {
     
        if (column === 0) {
     
          if (maxWidth) {
     
            canvasContext.fillText(text,x,y,maxWidth)
     
          } else {
     
            canvasContext.fillText(text,x,y)
     
          }
     
          return
     
        }
     
        let rows = 0
     
        if (text.length%column >0) {
     
          rows = parseInt(text.length/column)+1
     
        } else {
     
          rows = parseInt(text.length/column)
     
        }
     
        let index = 0
     
        for (var i = 0; i < rows; i++) {
     
          let rowText = text.substring(i*column,i*column+column)
     
          if (/\n/.test(rowText) || rowText.length > column) {
     
            rowText = rowText.split('\n')
     
            rowText.forEach(item => {
     
              index ++
     
              if (maxWidth) {
     
                canvasContext.fillText(item,x,y+(i+index)*column,maxWidth)
     
              } else {
     
                canvasContext.fillText(item,x,y+(i+index)*column)
     
              }
     
            })
     
          } else {
     
            if (maxWidth) {
     
              canvasContext.fillText(rowText,x,y+(i+index+2)*column,maxWidth)
     
            } else {
     
              canvasContext.fillText(rowText,x,y+(i+index+2)*column)
     
            }
     
          }
     
        }
     
      }


    2018-04-27
    有用 1
    回复
  • 陈泽彬
    陈泽彬
    2017-11-08

    canvas的arc画圆弧的时候,设置成逆时针旋转, 有些手机的结束角度参数会变成 旋转多少度,莫名奇妙

    2017-11-08
    有用 1
    回复 1
    • 阿巴阿巴
      阿巴阿巴
      2022-03-28
      是的,我的就是,前两个好好的,后面全部变了...然而现在还没修复
      2022-03-28
      回复
  • George Zhang
    George Zhang
    2017-08-29

    canvas好多bug,包括不能随着swiper左滑右滑


    2017-08-29
    有用 1
    回复
  • 肖本松
    肖本松
    2020-04-29

    我想在上传图片时,给图片加上水印。目前的方法是本地上传图片,获取图片数组。然后循环这个数组,利用canvas给每张图片加上水印。最后获得加上水印的图片数组。

    但是在循环时发现ctx.draw()方法只执行一次。是什么情况

    2020-04-29
    有用
    回复 3
  • 我
    2019-09-24

    canvas如何解析标签


    2019-09-24
    有用
    回复
  • C君
    C君
    2019-07-23

    `ctx.drawImage`绘制的画布,使用`ctx.clearRect`清除不了。这个有什么方法解决么

    2019-07-23
    有用
    回复 2
  • 2018-11-05

    画圆我是这样。

    context.beginPath(); //开始绘制
    //圆心的Y坐标
    //先画个圆, ,圆心距左X,圆心距右y,半径的长,
    context.arc(117, 550, 30, 0, Math.PI * 2, false);
    context.clip();
    // 向画布上绘制图像, X,宽,高
    context.drawImage(imgUrl, 87, 520, 60, 60, 87, 520); // 推进去图片
    context.restore();
    context.clip();


    2018-11-05
    有用
    回复
  • 鲨鱼辣椒
    鲨鱼辣椒
    2018-08-10

    那个canvas隐藏后还在页面显示,直接把canvas用fixed定位,顶出页面不就好了吗

    2018-08-10
    有用
    回复

正在加载...

登录 后发表内容