一 . 效果

 这是借用女神照生成的分享的海报,图片来自网络。

新增了poster组件和更新图片自适应

二 . 准备

 准备两张图片连接,最好是自己开发账号验证的https图片链接。

三 . 实现思路

其实就是canvas实现方式,首先要就是定义一个canvas容器,把容器放在中间,图片也要动态计算大小居中,显示下面的文字和二维码也是要根据容器动态去改变,这就是大概的实现思路。

四 . 实现代码

利用微信小程序canvas生成海报分享图片,这个生成图片排版和适配不同尺寸的手机是一个难点,特别是图片适应问题,我处理的方法是动态获取容器的宽度进行适应就是利用微信API wx.createSelectorQuery(),不知道还有没有更好的办法可以请教。

1.下载头像
为了确保图片下载完成之后,再回调其它方法执行下一步。

getAvaterInfo: function (cardInfo) {//cardInfo是传入的信息参数,按实际需要。
wx.showLoading({ title: '生成中...',mask: true,});
var that = this;
if (cardInfo.CardInfo.Avater) {
wx.downloadFile({
url: '图片路径',
success: function (res) {
wx.hideLoading();
if (res.statusCode === 200) {
var avaterSrc = res.tempFilePath;
that.getQrCode(avaterSrc, cardInfo);
}else{
wx.showToast({
title: '头像下载失败!',
icon:'none',
duration: 2000,
success:function(){
that.getQrCode(avaterSrc = "", cardInfo);//回调另一个图片下载
}
})
}
}
})
} else {
wx.hideLoading();
that.getQrCode(avaterSrc = "", cardInfo);//回调另一个图片下载
}
},

  2.下载二维码
二维码下载一样的道理,就是先下载完成,再进行绘图。

 getQrCode: function (avaterSrc, cardInfo) {
wx.showLoading({ title: '生成中...', mask: true, });
var that = this;
if (cardInfo.CardInfo.QrCode) {
wx.downloadFile({
url: cardInfo.CardInfo.QrCode,
success: function (res) {
wx.hideLoading();
if (res.statusCode === 200) {
var codeSrc = res.tempFilePath;
that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的绘图方法
} else {
wx.showToast({
title: '二维码下载失败!',
icon: 'none',
duration: 2000,
success: function () {
var codeSrc = "";
that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的绘图方法
}
})
}
}
})
} else {
wx.hideLoading();
var codeSrc = "";
that.sharePosteCanvas(cardInfo, avaterSrc, codeSrc);//真正的绘图方法
}
},

  3.绘制分享海报
这里才是canvas实现绘制的过程

sharePosteCanvas: function (cardInfo, avaterSrc, codeSrc) {
wx.showLoading({
title: '生成中...',
mask: true,
})
var that = this;
const ctx = wx.createCanvasContext('myCanvas');
var width = "";
wx.createSelectorQuery().select('#canvas-container').boundingClientRect(function (rect) {
var height = rect.height;
var right = rect.right;
width = rect.width * 0.8;
var left = rect.left + 5;
ctx.setFillStyle('#fff');
ctx.fillRect(0, 0, rect.width, height); //头像
if (avaterSrc) {
ctx.drawImage(avaterSrc, left, 20, width, width);
ctx.setFontSize(14);
ctx.setFillStyle('#fff');
ctx.setTextAlign('left');
} if (cardInfo.TagList.length > 0) {
ctx.fillText(cardInfo.TagList[0].TagName, left + 20, width - 4); //标签
const metrics = ctx.measureText(cardInfo.TagList[0].TagName); //测量文本信息
ctx.stroke();
ctx.rect(left + 10, width - 20, metrics.width + 40, 25);
ctx.setFillStyle('rgba(255,255,255,0.4)');
ctx.fill();
} if (cardInfo.CardInfo.Name) {
ctx.setFontSize(14);
ctx.setFillStyle('#000');
ctx.setTextAlign('left');
ctx.fillText(cardInfo.CardInfo.Name, left, width + 60); //姓名
} if (cardInfo.CardInfo.Position) {
ctx.setFontSize(12);
ctx.setFillStyle('#666');
ctx.setTextAlign('left');
ctx.fillText(cardInfo.CardInfo.Position, left, width + 85); //职位
} if (cardInfo.CardInfo.Mobile) {
ctx.setFontSize(12);
ctx.setFillStyle('#666');
ctx.setTextAlign('left');
ctx.fillText(cardInfo.CardInfo.Mobile, left, width + 105); //电话
} if (cardInfo.CardInfo.Company) {
// 公司名称
const CONTENT_ROW_LENGTH = 24; // 正文 单行显示字符长度
let [contentLeng, contentArray, contentRows] = that.textByteLength(cardInfo.CardInfo.Company, CONTENT_ROW_LENGTH);
ctx.setTextAlign('left');
ctx.setFillStyle('#000');
ctx.setFontSize(10);
let contentHh = 22 * 1;
for (let m = 0; m < contentArray.length; m++) {
ctx.fillText(contentArray[m], left, width + 150 + contentHh * m);
}
} // 绘制二维码cardInfo.CardInfo.QrCode
if (codeSrc) {
ctx.drawImage(codeSrc, left + 150, width + 40, width / 3, width / 3)
ctx.setFontSize(10);
ctx.setFillStyle('#000');
ctx.setTextAlign('right');
ctx.fillText("微信扫码或长按识别", left + 235, width + 150);
} }).exec() setTimeout(function () {
ctx.draw(); 这里有个需要注意就是,这个方法是在绘制完成之后在调用,不然容易其它被覆盖。
wx.hideLoading();
}, 1000) },

  4.多行显示文字
