{"id":13445864,"url":"https://github.com/kuckboy1994/mp_canvas_drawer","last_synced_at":"2025-05-16T02:07:49.768Z","repository":{"id":51648263,"uuid":"140584369","full_name":"kuckboy1994/mp_canvas_drawer","owner":"kuckboy1994","description":":rocket: 微信小程序上canvas绘制图片助手，一个json就制作分享朋友圈图片","archived":false,"fork":false,"pushed_at":"2019-11-14T08:04:34.000Z","size":249,"stargazers_count":1726,"open_issues_count":57,"forks_count":269,"subscribers_count":34,"default_branch":"master","last_synced_at":"2025-04-08T12:11:56.498Z","etag":null,"topics":["canvas","drawer","mp","mpvue","wepy","wxapp","xiaochengxu"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kuckboy1994.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-11T14:08:57.000Z","updated_at":"2025-04-06T11:52:15.000Z","dependencies_parsed_at":"2022-08-22T02:00:30.587Z","dependency_job_id":null,"html_url":"https://github.com/kuckboy1994/mp_canvas_drawer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuckboy1994%2Fmp_canvas_drawer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuckboy1994%2Fmp_canvas_drawer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuckboy1994%2Fmp_canvas_drawer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kuckboy1994%2Fmp_canvas_drawer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kuckboy1994","download_url":"https://codeload.github.com/kuckboy1994/mp_canvas_drawer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254453653,"owners_count":22073617,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["canvas","drawer","mp","mpvue","wepy","wxapp","xiaochengxu"],"created_at":"2024-07-31T05:00:40.848Z","updated_at":"2025-05-16T02:07:49.751Z","avatar_url":"https://github.com/kuckboy1994.png","language":"JavaScript","funding_links":[],"categories":["Libraries","组件","JavaScript"],"sub_categories":["Poster and Screenshot"],"readme":"## canvas drawer\n\n新增 [mpvue_canvas_drawer](https://github.com/kuckboy1994/mpvue_canvas_drawer)。之后同步更新。\n\n新增由[simmzl](https://github.com/simmzl)开发移植的[wepy_canvas_drawer](https://github.com/simmzl/wepy_canvas_drawer)。之后同步更新。\n\n做微信小程序中最好用的 `canvas` 绘图组件之一。\n\n当前环境下，大家都非常需要分享到朋友圈这个功能，但是实现起来各有心酸（坑比较多），所以才有了如下的 `canvas` 绘图工具。 \n\n具有如下特性：\n\n- 简单易用 —— 一个 `json` 搞定绘制图片\n- 功能全 —— 满足 `90%` 的使用场景\n  - 绘制文本（换行、超出内容省略号、中划线、下划线、文本加粗）\n  - 绘制图片\n  - 绘制矩形\n  - 保存图片\n  - 多图绘制\n  - ...\n- 代码量小\n\n## 体验\n\n```\ngit clone https://github.com/kuckboy1994/mp_canvas_drawer\n```\n想在手机上使用配置自己的 `appid` 即可。\n\n编译模式中已经为你配置好比较常用的两种模式：\n- 普通绘制，绘制单张分享图。\n- 多图绘制，连续绘制分享图\n\n## 演示\n\n![](http://wx3.sinaimg.cn/mw690/ec4d7780gy1ft7eihf9f0g206u0bnhdw.gif)\n\n左侧是 `canvasdrawer` 绘制的，右侧是UI给的图\n\n![](http://wx2.sinaimg.cn/mw690/ec4d7780gy1ft7h2qezidj21140qw1kx.jpg)\n\n## 使用\n\n- `git clone https://github.com/kuckboy1994/mp_canvas_drawer` 到本地\n- 把 `components` 中的 `canvasdrawer` 拷贝到自己项目下。\n- 在使用页面注册组件\n  ```json\n  {\n    \"usingComponents\": {\n      \"canvasdrawer\": \"/components/canvasdrawer/canvasdrawer\"\n    }\n  }\n  ```\n- 在页面 `**.wxml` 文件中加入如下代码\n  ```html\n  \u003ccanvasdrawer painting=\"{{painting}}\" bind:getImage=\"eventGetImage\"/\u003e\n  ```\n  `painting` 是需要传入的 `json`。 `getImage` 方法是绘图完成之后的回调函数，在 `event.detail` 中返回绘制完成的图片地址。\n- 当前栗子中的 `painting` 简单展示一下。详细配置请看 [API](https://github.com/kuckboy1994/mp_canvas_drawer#api)\n\n\n  \u003cdetails\u003e\u003csummary\u003epainting（点击展开）\u003c/summary\u003e\u003cbr\u003e\n\n  ```js\n  {\n    width: 375,\n    height: 555,\n    views: [\n      {\n        type: 'image',\n        url: 'https://hybrid.xiaoying.tv/miniprogram/viva-ad/1/1531103986231.jpeg',\n        top: 0,\n        left: 0,\n        width: 375,\n        height: 555\n      },\n      {\n        type: 'image',\n        url: 'https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83epJEPdPqQVgv6D8bojGT4DrGXuEC4Oe0GXs5sMsN4GGpCegTUsBgL9SPJkN9UqC1s0iakjQpwd4h4A/132',\n        top: 27.5,\n        left: 29,\n        width: 55,\n        height: 55\n      },\n      {\n        type: 'image',\n        url: 'https://hybrid.xiaoying.tv/miniprogram/viva-ad/1/1531401349117.jpeg',\n        top: 27.5,\n        left: 29,\n        width: 55,\n        height: 55\n      },\n      {\n        type: 'text',\n        content: '您的好友【kuckboy】',\n        fontSize: 16,\n        color: '#402D16',\n        textAlign: 'left',\n        top: 33,\n        left: 96,\n        bolder: true\n      },\n      {\n        type: 'text',\n        content: '发现一件好货，邀请你一起0元免费拿！',\n        fontSize: 15,\n        color: '#563D20',\n        textAlign: 'left',\n        top: 59.5,\n        left: 96\n      },\n      {\n        type: 'image',\n        url: 'https://hybrid.xiaoying.tv/miniprogram/viva-ad/1/1531385366950.jpeg',\n        top: 136,\n        left: 42.5,\n        width: 290,\n        height: 186\n      },\n      {\n        type: 'image',\n        url: 'https://hybrid.xiaoying.tv/miniprogram/viva-ad/1/1531385433625.jpeg',\n        top: 443,\n        left: 85,\n        width: 68,\n        height: 68\n      },\n      {\n        type: 'text',\n        content: '正品MAC魅可口红礼盒生日唇膏小辣椒Chili西柚情人',\n        fontSize: 16,\n        lineHeight: 21,\n        color: '#383549',\n        textAlign: 'left',\n        top: 336,\n        left: 44,\n        width: 287,\n        MaxLineNumber: 2,\n        breakWord: true,\n        bolder: true\n      },\n      {\n        type: 'text',\n        content: '￥0.00',\n        fontSize: 19,\n        color: '#E62004',\n        textAlign: 'left',\n        top: 387,\n        left: 44.5,\n        bolder: true\n      },\n      {\n        type: 'text',\n        content: '原价:￥138.00',\n        fontSize: 13,\n        color: '#7E7E8B',\n        textAlign: 'left',\n        top: 391,\n        left: 110,\n        textDecoration: 'line-through'\n      },\n      {\n        type: 'text',\n        content: '长按识别图中二维码帮我砍个价呗~',\n        fontSize: 14,\n        color: '#383549',\n        textAlign: 'left',\n        top: 460,\n        left: 165.5,\n        lineHeight: 20,\n        MaxLineNumber: 2,\n        breakWord: true,\n        width: 125\n      }\n    ]\n  }\n  ```\n  \u003c/details\u003e\n\n## API  \n\n\u003cdetails\u003e\u003csummary\u003e对象结构一览\u003c/summary\u003e\u003cbr\u003e\n\n```js\n{\n  width: 375,\n  height: 555,\n  views: [\n    {\n      type: 'image',\n      url: 'url',\n      top: 0,\n      left: 0,\n      width: 375,\n      height: 555\n    },\n    {\n      type: 'text',\n      content: 'content',\n      fontSize: 16,\n      color: '#402D16',\n      textAlign: 'left',\n      top: 33,\n      left: 96,\n      bolder: true\n    },\n    {\n      type: 'rect',\n      background: 'color',\n      top: 0,\n      left: 0,\n      width: 375,\n      height: 555\n    }\n  ]\n}\n```\n\u003c/details\u003e  \n\n\n数据对象的第一层需要三个参数: `width`、`height`、`mode`、`views`。配置中所有的数字都是没有单位的。这就意味着 `canvas` 绘制的是一个比例图。具体显示的大小直接把返回的图片路径放置到 `image` 标签中即可。\n\n`mode` 可选值有 `same`, 默认值为空，常规下尽量不要使用。如要使用请看 Q\u0026A的第1点。\n\n当前可以绘制3种类型的配置: `image`、`text`、`rect`。配置的属性基本上使用的都是 `css` 的驼峰名称，还是比较好理解的。 \n\n### image（图片）\n属性 | 含义 | 默认值 | 可选值\n---|---|---|---\nurl | 绘制的图片地址，可以是本地图片，如：`/images/1.jpeg` | | \ntop | 左上角距离画板顶部的距离 | | \nleft | 左上角距离画板左侧的距离 | | \nwidth | 要画多宽 | 0 | \nheight | 要画多高 | 0 | \n\n### text（文本）\n属性 | 含义 | 默认值 | 可选值\n---|---|---|---\ncontent | 绘制文本 | ''（空字符串） | \ncolor | 颜色 | black | \nfontSize | 字体大小 | 16 | \ntextAlign | 文字对齐方式 | left | center、right \nlineHeight | 行高，只有在多行文本中才有用 | 20 | \ntop | 文本左上角距离画板顶部的距离 | 0 | \nleft | 文本左上角距离画板左侧的距离 | 0 | \nbreakWord | 是否需要换行 | false | true \nMaxLineNumber | 最大行数，只有设置 `breakWord: true` ，当前属性才有效，超出行数内容的显示为... | 2 | \nwidth | 和 `MaxLineNumber` 属性配套使用，`width` 就是达到换行的宽度 |  | \nbolder | 是否加粗 | false | true \ntextDecoration | 显示中划线、下划线效果 | none | underline（下划线）、line-through（中划线）\n\n### rect (矩形，线条)\n属性 | 含义 | 默认值 | 可选值\n---|---|---|---\nbackground | 背景颜色 | black | \ntop | 左上角距离画板顶部的距离 | | \nleft | 左上角距离画板左侧的距离 | | \nwidth | 要画多宽 | 0 | \nheight | 要画多高 | 0 | \n\n## Q\u0026A\n0. 最佳实践\n\n    绘制操作的时候最好 `锁住屏幕` ，例如在点击绘制的时候\n    ```js\n    wx.showLoading({\n      title: '绘制分享图片中',\n      mask: true\n    })\n    ```\n    绘制完成之后\n    ```js\n    wx.hideLoading()\n    ```\n    具体可以参考项目下的 `/pages/multiple`\n1. [mpvue] 由于 `canvasdrawer` 不主动呈现绘制内容，而是交给调用者去使用 `image` 来展示，所以在mpvue更新数据就会render整个组件的，之后 `canvasdrawer` 又会重新被渲染，导致无限循环，所以默认情况下我把代码改为，传入的 `painting` 和之前的一样的话，组件就不渲染了。只有出现差异的内容才会更新（触发回调），这种个人认为还是可以接受的。\n    增加顶层参数 `mode`, `mode: 'same'` 为可以绘制同样的内容。在 `mpvue` 模式下`勿用`。\n2. 二维码和小程序码如何绘制？\n    - 二维码和小程序码可以通过调用[微信官方的接口](https://developers.weixin.qq.com/miniprogram/dev/api/qrcode.html)产生，需要后端配合。\n    - 然后走 `type: image` 类型进行绘制即可。\n3. 绘制流程相关\n    - `views` 数组中的顺序代表绘画的先后顺序，会有覆盖的现象。请各位使用者注意。\n4. 如何实现圆形头像？\n    - 由于完成一些效果，例如： `文字下划线` 等。必须要使用微信小程序 `rect` 相关的接口，和 `clip` 接口感觉相处的不好（存在bug）。可以查看 [微信小程序社区的帖子](https://developers.weixin.qq.com/blogdetail?action=get_post_info\u0026docid=00086255ef09d0df4b0751f6651000\u0026highline=clip\u0026token=895863755\u0026lang=zh_CN)。\n    - so，提供一种解决方式：使用一张中间镂空的图片盖在头像上。\n5. `canvas drawer` 组件为什么不直接显示canvas画板和其内容呢？\n    - 考虑到大部分场景，我们都是用来把图片保存到本地，或用以展示。\n    - 保存到本地，返回临时文件给调用者一定是最佳的解决方式。\n    - 展示，转化成图片之后，就可以使用 `image` 基础组件的所有显示模式了，还能设置宽高。\n\n## 更新计划\n\n- [x] 图片缓存机制 - 加快相同图片绘制的速度\n- [x] 增加 `measureText` 方法对于低版本的提示\n- [x] 安卓下文本绘制稳定性修复\n- [ ] 增加圆角属性 `borderRadius`、`border` 支持\n- [x] 错误异常回调支持\n- [ ] 预缓存模式\n- [ ] 优化 `measureText` 测量模式\n- [x] mpvue 版本小程序\n\n## TIPS\n\n如果有什么疑问，欢迎 `issues`。 如果觉得不错，能不能送我小 ✨ ✨ ，让我有更多的动力。\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuckboy1994%2Fmp_canvas_drawer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkuckboy1994%2Fmp_canvas_drawer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkuckboy1994%2Fmp_canvas_drawer/lists"}