微信小程序绘制海报

前言

实现海报?你想到的应该是html2canvas吧,但,这里是小程序,好像并不通用。只能用canvas一笔一划去描述了吗?答案肯定是不对的,今天介绍一个Painter插件,它可以帮助你快速完成小程序上的海报功能。

想到小程序中有如此大量的生成图片需求,而 Canvas 生成方法又是如此难用和坑爹(有关小程序的坑,可看 https://github.com/Kujiale-Mobile/MP-Keng )。我们就想到可不可以做一款可以很方便生成图片,并且还能屏蔽掉直接使用 Canvas 的一些坑的库呢?对此我们发起了 “画家计划— 通过 json 数据形式,来进行动态渲染并绘制出图片”。

前期准备

github下载插件需要的文件。下载地址:https://github.com/Kujiale-Mobile/Painter。下载文件后找到文件里面的components/painter,复制整个painter文件夹,到你小程序项目的component目录下,若考虑该文件较大,可以采用分包的形式,将文件放入分包中。

组件形式使用插件

需要绘制海报的页面的.json中添加组件,或者在app.json中添加全局的组件。


     
     
  1. { "usingComponents" :
  2. {
  3. "painter" : "./Components/painter/painter"
  4. }
  5. }

绘制界面样式、数据

既然要绘制海报,我们必然需要准备好海报的内容。如:用到的文案、真实的数据、海报素材,包括视频文件、图片文件等等。

准备好以上东西我们需要将这些东西绘制在海报上,我们需要按照一定的格式才能更方便的绘制,而不是像canvas那样一点点去绘制。

这里推荐使用工具Painter海报生成Json工具[https://lingxiaoyi.github.io/painter-custom-poster] 网站。因为使用painter插件可以让我们只要传输Json格式的数据给它,它就能帮我们绘制好页面。在网站内调整好布局后点击复制代码即可拷贝出如下Json格式的代码。


     
     
  1. export default class LastMayday {
  2. palette(params) {
  3. return ({
  4. width: "750rpx",
  5. height: "1200rpx",
  6. background: "#FEF8F3",
  7. views: [{
  8. type: "image",
  9. url: `***/weapp/poster/poster_${params.posterNum}.jpg`,
  10. css: {
  11. width: "750rpx",
  12. height: "1200rpx",
  13. top: "0px",
  14. left: "0px",
  15. mode: "scaleToFill"
  16. }
  17. },
  18. {
  19. type: "image",
  20. url: `${params.avatar}`,
  21. css: {
  22. width: "100rpx",
  23. height: "100rpx",
  24. top: "124rpx",
  25. left: "64rpx",
  26. borderRadius: "100rpx",
  27. mode: "scaleToFill",
  28. shadow: "2rpx 2rpx 4rpx #000",
  29. borderWidth: "1rpx",
  30. borderColor: "#fff"
  31. }
  32. },
  33. {
  34. type: "text",
  35. text: `${params.userName}`,
  36. css: {
  37. color: "#fff",
  38. width: "200rpx",
  39. top: "135rpx",
  40. left: "186rpx",
  41. fontSize: "32rpx",
  42. fontWeight: "bold",
  43. textAlign: "left",
  44. shadow: "4rpx 4rpx 6rpx #000"
  45. }
  46. },
  47. {
  48. type: "text",
  49. text: `${params.className}`,
  50. css: {
  51. color: "#fff",
  52. width: "300rpx",
  53. top: "175rpx",
  54. left: "186rpx",
  55. fontSize: "30rpx",
  56. textAlign: "left",
  57. shadow: "4rpx 4rpx 6rpx #000"
  58. }
  59. },
  60. {
  61. type: "text",
  62. text: `大学习第${params.term}期`,
  63. css: {
  64. color: "#fff",
  65. width: "300rpx",
  66. top: "135rpx",
  67. left: "398rpx",
  68. fontSize: "30rpx",
  69. fontWeight: "bold",
  70. textAlign: "right",
  71. shadow: "4rpx 4rpx 6rpx #000"
  72. }
  73. },
  74. {
  75. type: "image",
  76. url: `${params.medalNum>=1?'***/weapp/badge/badge_1.png':''}`,
  77. css: {
  78. width: "96rpx",
  79. top: "280rpx",
  80. left: "86rpx",
  81. mode: "scaleToFill",
  82. shadow: "2rpx 2rpx 4rpx #000"
  83. },
  84. },
  85. {
  86. type: "image",
  87. url: `${params.medalNum>=2?'***/weapp/badge/badge_2.png':''}`,
  88. css: {
  89. width: "96rpx",
  90. top: "280rpx",
  91. left: "182rpx",
  92. mode: "scaleToFill",
  93. shadow: "2rpx 2rpx 4rpx #000"
  94. },
  95. },
  96. {
  97. type: "image",
  98. url: `${params.medalNum>=3?'***/weapp/badge/badge_3.png':''}`,
  99. css: {
  100. width: "96rpx",
  101. top: "280rpx",
  102. left: "278rpx",
  103. mode: "scaleToFill",
  104. shadow: "2rpx 2rpx 4rpx #000"
  105. },
  106. },
  107. {
  108. type: "image",
  109. url: `${params.medalNum>=4?***/weapp/badge/badge_4.png':''}`,
  110. css: {
  111. width: "96rpx",
  112. top: "280rpx",
  113. left: "374rpx",
  114. mode: "scaleToFill",
  115. shadow: "2rpx 2rpx 4rpx #000"
  116. },
  117. },
  118. {
  119. type: "image",
  120. url: `${params.medalNum>=5?'***/weapp/badge/badge_5.png':''}`,
  121. css: {
  122. width: "96rpx",
  123. top: "280rpx",
  124. left: "470rpx",
  125. mode: "scaleToFill",
  126. shadow: "2rpx 2rpx 4rpx #000"
  127. },
  128. },
  129. {
  130. type: "image",
  131. url: `${params.medalNum>=6?'*****/weapp/badge/badge_6.png':''}`,
  132. css: {
  133. width: "96rpx",
  134. top: "280rpx",
  135. left: "566rpx",
  136. mode: "scaleToFill",
  137. shadow: "2rpx 2rpx 4rpx #000"
  138. },
  139. },
  140. {
  141. type: "text",
  142. text: "完成率达到",
  143. css: {
  144. color: "#fff",
  145. width: "300rpx",
  146. top: "680rpx",
  147. left: "105rpx",
  148. fontSize: "40rpx",
  149. textAlign: "left",
  150. shadow: "4rpx 4rpx 6rpx #000"
  151. }
  152. },
  153. {
  154. type: "text",
  155. text: `${params.ratio}%`,
  156. css: {
  157. color: "#ff4000",
  158. width: "200rpx",
  159. top: "678rpx",
  160. left: "307rpx",
  161. fontSize: "44rpx",
  162. fontWeight: "bold",
  163. textAlign: "left",
  164. shadow: "1rpx 1rpx 2rpx #000"
  165. }
  166. },
  167. {
  168. type: "text",
  169. text: "速度超过了全国",
  170. css: {
  171. color: "#fff",
  172. width: "300rpx",
  173. top: "746rpx",
  174. left: "105rpx",
  175. fontSize: "40rpx",
  176. textAlign: "left",
  177. shadow: "4rpx 4rpx 6rpx #000"
  178. }
  179. },
  180. {
  181. type: "text",
  182. text: `${params.classNum}`,
  183. css: {
  184. color: "#ff4000",
  185. width: "150rpx",
  186. top: "814rpx",
  187. left: "105rpx",
  188. fontSize: "46rpx",
  189. fontWeight: "bold",
  190. textAlign: "left",
  191. shadow: "1rpx 1rpx 2rpx #000"
  192. }
  193. },
  194. {
  195. type: "text",
  196. text: `个班级`,
  197. css: {
  198. color: "#fff",
  199. width: "400rpx",
  200. top: "818rpx",
  201. left: `${105+(params.classNum.toString().length)*30}rpx`,
  202. fontSize: "40rpx",
  203. textAlign: "left",
  204. shadow: "4rpx 4rpx 6rpx #000"
  205. }
  206. },
  207. ]
  208. });
  209. }
  210. }

在painter同级目录下新建一个paletle文件夹,然后在其下新建一个poster.js文件。如下:

 这个文件就是用来处理数据和绘制海报的Js。

使用poster文件

在需要绘制海报的页面的.js中引用文件。

import Poster from '../../Components/palette/poster'
     
     

然后在你需要开始绘制海报的地方执行如下代码:


     
     
  1. let posterParams = {
  2. avatar: this. data.avatar,
  3. userName: this. data.userName,
  4. className: this. data.className,
  5. term: this. data.term,
  6. ratio: this. data.ratio,
  7. classNum: this. data.classNum >= 100000 ? '10万+' : this. data.classNum,
  8. medalNum: this. data.medalNum,
  9. posterNum: this. data.currentIndex
  10. }
  11. wx.showToast({
  12. title: '海报绘制中',
  13. icon: 'loading',
  14. duration: 3000,
  15. })
  16. this.setData({
  17. paintPallette: new Poster().palette(posterParams),
  18. });

可以看到,我们是通过new创建一个Poster实例,然后调用实例的方法palette,方法可以传一个对象,这个对象就是海报需要动态修改的数据。

使用组件

在需要绘制海报的页面的.wxml中使用组件。

<painter customStyle='position: absolute; left: -9999rpx;' palette="{{paintPallette}}" bind:imgOK="onImgOK" bind:imgErr="onImgErr"/>
     
     

其中customStyle:是插件支持的自定义样式,如果需要在海报绘制成功后不希望出现在页面上,可以采用如上的position: absolute; left: -9999rpx;

palette:是绘制海报内容的数据,可以传输从服务器返回过来的数据。

imgOK:是海报绘制成功后的回调,imgErr:是海报绘制失败的回调。


     
     
  1. onImgOK( e) {
  2. that. setData({
  3. imagePath: e. detail. path, //绘制后的图片临时地址
  4. })
  5. }

 

 

 

踩坑预警

1、使用Painter海报生成Json工具复制的代码会有一部分是没有用的,且加上会出错。

 

可以参考我上面的样式属性。需要用到其他样式属性的可以一点点加上查看效果。

2、绘制出来的海报很模糊。我们需要在绘制图片时加上设备的分辨率,代码在拷贝下来的painter.js,里面找到wx.canvasToTempFilePath...这句代码,绘制的宽高加上getApp().systemInfo.pixelRatio。如图:

</article>

微信小程序绘制海报

    <div id="blogColumnPayAdvert">
        <div class="column-group">
            <div class="column-group-item column-group0 column-group-item-one">
                <div class="item-l">
                    <a class="item-target" href="https://blog.csdn.net/qq_26975307/category_9513335.html" target="_blank" title="微信小程序" data-report-click="{&quot;spm&quot;:&quot;1001.2101.3001.6332&quot;}">
                        <img class="item-target" src="https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64" alt="">
                        <span class="title item-target">
                            <span>
                            <span class="tit">微信小程序</span>
                                <span class="dec">专栏收录该内容</span>
                            </span>
                        </span>
                    </a>
                </div>
                <div class="item-m">
                    <span>8 篇文章</span>
                    <span>0 订阅</span>
                </div>
                <div class="item-r">
                        <a class="item-target article-column-bt articleColumnFreeBt" data-id="9513335">订阅专栏</a>
                </div>
            </div>
        </div>
    </div>
<article class="baidu_pl">
    <div id="article_content" class="article_content clearfix">
    <link rel="stylesheet" href="https://csdnimg.cn/release/blogv2/dist/mdeditor/css/editerView/ck_htmledit_views-b3c43d3711.css">
            <div id="content_views" class="htmledit_views">
                <h2><a name="t0"></a>前言</h2> 

实现海报?你想到的应该是html2canvas吧,但,这里是小程序,好像并不通用。只能用canvas一笔一划去描述了吗?答案肯定是不对的,今天介绍一个Painter插件,它可以帮助你快速完成小程序上的海报功能。

想到小程序中有如此大量的生成图片需求,而 Canvas 生成方法又是如此难用和坑爹(有关小程序的坑,可看 https://github.com/Kujiale-Mobile/MP-Keng )。我们就想到可不可以做一款可以很方便生成图片,并且还能屏蔽掉直接使用 Canvas 的一些坑的库呢?对此我们发起了 “画家计划— 通过 json 数据形式,来进行动态渲染并绘制出图片”。

前期准备

github下载插件需要的文件。下载地址:https://github.com/Kujiale-Mobile/Painter。下载文件后找到文件里面的components/painter,复制整个painter文件夹,到你小程序项目的component目录下,若考虑该文件较大,可以采用分包的形式,将文件放入分包中。

组件形式使用插件

需要绘制海报的页面的.json中添加组件,或者在app.json中添加全局的组件。


 
 
  1. { "usingComponents" :
  2. {
  3. "painter" : "./Components/painter/painter"
  4. }
  5. }

绘制界面样式、数据

既然要绘制海报,我们必然需要准备好海报的内容。如:用到的文案、真实的数据、海报素材,包括视频文件、图片文件等等。

准备好以上东西我们需要将这些东西绘制在海报上,我们需要按照一定的格式才能更方便的绘制,而不是像canvas那样一点点去绘制。

这里推荐使用工具Painter海报生成Json工具[https://lingxiaoyi.github.io/painter-custom-poster] 网站。因为使用painter插件可以让我们只要传输Json格式的数据给它,它就能帮我们绘制好页面。在网站内调整好布局后点击复制代码即可拷贝出如下Json格式的代码。


 
 
  1. export default class LastMayday {
  2. palette(params) {
  3. return ({
  4. width: "750rpx",
  5. height: "1200rpx",
  6. background: "#FEF8F3",
  7. views: [{
  8. type: "image",
  9. url: `***/weapp/poster/poster_${params.posterNum}.jpg`,
  10. css: {
  11. width: "750rpx",
  12. height: "1200rpx",
  13. top: "0px",
  14. left: "0px",
  15. mode: "scaleToFill"
  16. }
  17. },
  18. {
  19. type: "image",
  20. url: `${params.avatar}`,
  21. css: {
  22. width: "100rpx",
  23. height: "100rpx",
  24. top: "124rpx",
  25. left: "64rpx",
  26. borderRadius: "100rpx",
  27. mode: "scaleToFill",
  28. shadow: "2rpx 2rpx 4rpx #000",
  29. borderWidth: "1rpx",
  30. borderColor: "#fff"
  31. }
  32. },
  33. {
  34. type: "text",
  35. text: `${params.userName}`,
  36. css: {
  37. color: "#fff",
  38. width: "200rpx",
  39. top: "135rpx",
  40. left: "186rpx",
  41. fontSize: "32rpx",
  42. fontWeight: "bold",
  43. textAlign: "left",
  44. shadow: "4rpx 4rpx 6rpx #000"
  45. }
  46. },
  47. {
  48. type: "text",
  49. text: `${params.className}`,
  50. css: {
  51. color: "#fff",
  52. width: "300rpx",
  53. top: "175rpx",
  54. left: "186rpx",
  55. fontSize: "30rpx",
  56. textAlign: "left",
  57. shadow: "4rpx 4rpx 6rpx #000"
  58. }
  59. },
  60. {
  61. type: "text",
  62. text: `大学习第${params.term}期`,
  63. css: {
  64. color: "#fff",
  65. width: "300rpx",
  66. top: "135rpx",
  67. left: "398rpx",
  68. fontSize: "30rpx",
  69. fontWeight: "bold",
  70. textAlign: "right",
  71. shadow: "4rpx 4rpx 6rpx #000"
  72. }
  73. },
  74. {
  75. type: "image",
  76. url: `${params.medalNum>=1?'***/weapp/badge/badge_1.png':''}`,
  77. css: {
  78. width: "96rpx",
  79. top: "280rpx",
  80. left: "86rpx",
  81. mode: "scaleToFill",
  82. shadow: "2rpx 2rpx 4rpx #000"
  83. },
  84. },
  85. {
  86. type: "image",
  87. url: `${params.medalNum>=2?'***/weapp/badge/badge_2.png':''}`,
  88. css: {
  89. width: "96rpx",
  90. top: "280rpx",
  91. left: "182rpx",
  92. mode: "scaleToFill",
  93. shadow: "2rpx 2rpx 4rpx #000"
  94. },
  95. },
  96. {
  97. type: "image",
  98. url: `${params.medalNum>=3?'***/weapp/badge/badge_3.png':''}`,
  99. css: {
  100. width: "96rpx",
  101. top: "280rpx",
  102. left: "278rpx",
  103. mode: "scaleToFill",
  104. shadow: "2rpx 2rpx 4rpx #000"
  105. },
  106. },
  107. {
  108. type: "image",
  109. url: `${params.medalNum>=4?***/weapp/badge/badge_4.png':''}`,
  110. css: {
  111. width: "96rpx",
  112. top: "280rpx",
  113. left: "374rpx",
  114. mode: "scaleToFill",
  115. shadow: "2rpx 2rpx 4rpx #000"
  116. },
  117. },
  118. {
  119. type: "image",
  120. url: `${params.medalNum>=5?'***/weapp/badge/badge_5.png':''}`,
  121. css: {
  122. width: "96rpx",
  123. top: "280rpx",
  124. left: "470rpx",
  125. mode: "scaleToFill",
  126. shadow: "2rpx 2rpx 4rpx #000"
  127. },
  128. },
  129. {
  130. type: "image",
  131. url: `${params.medalNum>=6?'*****/weapp/badge/badge_6.png':''}`,
  132. css: {
  133. width: "96rpx",
  134. top: "280rpx",
  135. left: "566rpx",
  136. mode: "scaleToFill",
  137. shadow: "2rpx 2rpx 4rpx #000"
  138. },
  139. },
  140. {
  141. type: "text",
  142. text: "完成率达到",
  143. css: {
  144. color: "#fff",
  145. width: "300rpx",
  146. top: "680rpx",
  147. left: "105rpx",
  148. fontSize: "40rpx",
  149. textAlign: "left",
  150. shadow: "4rpx 4rpx 6rpx #000"
  151. }
  152. },
  153. {
  154. type: "text",
  155. text: `${params.ratio}%`,
  156. css: {
  157. color: "#ff4000",
  158. width: "200rpx",
  159. top: "678rpx",
  160. left: "307rpx",
  161. fontSize: "44rpx",
  162. fontWeight: "bold",
  163. textAlign: "left",
  164. shadow: "1rpx 1rpx 2rpx #000"
  165. }
  166. },
  167. {
  168. type: "text",
  169. text: "速度超过了全国",
  170. css: {
  171. color: "#fff",
  172. width: "300rpx",
  173. top: "746rpx",
  174. left: "105rpx",
  175. fontSize: "40rpx",
  176. textAlign: "left",
  177. shadow: "4rpx 4rpx 6rpx #000"
  178. }
  179. },
  180. {
  181. type: "text",
  182. text: `${params.classNum}`,
  183. css: {
  184. color: "#ff4000",
  185. width: "150rpx",
  186. top: "814rpx",
  187. left: "105rpx",
  188. fontSize: "46rpx",
  189. fontWeight: "bold",
  190. textAlign: "left",
  191. shadow: "1rpx 1rpx 2rpx #000"
  192. }
  193. },
  194. {
  195. type: "text",
  196. text: `个班级`,
  197. css: {
  198. color: "#fff",
  199. width: "400rpx",
  200. top: "818rpx",
  201. left: `${105+(params.classNum.toString().length)*30}rpx`,
  202. fontSize: "40rpx",
  203. textAlign: "left",
  204. shadow: "4rpx 4rpx 6rpx #000"
  205. }
  206. },
  207. ]
  208. });
  209. }
  210. }

在painter同级目录下新建一个paletle文件夹,然后在其下新建一个poster.js文件。如下:

 这个文件就是用来处理数据和绘制海报的Js。

使用poster文件

在需要绘制海报的页面的.js中引用文件。

import Poster from '../../Components/palette/poster'
 
 

然后在你需要开始绘制海报的地方执行如下代码:


 
 
  1. let posterParams = {
  2. avatar: this. data.avatar,
  3. userName: this. data.userName,
  4. className: this. data.className,
  5. term: this. data.term,
  6. ratio: this. data.ratio,
  7. classNum: this. data.classNum >= 100000 ? '10万+' : this. data.classNum,
  8. medalNum: this. data.medalNum,
  9. posterNum: this. data.currentIndex
  10. }
  11. wx.showToast({
  12. title: '海报绘制中',
  13. icon: 'loading',
  14. duration: 3000,
  15. })
  16. this.setData({
  17. paintPallette: new Poster().palette(posterParams),
  18. });

可以看到,我们是通过new创建一个Poster实例,然后调用实例的方法palette,方法可以传一个对象,这个对象就是海报需要动态修改的数据。

使用组件

在需要绘制海报的页面的.wxml中使用组件。

<painter customStyle='position: absolute; left: -9999rpx;' palette="{{paintPallette}}" bind:imgOK="onImgOK" bind:imgErr="onImgErr"/>
 
 

其中customStyle:是插件支持的自定义样式,如果需要在海报绘制成功后不希望出现在页面上,可以采用如上的position: absolute; left: -9999rpx;

palette:是绘制海报内容的数据,可以传输从服务器返回过来的数据。

imgOK:是海报绘制成功后的回调,imgErr:是海报绘制失败的回调。


 
 
  1. onImgOK( e) {
  2. that. setData({
  3. imagePath: e. detail. path, //绘制后的图片临时地址
  4. })
  5. }

 

 

 

踩坑预警

1、使用Painter海报生成Json工具复制的代码会有一部分是没有用的,且加上会出错。

 

可以参考我上面的样式属性。需要用到其他样式属性的可以一点点加上查看效果。

2、绘制出来的海报很模糊。我们需要在绘制图片时加上设备的分辨率,代码在拷贝下来的painter.js,里面找到wx.canvasToTempFilePath...这句代码,绘制的宽高加上getApp().systemInfo.pixelRatio。如图:

</article>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值