这个函数就是需要多行显示文字的时候进行折行,就是切分为数组。

textByteLength(text, num) { // text为传入的文本  num为单行显示的字节长度
let strLength = 0; // text byte length
let rows = 1;
let str = 0;
let arr = [];
for (let j = 0; j < text.length; j++) {
if (text.charCodeAt(j) > 255) {
strLength += 2;
if (strLength > rows * num) {
strLength++;
arr.push(text.slice(str, j));
str = j;
rows++;
}
} else {
strLength++;
if (strLength > rows * num) {
arr.push(text.slice(str, j));
str = j;
rows++;
}
}
}
arr.push(text.slice(str, text.length));
return [strLength, arr, rows] // [处理文字的总字节长度,每行显示内容的数组,行数]
},

  5.保存绘制生成图片
这一步就是最后把canvas生成图片了,大功告成。

 //点击保存到相册
saveShareImg: function () {
var that = this;
wx.showLoading({
title: '正在保存',
mask: true,
})
setTimeout(function () {
wx.canvasToTempFilePath({
canvasId: 'myCanvas',
success: function (res) {
wx.hideLoading();
var tempFilePath = res.tempFilePath;
wx.saveImageToPhotosAlbum({
filePath: tempFilePath,
success(res) {
wx.showModal({
content: '图片已保存到相册,赶紧晒一下吧~',
showCancel: false,
confirmText: '好的',
confirmColor: '#333',
success: function (res) {
if (res.confirm) { }
},
fail: function (res) { }
})
},
fail: function (res) {
wx.showToast({
title: res.errMsg,
icon: 'none',
duration: 2000
})
}
})
}
});
}, 1000);
},

  

五 . 填坑

1.图片要提前下载
这里面还有一个问题就是,图片要提前下载完之后再绘图,不然图片显示不出来,可以把下载图片的方法单独拎出来,然后下载图片后回调绘图方法。

  1. ctx.draw()
    这个方法是在绘制完成之后在调用,不然容易其它被覆盖。

这样就大功告成了,有问题可以和联系作者,一起进步。
喜欢就点点喜欢鼓励
DEMO路径:https://github.com/kingbuwu/poster
demo上封装了poster组件和显示头图图片自适应

												

