微信小程序实现海报功能经历

前言

大家好,我是《前端发现》。发现前端,发现技术,让前端变得更加容易。

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

前期准备

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

组件形式使用插件

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

{  "usingComponents": 
	{   
		 "painter":"./Components/painter/painter"
	}
}

绘制界面样式、数据

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

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

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

export default class LastMayday {
  palette(params) {
    return ({
      width: "750rpx",
      height: "1200rpx",
      background: "#FEF8F3",
      views: [{
          type: "image",
          url: `***/weapp/poster/poster_${params.posterNum}.jpg`,
          css: {
            width: "750rpx",
            height: "1200rpx",
            top: "0px",
            left: "0px",
            mode: "scaleToFill"
          }
        },
        {
          type: "image",
          url: `${params.avatar}`,
          css: {
            width: "100rpx",
            height: "100rpx",
            top: "124rpx",
            left: "64rpx",
            borderRadius: "100rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000",
            borderWidth:"1rpx",
            borderColor:"#fff"
          }
        },
        {
          type: "text",
          text: `${params.userName}`,
          css: {
            color: "#fff",
            width: "200rpx",
            top: "135rpx",
            left: "186rpx",
            fontSize: "32rpx",
            fontWeight: "bold",
            textAlign: "left",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
        {
          type: "text",
          text: `${params.className}`,
          css: {
            color: "#fff",
            width: "300rpx",
            top: "175rpx",
            left: "186rpx",
            fontSize: "30rpx",
            textAlign: "left",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
        {
          type: "text",
          text: `大学习第${params.term}期`,
          css: {
            color: "#fff",
            width: "300rpx",
            top: "135rpx",
            left: "398rpx",
            fontSize: "30rpx",
            fontWeight: "bold",
            textAlign: "right",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
        {
          type: "image",
          url: `${params.medalNum>=1?'***/weapp/badge/badge_1.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "86rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "image",
          url: `${params.medalNum>=2?'***/weapp/badge/badge_2.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "182rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "image",
          url: `${params.medalNum>=3?'***/weapp/badge/badge_3.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "278rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "image",
          url: `${params.medalNum>=4?***/weapp/badge/badge_4.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "374rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "image",
          url: `${params.medalNum>=5?'***/weapp/badge/badge_5.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "470rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "image",
          url: `${params.medalNum>=6?'*****/weapp/badge/badge_6.png':''}`,
          css: {
            width: "96rpx",
            top: "280rpx",
            left: "566rpx",
            mode: "scaleToFill",
            shadow:"2rpx 2rpx 4rpx #000"
          },
        },
        {
          type: "text",
          text: "完成率达到",
          css: {
            color: "#fff",
            width: "300rpx",
            top: "680rpx",
            left: "105rpx",
            fontSize: "40rpx",
            textAlign: "left",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
        {
          type: "text",
          text: `${params.ratio}%`,
          css: {
            color: "#ff4000",
            width: "200rpx",
            top: "678rpx",
            left: "307rpx",
            fontSize: "44rpx",
            fontWeight: "bold",
            textAlign: "left",
            shadow: "1rpx 1rpx 2rpx #000"
          }
        },
        {
          type: "text",
          text: "速度超过了全国",
          css: {
            color: "#fff",
            width: "300rpx",
            top: "746rpx",
            left: "105rpx",
            fontSize: "40rpx",
            textAlign: "left",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
        {
          type: "text",
          text: `${params.classNum}`,
          css: {
            color: "#ff4000",
            width: "150rpx",
            top: "814rpx",
            left: "105rpx",
            fontSize: "46rpx",
            fontWeight: "bold",
            textAlign: "left",
            shadow: "1rpx 1rpx 2rpx #000"
          }
        },
        {
          type: "text",
          text: `个班级`,
          css: {
            color: "#fff",
            width: "400rpx",
            top: "818rpx",
            left: `${105+(params.classNum.toString().length)*30}rpx`,
            fontSize: "40rpx",
            textAlign: "left",
            shadow:"4rpx 4rpx 6rpx #000"
          }
        },
      ]
    });
  }
}

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

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

使用poster文件

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

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

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

let posterParams = {
  avatar: this.data.avatar,
  userName: this.data.userName,
  className: this.data.className,
  term: this.data.term,
  ratio: this.data.ratio,
  classNum: this.data.classNum >= 100000 ? '10万+' : this.data.classNum,
  medalNum: this.data.medalNum,
  posterNum: this.data.currentIndex
}
wx.showToast({
  title: '海报绘制中',
  icon: 'loading',
  duration: 3000,
})
this.setData({
  paintPallette: new Poster().palette(posterParams),
});

可以看到,我们是通过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:是海报绘制失败的回调。

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

踩坑预警

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

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

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

欢迎补充…

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端发现

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值