收藏
回答

canvas绘制大量数据卡顿

代码片段:

wechatide://minicode/ROIdcdmz712p


代码片段中 canvas 绘制开发工具下可一直保持流畅(我运行了 5-6 分钟),同样的代码在 web(微信浏览器)流畅运行。

真机下,大概 10 秒就会降到 30 fps,然后大概1分钟不到就会降到 1-2 fps。


虽说可以通过 canvasToTempFilePath 保存已经绘制的内容再重绘图片来降低卡顿,但是操作起来会很麻烦,而且可能会造成绘制丢失

所以想了解下这是什么问题,有没有更好的解决方法?

另外有个小疑惑,原生 canvas 为什么比 web 要卡,用原生 canvas 实现有什么意义?


Thanks for your time!

最后一次编辑于  2018-09-06  (未经腾讯允许,不得转载)
邀请回答
复制链接收藏投诉关注问题回答

29 个回答

  • 葱
    2018-09-06

    确实会有这个问题,我也碰到过

    不知道楼主是啥场景下用canvas ,如果是要导出图片的原因,可以使用view布局,界面呈现动画使用view,将canvas组件定位到屏幕看不见的位置,当动画停止后,再在canvas上绘图就可以了

    我是的小项目是这样做的,可以参考下


    2018-09-06
    赞同 11
    回复 3
    • Talent
      Talent
      2018-09-06

      谢谢,场景不同,我是要还原书写笔迹,必须要用 canvas 贝塞尔曲线画出数据记录的坐标点,这需要不断得向 canvas 绘制贝赛尔曲线,并非导出图片问题。

      2018-09-06
      赞同
      回复
    • 葱
      2018-09-06回复Talent

      那就只能希望官方尽快改进吧 …

      2018-09-06
      赞同
      回复
    • wfei
      wfei
      2018-09-07回复

      兄弟 ,你的小程序似乎没有考虑到授权拒绝的情景,比如,现在一直提示卡片生成中,请稍后。。。

      2018-09-07
      赞同
      回复
  • 晨
    2018-09-06

    怎么访问wechatide://minicode/ROIdcdmz712p 这个


    2018-09-06
    赞同
    回复 1
    • Talent
      Talent
      2018-09-06

      这是代码片段,开发工具-项目-导入代码片段,复制连接进去,最好填上 APPID 可以真机预览

      2018-09-06
      赞同
      回复
  • 卢霄霄
    卢霄霄
    2018-09-06

    你这个是要越画越快,越来越频繁吗?

    2018-09-06
    赞同
    回复 10
    • Talent
      Talent
      2018-09-06

      不是,你看下代码就知道了,每个 5ms 画一条线,画 10 条线后,draw(true) 一次,只是用来模拟大量绘制的,与绘制方法无关

      2018-09-06
      赞同
      回复
    • 卢霄霄
      卢霄霄
      2018-09-06回复Talent

      5ms。。挺短的。。不过50ms才绘制也还好。。你实际场景是画的啥啊

      2018-09-06
      赞同
      回复
    • Talent
      Talent
      2018-09-06回复卢霄霄

      书写笔记还原,因为是文字,坐标点比较多,写满完一页大搞 1-2w左右 个点,要求按照书写时间播放出来

      2018-09-06
      赞同
      回复
    • 卢霄霄
      卢霄霄
      2018-09-06回复Talent

      话说。。你在小程序里直接用webview的页面画,会卡吗?

      2018-09-06
      赞同
      回复
    • Talent
      Talent
      2018-09-06回复卢霄霄

      刚刚试了 webview 相同的代码不会卡,稳定 60fps ,直接 webview 也算是个简单的办法

      2018-09-06
      赞同
      回复
    查看更多(5)
  • Johnson Xu
    Johnson Xu
    2018-09-07

    之前试过draw(true),性能很差。后面改成draw(),每次都重绘全部,反而不卡。

    2018-09-07
    赞同
    回复 1
    • Talent
      Talent
      2018-09-07

      谢谢,这个我知道,但是我的场景每次都要重绘多次贝塞尔,而且会越来越多,最后每次重绘可能要到上万次,不可行。

      2018-09-07
      赞同
      回复
  • 💭xdooi🗯          🍁
    💭xdooi🗯 🍁
    2018-09-07

    欢迎体验,也使用了canva绘图,还行不是特卡顿,吐槽吧


    2018-09-07
    赞同
    回复 4
    • Talent
      Talent
      2018-09-07

      谢谢,哭,完全看不出来哪里有 canvas。

      2018-09-07
      赞同
      回复
    • 💭xdooi🗯          🍁
      💭xdooi🗯 🍁
      2018-09-10回复Talent

      绘制分享图那块有

      2018-09-10
      赞同
      回复
    • 💭xdooi🗯          🍁
      💭xdooi🗯 🍁
      2018-09-10回复Talent

      你用h5 绘制时候会卡顿么?

      2018-09-10
      赞同
      回复
    • Talent
      Talent
      2018-09-10回复💭xdooi🗯 🍁

      h5不会卡

      2018-09-10
      赞同
      回复
  • 陈子羽
    陈子羽
    2018-09-09

    可以考虑下在服务端生成图片啊

    2018-09-09
    赞同
    回复 1
    • Talent
      Talent
      2018-09-09

      只要图片的话客户端就可以,问题是我们需要增加音频以模拟视频来还原书写过程

      2018-09-09
      赞同
      回复
  • ye
    ye
    2018-09-09

    小程序封装的canvas绘图api确实会有不小的问题。

    首先和原生的同步api不同,新增了异步的draw方法,这个方法提供了一个不太靠谱的callback参数,这个回调在一些场景下会miss。

    其次,draw方法的第一个参数reserve,在为true时会有记录之前所有绘制内容的功能,在每次调用时会把历史栈内的所有data都拿出来绘制一遍,这在连续绘制(比如魔方画笔拖动)的实现里就是个灾难。

    另外,同样基于异步实现的imageData的相关api也存在着性能和失真的各种问题。

    于是目前最好的解决办法就是,



    使用webview,在网页里愉快得用原生的canvas。

    2018-09-09
    赞同
    回复 2
    • Talent
      Talent
      2018-09-09

      谢谢分析,大致和我猜测差不多,不知道官方有没有说明过关于 canvas 这部分的原理?

      2018-09-09
      赞同
      回复
    • 我执
      我执
      08-08回复Talent
      可以把连续绘制中使用 setData的变量, 换成顶层对象上的变量。 我这边做的绘制已经勉强可以使用了
      08-08
      赞同
      回复