微信小程序利用canvas生成海报分享图片的更多相关文章

  1. 微信小程序之canvas绘制海报分享到朋友圈

    绘制canvas内容 首先,需要写一个canvas标签,给canvas-id命名为shareBox <canvas canvas-id="shareBox"></ ...

  2. 关于微信小程序使用canvas生成图片,内容图片跨域的问题

    最近有个项目是保存为名片(图片),让用户发送给朋友或朋友圈,找了很多方案都不适用,绞尽脑汁之后还是选了使用canvas,但是用这玩意儿生成图片最大的缺点就是,如果你的内容中有图片,并且这个图片是通过外 ...

  3. 小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像)

    小程序利用canvas 绘制图案 (生成海报, 生成有特色的头像) 微信小程序生成特色头像,海报等是比较常见的.下面我来介绍下实现该类小程序的过程. 首先选择前端来通过 canvas 绘制.这样比较节 ...

  4. 微信小程序-基于canvas画画涂鸦

    代码地址如下:http://www.demodashi.com/demo/14461.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  5. 关于微信小程序前端Canvas组件教程

    关于微信小程序前端Canvas组件教程 微信小程序Canvas接口函数 ​ 上述为微信小程序Canvas的内部接口,通过熟练使用Canvas,即可画出较为美观的前端页面.下面是使用微信小程序画图的一些 ...

  6. 微信小程序 在canvas画布上划动,页面禁止滑动

    要实现微信小程序 在canvas画布上划动,页面禁止滑动,不仅要设置disable-scroll="true",还要要给canvas绑定一个触摸事件才能生效. <canvas ...

  7. 解决微信小程序安卓手机访问不到图片,无法显示图片

    关于微信小程序不显示图片 通病可能有以下几个可能性: 非本地图片:确定图片资源存在,copy 图片url再浏览器打开,确定图片资源存在且能正常访问 本地图片:确定相对路径或者绝对路径正确 微信小程序图 ...

  8. 微信小程序初探--写个扫雷分享给你玩

    闲暇里,想学一下微信小程序, 于是,用微信小程序原生做了个扫雷玩. 以下略作总结,分享给大家. 微信里下拉,输入[mini计算器], 看到这个图标的就是了: 说好的扫雷,怎么变成计算器了?原因后面解释 ...

  9. 微信小程序初体验与DEMO分享

    前言 前一段时间微信公布小程序,瞬间引来了大量的关注.博主的公司也将其定为目标之一,遂派本菜为先头兵(踩坑侠). 这次开发了一个比较完整的DEMO,模仿自某个APP首页,由于保护隐私的目的我把数据拷贝 ...

随机推荐

  1. 【数据库】一篇文章搞掂:SQL Server数据库

    问题: 1.同一段代码,在存储过程中运行比普通SQL执行速度慢几十倍 原理: 在SQL Server中有一个叫做 “Parameter sniffing”参数嗅探的特性.SQL Server在存储过程 ...

  2. django更换默认数据库sqlite3为pymsql后出现Keyerror:255的解决办法----升级PyMySQL

    一.更换数据库的办法: 1.安装PyMySQL 2.修改project目录同名文件下的settings.py:DATABASES = { 'default': { # 'ENGINE': 'djang ...

  3. 软件-平面设计-CorelDRAW:CorelDRAW

    ylbtech-软件-平面设计-CorelDRAW:CorelDRAW CorelDRAW Graphics Suite是加拿大Corel公司的平面设计软件:该软件是Corel公司出品的矢量图形制作工 ...

  4. Struts1.3——登录案例的改进

    在上篇写的用户登录验证案例的基础上进一步改进. 1.在登录成功后的welcome.jsp页面显示登录成功的用户名 思路1:在LoginAction中,将username放入request的域对象中 因 ...

  5. 设置 Quartus II 的仿真时间大于 1us

    Quartus II 仿真的默认时长是 1us. 设置时钟时看到 End time 想修改时长,把默认的 1us 改成 10us. 然后提示 End time 不合法.(只能设置为 0 到 1us) ...

  6. flex属性flex-grow、flex-shrink、flex-basis

    tip: 1)这些属性写在子元素中,作用于子元素(父元素中应设置display:flex) 2)作用是子元素如何分配父元素的空间 3) flex-grow 是扩展比率,当子元素宽度总和小于父元素宽度时 ...

  7. Dubbo 系列(07-1)集群容错 - 服务字典

    Dubbo 系列(07-1)集群容错 - 服务字典 [toc] Spring Cloud Alibaba 系列目录 - Dubbo 篇 1. 背景介绍 本篇文章,将开始分析 Dubbo 集群容错方面的 ...

  8. webpack3.X的学习

    文章说明,这篇主要是记录一下我学习的过程.以代码为主.一些概念啊,插件的用途说明啊不做任何说明.有任何不明白的请参照webpack中文官网https://doc.webpack-china.org/. ...

  9. linux/unix下setuid/seteuid/setreuid/setresuid

    其中setresuid()具有最清晰的语法: setresuid()被执行的条件有: ①当前进程的euid是root ②三个参数,每一个等于原来某个id中的一个 如果满足以上条件的任意一个,setre ...

  10. enovia plm export to sap

    UPC creation UPC 结构 PLM 使用的UPC 是 14个数字组成的,兼容. 前两位为 0,后12位为有效数字,在SAP中0会被忽略,符合国际UPC通用 规则, 前一位为0,后13 位为 ...