前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >轻松生成小程序分享海报

轻松生成小程序分享海报

作者头像
honey缘木鱼
发布于 2018-09-26 09:27:09
发布于 2018-09-26 09:27:09
2.5K00
代码可运行
举报
文章被收录于专栏:娱乐心理测试娱乐心理测试
运行总次数:0
代码可运行

需求

小程序分享到朋友圈只能使用小程序码海报来实现,生成小程序码的方式有两种,一种是使用后端方式,一种是使用小程序自带的canvas生成;后端的方式开发难度大,由于生成图片耗用内存比较大对服务端也是不小的压力;所以使用小程序的canvas是一个不错的选择,但由于canvas水比较深,坑比较多,还有不同海报需要重现写渲染流程,导致代码冗余难以维护,加上不同设备版本的情况不一样,因此小程序海报生成组件的需求十分迫切。

在实际开发中,我发现海报中的元素无非一下几种,只要实现这几种,就可以通过一份配置文件生成各种各样的海报了。

海报中的元素分类

<ignore_js_op style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal;">

image

</ignore_js_op>

要解决的问题

  • 单位问题
  • canvas隐藏问题
  • 圆角矩形、圆角图片
  • 多段文字
  • 超长文字和多行文字缩略问题
  • 矩形包含文字
  • 多个元素间的层级问题
  • 图片尺寸和渲染尺寸不一致问题
  • canvas转图片
  • IOS 6.6.7 clip问题
  • 关于获取canvas实例

单位问题

canvas绘制使用的是px单位,但不同设备的px是需要换算的,所以在组件中统一使用rpx单位,这里就涉及到单位怎么换算问题。

通过wx.getSystemInfoSync获取设备屏幕尺寸,从而得到比例,进而做转换,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const sysInfo = wx.getSystemInfoSync();
const screenWidth = sysInfo.screenWidth;
this.factor = screenWidth / 750;    // 获取比例
function toPx(rpx) {    // rpx转px
    return rpx * this.factor;
}
function toRpx(px) {    // px转rpx
    return px / this.factor;
},**canvas隐藏问题**

在绘制海报过程时,我们不想让用户看到canvas,所以我们必须把canvas隐藏起来,一开始想到的是使用display:none; 但这样在转化成图片时会空白,所以这个是行不通的,所以只能控制canvas的绝对定位,将其移出可视界面,代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.canvas.pro {
    position: absolute;
    bottom: 0;
    left: -9999rpx;
}**圆角矩形、圆角图片**

由于canvas没有提供现成的圆角api,所以我们只能手工画啦,实际上圆角矩形就是由4条线(黄色)和4个圆弧(红色)组成的,如下:

<ignore_js_op style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal;">

image

</ignore_js_op>

圆弧可以使用canvasContext.arcTo这个api实现,这个api的入参由两个控制点一个半径组成,对应上图的示例

canvasContext.arcTo(x1, y1, x2, y2, r)

接下来我们就可以非常轻松的写出生成圆角矩形的函数啦

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
* 画圆角矩形
*/

_drawRadiusRect(x, y, w, h, r) {
    const br = r / 2;
    this.ctx.beginPath();
    this.ctx.moveTo(this.toPx(x + br), this.toPx(y));           // 移动到左上角的点
    this.ctx.lineTo(this.toPx(x + w - br), this.toPx(y));       // 画上边的线
    this.ctx.arcTo(this.toPx(x + w), this.toPx(y), this.toPx(x + w), this.toPx(y + br), this.toPx(br));                                                 // 画右上角的弧       
    this.ctx.lineTo(this.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();

如果是圆角图片就使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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');;

<ignore_js_op style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal;">

image

</ignore_js_op>

多个元素间的层级问题

由于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是源图像的矩形选择框的宽度和高度,如下图:

<ignore_js_op style="word-wrap: break-word; margin: 0px; padding: 0px; text-decoration: none; font-style: normal;">

image

</ignore_js_op>

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

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

canvas转图片

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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);
});
**iOS 6.6.7 clip问题**

