评论

wxml-to-canvas 使用规则

安装使用见官方文档,本文主要提及wxml-to-canvas重要使用规则。

先说结论:

仅适用生成简单布局的页面,复杂页面会有大量性能开销。

复杂页面可以其他使用webview嵌入的方式用原生H5代替。

安装使用见官方文档,本文主要提及重要使用规则。

  • 需要为wxml-to-canvas指定width和height属性,默认为400*300,当该尺寸与wxss最大容器尺寸不一致时会有异常
  • 只能使用view、text、image标签
  • view只用于布局、text只用于文字、image只用于图片(可绝对定位作为背景)
  • text、image必须指定width、height
  • view可以不指定height、只指定width,由子元素动态撑高。
  • 渲染高度限制:IOS实际像素 < 4096,实际高度需 < 4096/3 = 1356
  • 动态数据可通过函数结合模板字符串实现
  • 画布高度最好是确定的数字(<1356)
  • lineHeight可使text文本居中,lineHeight值等于height即可
  • 多个absolute元素时,因为没有z-index,template元素自上而下渲染,对应z-index依次增高
  • 元素默认为flex布局,子元素会继承父元素的flex布局属性(row或column)
  • 背景颜色仅可使用backgroundColor,而非background。

性能优化指南

  • 在canvas绘制完成后,可以使用this.widget.canvasToTempFilePath来保存并获取本地临时路径,但是图片可能会比较大,通常会1-2M,实际我们应该尽可能在保证清晰的情况下减小文件大小,我们可以通过canvasToTempFilePath的参数配置来进行调整,如下通常可以保持较小的体积及基本合适的清晰度。更多的配置可详细参考canvasToTempFilePath文档
{
destWidth: canvas组件的宽度,
destHeight: canvas组件的高度,
fileType: 'jpg',
quality: 0.9
}


以下是动态数据与动态高度及基本使用的示例:

//动态wxml : poster-data.js 
const getWxml = (info)=>{
  return `${info.a?`${info.b}`:''}`
}
//动态css
const getStyle = (info)=>{
  return {
    textTest: {
      width: 100,
      height: 20,
      fontSize: info.fontSize
    }
  }
}
//页面使用 : index.js
const { wxml, style } = require('./poster-data.js');
//...
data:{
  canvasHeight: 0,
  info:{
    a:1,
    b:2,
    fontSize: 16
  }
}
onLoad(){
  const tempHeight = this.computeContentHeight()
  this.setData({
    canvasHeight:tempHeight
  },()=>{
    this.widget = this.selectComponent('.widget');//数据就绪后canvas高度已确定,再获取canvas组件实例
  })
}
computeContentHeight(){
  //do something 根据数据动态现实隐藏而修改canvas高度
  return 500;
}

saveImage(){
  wx.showLoading({
    title: '生成中请稍后.',
    mask: false,
  });
  const template = getWxml(this.data.info);//获取template
  const css = getStyle(this.data.info)//获取canvas
  const p1=this.widget.renderToCanvas({wxml:template,style:css});
      p1.then((res)=>{
        const p2 =this.widget.canvasToTempFilePath();//canvas图片保存到本地临时路径
        p2.then(res=>{
          wx.hideLoading();
          this.data.poster = res.tempFilePath
          // 使用微信分享
          wx.showShareImageMenu({
            path:  res.tempFilePath
          });
          // 或保存到本地
          // wx.saveImageToPhotosAlbum({
          // 	filePath: res.tempFilePath,
          // 	success(res){
          // 		console.log(res);
          // 	},
          // 	fail(res){
          // 		console.log(res);
          // 	}
          // });
        });
      });
}
//隐藏canvas
.widget {
  position: absolute;
  left: -999px;
}


参考


最后一次编辑于  2023-08-01  
点赞 4
收藏
评论

6 个评论

  • simple
    simple
    2023-07-10

    那些我们执着的技术会在底层优化后,迅速失去价值。

    2023-07-10
    赞同 2
    回复 7
    • 唐伯猫
      唐伯猫
      2023-07-24
      高人!
      2023-07-24
      回复
    • 陈凯昂
      陈凯昂
      2023-08-16
      这个组件什么时候可以用?
      2023-08-16
      回复
    • simple
      simple
      2023-08-17回复陈凯昂
      关注官方skyline特性的更新日志吧,目前还未对外。
      2023-08-17
      回复
    • 超级中
      超级中
      2023-09-27
      Cannot read property 'layoutBox' of undefined
      2023-09-27
      回复
    • Q
      Q
      2023-11-26
      特意登录上来点赞加评论,高人~
      2023-11-26
      回复
    查看更多(2)
  • 优质山贼
    优质山贼
    01-23

    我很好奇的是,tc是怎么想到要把以前凑合能用的canvas api改成现在的一堆shi的?现在的难用不说,连个文档都没有。

    01-23
    赞同 1
    回复 1
    • Giacomo
      Giacomo
      01-30
      没办法,专心干活的不会拍马屁已经被裁员了,剩下一群猪一样的马屁王在屎里挣扎
      01-30
      1
      回复
  • L
    L
    06-02

    如何使用for循环

    06-02
    赞同
    回复 1
    • simple
      simple
      发表于小程序端
      06-03

      map

      06-03
      回复
  • 超级中
    超级中
    2023-09-27

    Cannot read property 'layoutBox' of undefined 官方demo 报错


    2023-09-27
    赞同
    回复 2
    • simple
      simple
      2023-09-27
      应该图片资源问题,换个自己的网络图片地址吧
      2023-09-27
      1
      回复
    • 小叶子
      小叶子
      09-10回复simple
      果然换个资源可以了👍🏻。官方的demo都报错,遇到不是一次了,本来就是没用过不懂才会去看官方的demo,结果还报错让人找半天哪里有问题真的是......
      09-10
      回复
  • GYP
    GYP
    发表于移动端
    2023-07-10
    https://developers.weixin.qq.com/s/hsAP9Bm77CJn 大师你好,可以帮我看下我的这个代码为啥跑不起?点击生成图片无任何反应
    2023-07-10
    赞同
    回复 1
    • simple
      simple
      发表于小程序端
      2023-07-11

      给的示例没有业务代码

      2023-07-11
      回复
  • 余念
    余念
    2022-10-22

    const p1 = this.widget.renderToCanvas({wxml,style})

    p1.then((res)=>{})

    .catch((err)=>{})

    renderToCanvas这个方法,在有的手机上.then .catch 都不走是为什么?

    wxml,style 这个数据打印出来没有问题

    有什么解决办法吗?

    2022-10-22
    赞同
    回复 4
    • simple
      simple
      2022-10-23
      这个一般都是wxml或style写错了,所以canvas绘制异常了,你检查下这两部分
      2022-10-23
      回复
    • simple
      simple
      2022-10-24
      还有可能就是高度太高了,比如IOS就无法绘制高于1356的,其他情况暂不了解
      2022-10-24
      回复
    • undefined
      undefined
      2022-12-12
      示例的图片无法加载导致无法在canvas渲染的时候报错
      2022-12-12
      回复
    • 王晓聪
      王晓聪
      2023-02-02
      请问这个问题解决了吗
      2023-02-02
      回复
登录 后发表内容