在小程序做海报的话,Painter就很给力

点赞 + 关注 + 收藏 = 学会了

最近做了一款粉丝向的小程序,主要功能是编辑海报信息。

微信小程序提供的 Canvas 功能用起来太麻烦了,有库当然是用库易库啦~而且是越简单越好的库~

如果只是要实现海报功能的话,Painter 就非常合适。它使用 JSON 配置数据,像写 CSS 一样,快速在小程序 <canvas> 上生成图片。

本文快速过一遍 Painter 的安装方法和常用的功能。

安装 Painter

1、访问 Painter 的 GitHub 仓库:github.com/manycore-ma...

2、下载或克隆整个项目。

3、将仓库中的 components/painter 文件夹完整地复制到您小程序的 components 目录下(例如:your-miniprogram/components/painter)。

基础用法

Painter 和我们常见的 Canvas 库在渲染流程上有一丢丢不同。

我们在 Web 端常用的 Canvas 库(比如 Fabric.js、Konva.js)都是直接绑定一个 Canvas 元素然后在上边涂涂画画。

而 Painter 需要先提供数据给它生成图片,然后再通过 <image> 元素将图片渲染出来。

引入 Painter 组件

按照前面的操作,已经把 Painter 下载到你项目里了。

然后在需要使用 Painter 的页面或者组件的 .json 文件中引入 Painter。

json 复制代码
// pages/your-page/your-page.json

{
  "usingComponents": {
    "painter": "/components/painter/painter"
  }
}

做完这步就可以使用 Painter 了。

基础配置

在页面中(*.wxml)使用 Painter 至少需要2个元素。

html 复制代码
<view>
  <Painter />
  <image />
</view>

虽然页面有 <Painter /> 组件,但不会渲染出来的,简单来说就是肉眼看不见它。

真正展示内容的是 <image />

但此时还没能开始工作。Painter 需要接收一些"数据"才能将其生成图片,而生成图片后还要通过 imgOK 监听,监听到图片生成后再通知 <image /> 可以渲染了。

所以,上面的 HTML 代码要补几个属性。

html 复制代码
<view>
  <painter 
    palette="{{paintJson}}" 
    bind:imgOK="onImgOK" 
  />

  <image
    src="{{finalPath}}"
  />
</view>
  • palette 属性绑定了要渲染的数据。
  • bind:imgOK 绑定一个方法,用来监听通过 palette 接收的数据是否渲染成功。
  • <image />src 指向 Painter 生成的图片地址。

在 JS 这边,我打算在页面加载成功后立刻给一行字 Painter 让它生成一张图片。

less 复制代码
// pages/index/index.js
Page({
  data: {
    paintJson: {}, // 存储用于绘制的 JSON 数据
    finalPath: '', // 存储最终生成图片的本地路径
  },

  // 接收绘制成功的图片路径
  onImgOK(e) {
    const { path } = e.detail;
    this.setData({
      finalPath: path
    });
  },

  // 构建绘制所需的 JSON 数据
  createPosterData() {
    return {
      width: '600px',
      height: '800px',
      background: '#f8f8f8',
      views: [
        {
          type: 'text',
          text: '雷猴世界',
          css: {
            fontSize: '72px',
            color: 'red'
          }
        },
      ]
    };
  },
  onLoad(options) {
    // 在页面加载时,需要绘制的数据
    this.setData({
      paintJson: this.createPosterData()
    });
  }
})

