手机版

轻松生成小程序分享海报

时间:2021-12-07 来源:互联网 编辑:宝哥软件园 浏览:

小程序海报组件

需求

小程序分享到朋友圈只能用小程序代码海报来实现。生成小程序代码有两种方法,一种是使用后端方法,另一种是使用小程序附带的画布。后端方法开发难度大,生成图片内存消耗大,对服务器压力不小。因此,使用小程序的画布是一个不错的选择。但是由于画布中的水很深,坑很多,需要重现书写和渲染过程的海报也不一样,代码冗余难以维护,不同设备版本的情况也不一样,所以对小程序的海报生成组件的需求非常迫切。

在实际开发中,我发现海报中只有很少的元素。只要实现了这些元素,就可以通过一个配置文件生成各种海报。

海报中的元素分类

轻松生成小程序分享海报(图1)

要解决的问题

单元问题canvas隐藏问题圆角矩形、圆角图片多段文字超长文字和多行文字缩写问题矩形包含文字层次问题多元素之间图片大小和渲染大小不一致问题canvas到图片IOS 6.6.7剪辑问题关于获取canvas实例

单位问题

canvas绘制使用px单元,但是不同设备的px需要转换,所以组件中统一使用rpx单元。

通过wx.getSystemInfoSync得到设备的屏幕尺寸,从而得到比例,然后做转换。代码如下:

const SysInfo=wx . GetSystemInfoSync();const screenWidth=SysInfo . screenWidth;this . factor=screenWidth/750;//获取比例函数toPx(rPx) {//rpx到px返回rpx * this.factor}函数toRpx(px) {//px到Rpx返回px/this . factor;

canvas隐藏问题

在绘制海报的过程中,我们不希望用户看到画布,所以必须隐藏画布。起初,我们想到使用display:none。但是这个转换成图片的时候会是空白的,所以这个不行,所以我们只能控制画布的绝对定位,把它移出视觉界面。代码如下:

. canvas . pro { position : absolute;bottom : 0;left :-9999 rpx;}

圆角矩形、圆角图片

由于canvas不提供现成的圆角api,我们只能手工绘制。实际上,圆角矩形由四条线(黄色)和四条弧(红色)组成,如下所示:

轻松生成小程序分享海报(图2)

Arc可以通过使用api canvasContext.arcTo来实现,这个api的参数由两个控制点和一个半径组成,对应上面的例子。

接下来,我们可以轻松编写生成圆角矩形的函数。

/* * *画一个圆角矩形*/_ drawradiausrect (x,y,w,h,r){ const br=r/2;this . CTX . BeginPath();this.ctx.moveTo(this.toPx(x br),this . ToPx(y));//移至此处。CTX。Lineto(这个。topx (x w-br),这个。左上角的topx(y));//就此划清界限。CTX。阿尔托(这个。topx (x w),这个。topx (y),这个。topx (x w),这个。topx(y br));//用这个画弧线。CTX。右上角的line to(thi

s.toPx(x + w), this.toPx(y + h - br)); // 画右边的线 this.ctx.arcTo(this.toPx(x + w), this.toPx(y + h), this.toPx(x + w - br), this.toPx(y + h), this.toPx(br)); // 画右下角的弧 this.ctx.lineTo(this.toPx(x + br), this.toPx(y + h)); // 画下边的线 this.ctx.arcTo(this.toPx(x), this.toPx(y + h), this.toPx(x), this.toPx(y + h - br), this.toPx(br)); // 画左下角的弧 this.ctx.lineTo(this.toPx(x), this.toPx(y + br)); // 画左边的线 this.ctx.arcTo(this.toPx(x), this.toPx(y), this.toPx(x + br), this.toPx(y), this.toPx(br)); // 画左上角的弧}如果是 画线框 就使用 this.ctx.stroke();如果是 画色块 就使用 this.ctx.fill();如果是 圆角图片 就使用this.ctx.clip();this.ctx.drawImage(***);

clip()方法从原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。

多段文字

如果是连续多段不同格式的文字,如果让用户每段文字都指定坐标是不现实的,因为上一段文字的长度是不固定的,这里的解决方案是使用ctx.measureText(基础库 1.9.90 开始支持)Api来计算一段文字的宽度,记住这里返回宽度的单位是px(坑),从而知道下一段文字的坐标。

超长文字和多行文字缩略问题

设置文字的宽度,通过ctx.measureText知道文字的宽度,如果超出设定的宽度,超出部分使用“...”代替;对于多行文字,经测试发现字体的高度大约等于字体大小,并提供lineHeight参数让用户可以自定义行高,这样我们就可以知道下一行的y轴坐标了。

矩形包含文字

这个同样使用ctx.measureText接口,从而控制矩形的宽度,当然这里用户还可以设置paddingLeft和paddingRight字段;

文字的垂直居中问题可以设置文字的基线对齐方式为middle(this.ctx.setTextBaseline('middle');),设置文字的坐标为矩形的中线就可以了;水平居中this.ctx.setTextAlign('center');;

轻松生成小程序分享海报(图3)

多个元素间的层级问题

由于canvas没有Api可以设置绘制元素的层级,只能是根据后绘制层级高于前面绘制的方式,所以需要用户传入zIndex字段,利用数组排序(Array.prototype.sort)后再根据顺序绘制。

图片尺寸和渲染尺寸不一致问题

绘制图片我们使用ctx.drawImage()API;

如果使用drawImage(dx, dy, dWidth, dHeight),图片会压缩尺寸以适应绘制的尺寸,图片会变形,如下图:

在基础库1.9.0起支持drawImage(sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight),sx和sy是源图像的矩形选择框左上角的坐标,sWidth和sHeight是源图像的矩形选择框的宽度和高度,如下图:

轻松生成小程序分享海报(图4)

如果绘制尺寸比源图尺寸宽,那么绘制尺寸的宽度就等于源图宽度;反之,绘制尺寸比源图尺寸高,那么绘制尺寸的高度等于源图高度;

我们可以通过wx.getImageInfoApi获取源图的尺寸;

canvas转图片

在canvas绘制完成后调用wx.canvasToTempFilePathApi将canvas转为图片输出,这样需要注意,wx.canvasToTempFilePath需要写在this.ctx.draw的回调中,并且在组件中使用这个接口需要在第二个入参传入this(坑),如下

this.ctx.draw(false, () => {    wx.canvasToTempFilePath({        canvasId: 'canvasid',        success: (res) => {            wx.hideLoading();            this.triggerEvent('success', res.tempFilePath);        },        fail: (err) => {            wx.hideLoading();            this.triggerEvent('fail', err);        }    }, this);});

版权声明:轻松生成小程序分享海报是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。