在iOS 6.6.7版本中clip方法连续裁剪图片时,只有第一张有效,这是微信的bug,官方也证实了(https://developers.weixin.qq.com/community/develop/buglist

关于获取canvas实例

我们可以使用wx.createCanvasContext获取小程序实例,但在组件中使用切记第二个参数需要带上this,如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.ctx = wx.createCanvasContext('canvasid', this);**如何使用组件**

https://github.com/jasondu/wxa-plugin-canvas

原创作者:微信小程序联盟博主weizaidu

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.09.14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
轻松生成小程序分享海报的神器来了
小程序是一种不用下载就能使用的应用,也是一项门槛非常高的创新,经过将近两年的发展,已经构造了新的小程序开发环境和开发者生态。小程序越来越火爆,基于微信的各类小程序优秀项目真实层出不穷,小程序商城更是成为了企业商家的标配,
用户7690885
2021/04/20
8420
新手必看!小程序中用 JSON 绘制海报?真的太简单了!【建议收藏】
大家好,我是HoMeTown,生成海报相信大家有的人都做过,但是canvas绘图的坑太多。大家可以试试这个组件 painter。
HoMeTown
2023/08/23
2640
新手必看!小程序中用 JSON 绘制海报?真的太简单了!【建议收藏】
手把手教你撸一个小程序带太阳码的海报分享
我们都知道,微信小程序目前还不支持转发朋友圈,可能现在Android是支持了,iOS还不支持,但总的来说还不能支持普遍机型。这样假如我们需要推荐某个心仪的商品到朋友圈就没法分享出去,于是就可以使用生成海报的形式,让商品详情页的信息显示在一张图片上,保存到手机相册,然后发朋友圈,朋友可以长按识别海报上的小程序码直达该商品详情页面,从而达到如同直接分享商品详情页的效果。
悟空码字
2021/03/23
2.1K0
小程序如何生成海报分享朋友圈
项目需求写完有一段时间了,但是还是想回过来总结一下,一是对项目的回顾优化等,二是对坑的地方做个记录,避免以后遇到类似的问题。
super.x
2019/07/02
1.5K0
干货 | 用uni-app制作迷你PS小程序
该文章主要讲解最近基于 uni-app 框架编写的集图文拖拽等多方位编辑、油墨电子签名、开放式海报于一体的小程序的制作思路和实现代码。 1、完整源码链接: 完整代码:https://github.com/TensionMax/mini-ps 其中演示的文字编辑、图片编辑、油墨电子签名、开放式海报可单独使用,含文档说明。 2、实现思路 该工具主要由五个不同组件模块:文字编辑、图片编辑,油墨电子签名、控制、开放式海报 1、文字编辑模块设置好的文字参数对象插入到文字队列中。 2、图片编辑模块设置好的
腾讯NEXT学位
2020/02/24
1.3K0
干货 | 用uni-app制作迷你PS小程序
【小程序】728- 小程序如何生成海报分享朋友圈
https://segmentfault.com/a/1190000019083548
pingan8787
2020/09/30
1.4K0
【小程序】728- 小程序如何生成海报分享朋友圈
Canvas绘图在微信小程序中的应用:生成个性化海报
从2012年开始,微信那个时候用户的积累的量已经非常大了,推出公众号,当然大屏智能手机在那个时候也流行,传统的大众媒体逐步消亡,像微信公众号这样的新媒体盛行。企业的广告投入开始从电视等传统媒体向基于圈层文化的新媒体精准营销转移,甚至很多企业尤其互联网企业开始思考如何利用用户的自传播这种方式去宣传企业、实现商业目标。而用户的自传播很好的途径就是生产个性化的海报。举个最常见的例子,我第一次使用Keep是因为在朋友圈看到朋友分享她运动量的一个截图,当时在我看来非常酷,有心率脉搏呀、时速运动量啊、消耗的卡路里等,还有一个二维码,然后我就点了下载了Keep,这整个获客成本几乎为0,秒秒钟就多了一个用户。而实现这一过程的技术手段就可以用canvas。所以,canvas的盛行,与企业的精准营销和用户的自传播有很大的关系。 如极客时间的一些实现案例:
胡琦
2021/09/09
1.5K0
【Web技术】929- 前端海报生成的不同方案和优劣
首页测试demo:https://html2canvas.hertzen.com/
pingan8787
2021/04/26
1.5K0
【Web技术】929- 前端海报生成的不同方案和优劣
【Canvas】266- 更优雅地基于 canvas 在前端画海报
我们的业务涉及电商、教育行业,出于营销以及功能需要,会有很多卡片展示(长按保存)的需求,或者分享长图的需求。以及我们有面向商家的 PC 端,商家端又能编辑、实时预览卡片的样式。
pingan8787
2019/07/25
1.6K0
【Canvas】266- 更优雅地基于 canvas 在前端画海报
微信小程序分享图片的简易canvas工具类
如有需要请自取:GitHub微信小程序保存图片分享的 canvas 简易自用工具类
韦弦zhy
2018/12/05
1.5K0
微信小程序分享图片的简易canvas工具类
微信小程序之分享海报生成
为了吸引更多的用户,设计好一个分享海报还是很有必要的。而小程序要生成一个海报还是有点坑的,下面分享下我们打卡小程序的一些经验。
IMWeb前端团队
2019/12/03
3.5K0
微信小程序之分享海报生成
小程序 canvas 生成海报 一次搞掂
需要注意的是,目前的canvas可以简单分为两种。一种是传统网页中的canvas,一种是小程序中的canvas。两者的功能是完全一样的。只是标签的样式,和 api 略有区别而已。目前我们主要讲解小程序中的canvas。
万少
2025/02/11
1810
小程序 canvas 生成海报 一次搞掂
【愚公系列】2022年08月 微信小程序-view生成分享图片
微信小程序并不支持view直接转绘到画布上,想要实现海报功能必须通过以下4个步骤:
愚公搬代码
2022/09/26
1.1K0
7-微信小程序开发-Canvas画图入门与尺寸转换
<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearningMiniProgram/" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
杨奉武
2020/12/16
9770
7-微信小程序开发-Canvas画图入门与尺寸转换
第九十期:一个小程序生成海报的问题
最近还是在做基于ts+taro的小程序开发,有个前端生成海报的需求。本来想着这个需求很简单,因为之前写过这个功能,基本的逻辑就是产品图片地址和小程序码图片地址下载到本地,然后通过createCanvasContext()这个方法拿到canvas的上下文,进行绘制即可。
terrence386
2022/07/15
5330
仿bilibili刷新按钮的实现
简述 最近跟小伙伴一起讨论了一下,决定一起仿一个BiliBili的app(包括android端和iOS端),我们并没有打算把这个项目完全做完,毕竟我们的重点是掌握一些新框架的使用,并在实战过程中发现并弥补自身的不足。 本系列将记录我(android端)在开发过程中的一些我觉得有必要记录的功能实现而已,并不是完整的从0到1的完整教程,若个别看官大爷觉得不好请出门左拐谢谢。 以下是该项目将会完成的功能。 视频播放功能 直播功能 弹幕功能 换肤功能 ... 本系列文章,将会有记录以上功能的实现但不仅仅只有这些,还
我就是马云飞
2018/02/05
1.5K1
仿bilibili刷新按钮的实现
小程序海报,极简的实现方式
需要注意的是,目前的canvas可以简单分为两种。一种是传统网页中的canvas,一种是小程序中的canvas。两者的功能是完全一样的。只是标签的样式,和 api 略有区别而已。目前我们主要讲解小程序中的canvas。
万少
2025/02/11
1530
小程序海报,极简的实现方式
小程序canvas生成海报图片压缩和失真问题解决
我这里绘制二维码使用的 wxapp-qrcode ,也可以使用weapp-qrcode,基本是一样的,今天主要讲解适配不同屏幕尺寸的canvas。
PHP开发工程师
2022/04/14
2.2K0
小程序Canvas实践指南
导语 总结在小程序canvas开发实践中遇到的一些问题和解决方法。 1. 什么是 Canvas? 在 MDN 是这样定义 canvas 的: canvas 是 HTML5 新增的元素,可用于通过使用 JavaScript 中的脚本来绘制图形。例如,它可以用于绘制图形、制作照片、创建动画,甚至可以进行实时视频处理或渲染。 Canvas 是由 HTML 代码配合高度和宽度属性而定义出的可绘制区域。JavaScript 代码可以访问该区域,类似于其他通用的二维 API,通过一套完整的绘图函数来动态生成图形。
腾讯VTeam技术团队
2020/10/14
3.8K0
微信小程序之生成图片分享
通过社交软件分享的方式来进行营销小程序,是一个常用的运营途径。小程序本身支持直接将一个小程序的链接卡片分享至微信好友或微信群,然后别人就可以通过点击该卡片进入该小程序页面。但是小程序目前不支持直接分享到微信朋友圈,而对我们来说,微信朋友圈又是一个很重要的吸引别人关注的入口,所以,得想办法把这个资源利用起来。
一斤代码
2018/08/21
4.8K0
微信小程序之生成图片分享
推荐阅读
相关推荐
轻松生成小程序分享海报的神器来了
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验