Painter 通过 palette 接收要渲染的数据,这个数据中必传的值有这几个:

  • width:设置图片的宽度,类型是字符串。比如 '600px'。
  • height:设置图片的高度,类型是字符串。比如 '800px'。
  • views:核心!定义要绘制的所有视图元素,类型是数组。`[{...}, {...}]``

views 数组中的每个对象都代表图片上的一个元素(例如:文字、图片、矩形等),它至少包含 typecss 两个核心属性。

type 用来声明该元素是什么类型的元素,css 就是这个元素的样式了,支持大部分 CSS 属性。

细心的工友可能发现了,上面这个例子中给画布设置的宽高是 600 x 800 像素,应该是一个"高"的画布,为什么在页面渲染出来这么"胖"呢?

因为小程序的 image 组件默认宽度320px、高度240px,是一个"胖"图片。

但这不影响导出图片的宽高比,比如我这里设置的是 600 x 800,我们用小程序提供的图片导出方法看看。

在页面添加一个"保存图片"的按钮。

html 复制代码
<view>
  <!-- 省略其他代码 -->

  <button bind:tap="saveImg">保存图片</button>
</view>

在js里增加一个 saveImg 方法导出图片。

js 复制代码
// 省略其他代码

// 保存图片
saveImg() {
  wx.saveImageToPhotosAlbum({
    filePath: this.data.finalPath,
    success() {
      wx.showToast({
        title: '保存成功',
        icon: 'success'
      });
    }
  })
},

可以看到,导出后的图片是保持在 JS 里画布设置的尺寸。

如果想在页面展示时让图片保持画布设置的宽高比,我的一个小技巧是将画布的宽高存到 data 里,然后画布和 <image> 共用套宽高,或者<image> 元素也可以根据页面布局和画布宽高比动态计算一个宽高出来。

那么页面部分的代码

html 复制代码
<!-- 省略部分代码 -->

<image
  src="{{finalPath}}"
  style="width: {{imgWidth}}rpx; height: {{imgHeight}}rpx"
/>

JS 部分的代码

js 复制代码
// 省略部分代码

// 构建绘制所需的 JSON 数据
createPosterData() {
  return {
    width: `${this.data.imgWidth}px`,
    height: `${this.data.imgHeight}px`,
    background: '#f8f8f8',
    views: [
      {
        type: 'text',
        text: '雷猴世界',
        css: {
          fontSize: '72px',
          color: 'red'
        }
      },
    ]
  };
},

这样就能保证预览图的比例是正确的了。

常用属性

通过前面的例子应该大概了解 Painter 的基础用法了吧。

其实真正配置的地方是 views 数组。

type 属性支持文本(text)、图片(image)、矩形(rect)和二维码(qrcode)。

接下来逐一讲解这几种元素的基础用法。

文本

渲染文本的话,type 需要填 "text"。然后 text 的值就是要渲染的文本内容。

js 复制代码
views: [
  {
	  type: 'text',
  	text: '文本内容'
  }
]

要给文本添加样式很简单,和 CSS 的用法是差不多的。

less 复制代码
views: [
  {
    type: 'text',
    text: '雷猴世界',
    css: {
      top: '200px', // 画布上方的距离
      left: '100px', // 画布左侧的距离
      fontSize: '100px', // 字号
      color: 'red', // 文字颜色
      rotate: '45', // 旋转角度
    }
  },
]

如果想设置多行文字,或者在画布渲染多个元素,只需在 views 数组里添加多个对象即可。

less 复制代码
views: [
  {
    type: 'text',
    text: '雷猴世界',
    css: {
      top: '20px', // 画布上方的距离
      left: '10px', // 画布左侧的距离
      fontSize: '100px', // 字号
      color: 'red', // 文字颜色
    }
  },
  {
    type: 'text',
    text: '德育处主任',
    css: {
      top: '140px', // 画布上方的距离
      left: '10px', // 画布左侧的距离
      fontSize: '100px', // 字号
      color: 'blue', // 文字颜色
    }
  },
]

需要注意的是要配置好各个元素的 topleft,不然就重叠了。

图片

渲染图片的话,type 需要填 "image",然后还要给图片元素配一个 url (图片地址)。

比如,我把图片放在项目的 assets/image 里。

js 复制代码
views: [
  {
    type: 'image',
    url: '/assets/image/f2o30Al.png'
  },
]

这个 url 也支持网络地址,但存在服务器的图片,这个服务器要在微信小程序后台配置到合法域名列表里。也就是说,如果是白嫖赛博菩萨的图床,那基本是无法在小程序里使用网络图片了。

给图片设置样式同样在 css 里配置。

js 复制代码
views: [
  {
    type: 'image',
    url: '/assets/image/f2o30Al.png',
    css: {
      top: '100px', // 图片距离画布上方的距离
      right: '20px', // 图片距离画布右侧的距离
      width: '300px', // 设置图片宽度(只设置宽度的话,高度会等比缩放)
    }
  },
]

矩形

渲染矩形的话,type 需要填 "rect"。然后 text 的值就是要渲染的文本内容。

js 复制代码
views: [
  {
    type: 'rect',
    css: {
      width: '300px', // 设置矩形宽度
      height: '150px', // 设置矩形高度
    }
  },
]

创建矩形的时候必须给矩形设置宽高,不然回报错的。

需要注意的是,给矩形填充颜色用的是属性是 color,这跟我们在 canvas 里使用 fill 以及在 CSS 里使用 backgroundColor 有所不同。

js 复制代码
views: [
  {
    type: 'rect',
    css: {
      width: '300px', // 设置矩形宽度
      height: '150px', // 设置矩形高度
      color: 'orange'
    }
  },
]

如果需要创建圆形或者椭圆,创建方法和 CSS 的方式是一样的,加圆角。

js 复制代码
views: [
  {
    type: 'rect',
    css: {
      width: '300px', // 设置矩形宽度
      height: '300px', // 设置矩形高度
      color: 'orange',
      borderRadius: '150px',
    }
  },
]

二维码

渲染二维码的话,type 需要填 "qrcode"

二维码都内容填在 content 属性里。

同时还要给二维码设置宽高,不然会报错。

js 复制代码
views: [
  {
    type: 'qrcode',
    content: 'http://weixin.qq.com/r/mp/rkPm-uPEVL4rraed9xa8',
    css: {
      width: '300px',
      height: '300px'
    }
  },
]

如果想给二维码上色,和矩形的方式一样,配置一下 color 属性就可以了。

js 复制代码
views: [
  {
    type: 'qrcode',
    content: 'http://weixin.qq.com/r/mp/rkPm-uPEVL4rraed9xa8',
    css: {
      width: '300px',
      height: '300px',
      color: 'red'
    }
  },
]

以上就是本文的全部内容了,更多用法可以参考 Painter 官方文档 painterjs.github.io/docs.html

点赞 + 关注 + 收藏 = 学会了

相关推荐
匠心码员2 小时前
Git Commit 提交规范:让每一次提交都清晰可读
前端
骑斑马的李司凌2 小时前
调试时卡半天?原来127.0.0.1和localhost的区别这么大!
前端
哈哈O哈哈哈2 小时前
Electron + Vue 3 + Node.js 的跨平台桌面应用示例项目
前端
ycbing2 小时前
设计并实现一个 MCP Server
前端
千寻girling2 小时前
面试官: “ 说一下怎么做到前端图片尺寸的响应式适配 ”
前端·javascript·面试
少莫千华2 小时前
【Web API】RESTful API接口规范
前端·后端·json·api·restful·rest
掘金酱2 小时前
2025年度稀土掘金影响力榜单发布!
前端·人工智能·后端
GISer_Jing2 小时前
AI编程革命:Trae如何重塑前端开发
前端·前端框架·aigc·ai编程
豌豆学姐3 小时前
Sora2 视频生成 API 如何对接?附可直接使用的开源前端项目
前端·人工智能·开源·aigc·php