openStatus = false

console.log(‘请设置允许访问相册’)

wx.showToast({

title: ‘请设置允许访问相册’,

icon: ‘none’

})

}

})

} else {

// 有则直接保存

openStatus = true

wx.saveImageToPhotosAlbum({

filePath: canvasToTempFilePath,

success() {

that.setData({

showShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

})

},

fail() {

wx.showToast({

title: ‘保存失败’,

icon: ‘none’

})

}

})

}

},

fail(err) {

console.log(err)

}

})

}

总结

至此所有的步骤都已实现,在绘制的时候会遇到一些异步请求后台返回的数据,所以我用promise和async和await进行了封装,确保导出的图片信息是完整的。在绘制的过程确实遇到一些坑的地方。比如初开始导出的图片比例大小不对,还有用measureText测量文字宽度不对,多次绘制(可能受网络原因)有时导出的图片上的文字颜色会有误差等。如果你也遇到一些比较坑的地方可以一起探讨下做个记录,下面附下完整的代码

import regeneratorRuntime from ‘…/…/utils/runtime.js’ // 引入模块

const app = getApp(),

api = require(’…/…/service/http.js’);

var ctx = null, // 创建canvas对象

canvasToTempFilePath = null, // 保存最终生成的导出的图片地址

openStatus = true; // 声明一个全局变量判断是否授权保存到相册

// 获取微信公众号二维码

getCode: function () {

return new Promise(function (resolve, reject) {

api.fetch(’/wechat/open/getQRCodeNormal’, ‘GET’).then(res => {

console.log(res, ‘获取微信公众号二维码’)

if (res.code == 200) {

console.log(res.content, ‘codeUrl’)

resolve(res.content)

}

}).catch(err => {

console.log(err)

})

})

},

// 生成海报

async createCanvasImage() {

let that = this;

// 点击生成海报数据埋点

that.setData({

generateId: ‘点击生成海报’

})

if (!ctx) {

let codeUrl = await that.getCode()

wx.showLoading({

title: ‘绘制中…’

})

let code = new Promise(function (resolve) {

wx.getImageInfo({

src: codeUrl,

success: function (res) {

resolve(res.path)

},

fail: function (err) {

console.log(err)

wx.showToast({

title: ‘网络错误请重试’,

icon: ‘loading’

})

}

})

})

let headImg = new Promise(function (resolve) {

wx.getImageInfo({

src: ${app.globalData.baseUrl2}${that.data.currentChildren.headImg},

success: function (res) {

resolve(res.path)

},

fail: function (err) {

console.log(err)

wx.showToast({

title: ‘网络错误请重试’,

icon: ‘loading’

})

}

})

})

Promise.all([headImg, code]).then(function (result) {

const ctx =
wx.createCanvasContext(‘myCanvas’)

console.log(ctx, app.globalData.ratio, ‘ctx’)

let canvasWidthPx = 690 * app.globalData.ratio,

canvasHeightPx = 1085 * app.globalData.ratio,

avatarurl_width = 60, //绘制的头像宽度

avatarurl_heigth = 60, //绘制的头像高度

avatarurl_x = 28, //绘制的头像在画布上的位置

avatarurl_y = 36, //绘制的头像在画布上的位置

codeurl_width = 80, //绘制的二维码宽度

codeurl_heigth = 80, //绘制的二维码高度

codeurl_x = 588, //绘制的二维码在画布上的位置

codeurl_y = 984, //绘制的二维码在画布上的位置

wordNumber = that.data.wordNumber, // 获取总阅读字数

// nameWidth = ctx.measureText(that.data.wordNumber).width, // 获取总阅读字数的宽度

// allReading = ((nameWidth + 375) - 325) * 2 + 380;

// allReading = nameWidth / app.globalData.ratio + 325;

allReading = 97 / 6 / app.globalData.ratio * wordNumber.toString().length + 325;

console.log(wordNumber, wordNumber.toString().length, allReading, ‘获取总阅读字数的宽度’)

ctx.drawImage(’/img/study/shareimg.png’, 0, 0, 690, 1085)

ctx.save(); // 先保存状态 已便于画完圆再用

ctx.beginPath(); //开始绘制

//先画个圆 前两个参数确定了圆心 (x,y) 坐标 第三个参数是圆的半径 四参数是绘图方向 默认是false,即顺时针

ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);

ctx.clip(); //画了圆 再剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内

ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片

ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.setFontSize(28); // 文字字号

ctx.fillText(that.data.currentChildren.name, 103, 78); // 绘制文字

ctx.font = ‘normal bold 44px sans-serif’;

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.fillText(wordNumber, 325, 153); // 绘制文字

ctx.font = ‘normal normal 30px sans-serif’;

ctx.setFillStyle(’#ffffff’)

ctx.fillText(‘字’, allReading, 150);

ctx.font = ‘normal normal 24px sans-serif’;

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.fillText(‘打败了全国’, 26, 190); // 绘制文字

ctx.font = ‘normal normal 24px sans-serif’;

ctx.setFillStyle(’#faed15’); // 文字颜色

ctx.fillText(that.data.percent, 154, 190); // 绘制孩子百分比

ctx.font = ‘normal normal 24px sans-serif’;

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.fillText(‘的小朋友’, 205, 190); // 绘制孩子百分比

ctx.font = ‘normal bold 32px sans-serif’;

ctx.setFillStyle(’#333333’); // 文字颜色

ctx.fillText(that.data.singIn, 50, 290); // 签到天数

ctx.fillText(that.data.reading, 280, 290); // 阅读时长

ctx.fillText(that.data.reading, 508, 290); // 听书时长

// 书籍阅读结构

ctx.font = ‘normal normal 28px sans-serif’;

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.fillText(that.data.bookInfo[0].count, 260, 510);

ctx.fillText(that.data.bookInfo[1].count, 420, 532);

ctx.fillText(that.data.bookInfo[2].count, 520, 594);

ctx.fillText(that.data.bookInfo[3].count, 515, 710);

ctx.fillText(that.data.bookInfo[4].count, 492, 828);

ctx.fillText(that.data.bookInfo[5].count, 348, 858);

ctx.fillText(that.data.bookInfo[6].count, 212, 828);

ctx.fillText(that.data.bookInfo[7].count, 148, 726);

ctx.fillText(that.data.bookInfo[8].count, 158, 600);

ctx.font = ‘normal normal 18px sans-serif’;

ctx.setFillStyle(’#ffffff’); // 文字颜色

ctx.fillText(that.data.bookInfo[0].name, 232, 530);

ctx.fillText(that.data.bookInfo[1].name, 394, 552);

ctx.fillText(that.data.bookInfo[2].name, 496, 614);

ctx.fillText(that.data.bookInfo[3].name, 490, 730);

ctx.fillText(that.data.bookInfo[4].name, 466, 850);

ctx.fillText(that.data.bookInfo[5].name, 323, 878);

ctx.fillText(that.data.bookInfo[6].name, 184, 850);

ctx.fillText(that.data.bookInfo[7].name, 117, 746);

ctx.fillText(that.data.bookInfo[8].name, 130, 621);

ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth); // 绘制头像

ctx.draw(false, function () {

// canvas画布转成图片并返回图片地址

wx.canvasToTempFilePath({

canvasId: ‘myCanvas’,

success: function (res) {

canvasToTempFilePath = res.tempFilePath

that.setData({

showShareImg: true

})

console.log(res.tempFilePath, ‘canvasToTempFilePath’)

wx.showToast({

title: ‘绘制成功’,

})

},

fail: function () {

wx.showToast({

title: ‘绘制失败’,

})

},

complete: function () {

wx.hideLoading()

wx.hideToast()

}

})

})

})

}

},

// 保存到系统相册

saveShareImg: function () {

let that = this;

// 数据埋点点击保存学情海报

that.setData({

saveId: ‘保存学情海报’

})

// 获取用户是否开启用户授权相册

if (!openStatus) {

wx.openSetting({

success: (result) => {

if (result) {

if (result.authSetting[“scope.writePhotosAlbum”] === true) {

openStatus = true;

wx.saveImageToPhotosAlbum({

filePath: canvasToTempFilePath,

success() {

that.setData({

showShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

})

},

fail() {

wx.showToast({

title: ‘保存失败’,

icon: ‘none’

})

}

})

}

}

},

fail: () => { },

complete: () => { }

});

} else {

wx.getSetting({

success(res) {

// 如果没有则获取授权

if (!res.authSetting[‘scope.writePhotosAlbum’]) {

wx.authorize({

scope: ‘scope.writePhotosAlbum’,

success() {

openStatus = true

wx.saveImageToPhotosAlbum({

filePath: canvasToTempFilePath,

success() {

that.setData({

showShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

})

},

fail() {

wx.showToast({

title: ‘保存失败’,

icon: ‘none’

})

}

})

},

fail() {

// 如果用户拒绝过或没有授权,则再次打开授权窗口

openStatus = false

console.log(‘请设置允许访问相册’)

wx.showToast({

title: ‘请设置允许访问相册’,

icon: ‘none’

})

}

})

} else {

// 有则直接保存

openStatus = true

wx.saveImageToPhotosAlbum({

filePath: canvasToTempFilePath,

success() {

that.setData({

showShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

owShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

})

},

fail() {

wx.showToast({

title: ‘保存失败’,

icon: ‘none’

})

}

})

},

fail() {

// 如果用户拒绝过或没有授权,则再次打开授权窗口

openStatus = false

console.log(‘请设置允许访问相册’)

wx.showToast({

title: ‘请设置允许访问相册’,

icon: ‘none’

})

}

})

} else {

// 有则直接保存

openStatus = true

wx.saveImageToPhotosAlbum({

filePath: canvasToTempFilePath,

success() {

that.setData({

showShareImg: false

})

wx.showToast({

title: ‘图片保存成功,快去分享到朋友圈吧~’,

icon: ‘none’,

duration: 2000

小程序如何生成海报分享朋友圈,android移动开发技术与应用相关推荐

  1. 【小程序】728- 小程序如何生成海报分享朋友圈

    作者:小白 https://segmentfault.com/a/1190000019083548 项目需求写完有一段时间了,但是还是想回过来总结一下,一是对项目的回顾优化等,二是对坑的地方做个记录, ...

  2. 微信小程序转发好友和分享朋友圈

    onLoad: function (options) {//修改当前页面标题wx.setNavigationBarTitle({title: "会员中心"}); //用户点击右上角 ...

  3. uniapp(HBuilder X)实现微信小程序转发好友和分享朋友圈(携带多个参数)

    1.转发好友 onShareAppMessage() {let that=this;var url="/pages/xxxx/xxxx?id=123&type=goods" ...

  4. 微信小程序-运用painter插件生成海报分享朋友圈--比canvas好用

    微信小程序-运用painter插件生成海报–比canvas好用 先放插件地址:https://github.com/Kujiale-Mobile/Painter 还有个可视化把海报生成代码的地址:ht ...

  5. 【微信小程序】用painter插件生成海报分享朋友圈简单教程

    第一步:去Git下载插件 1.这是核心插件 需要下载全部内容 https://github.com/Kujiale-Mobile/PainterCore 2.官方文档 https://github.c ...

  6. 小程序canvas实现(分享朋友圈生成图片)

    业务场景:生成一个浮层图片 实现思路: 设置一个盒子,将canvas生成的图片和保存图片的按钮放里边,当有canvas生成图片的时候这个盒子显示,否则隐藏. 这里需要注意的是,canvas画图片的时候 ...

  7. 小程序的页面生成图片分享朋友圈

    网上的经验其实挺多.我是按照这个 https://www.jianshu.com/p/01f526a4f948 https://github.com/JaimeCheng/canvasShareImg ...

  8. 小程序生成二维码分享朋友圈的功能

    一.如何生成小程序分享页面的二维码? 通过后台接口可以获取小程序任意页面的二维码,具体可以参考https://developers.weixin.qq.com/miniprogram/dev/api/ ...

  9. mpvue 微信小程序canvas生成海报

    mpvue 微信小程序canvas生成海报 效果 贴代码 html <template><!--index.wxml--><view class="poster ...

最新文章

  1. Java8的集合:LinkedList的实现原理
  2. MDaemon使用技巧大全--新建账户欢迎文件的设置
  3. 新手理解之NHibernate是什么?
  4. tar压缩解压命令详解
  5. AC解 - Phone List(HDOJ#1671) 前缀树的一个应用
  6. MySQL数据库从入门到实战(四)
  7. 小学二年几手工计算机的制作,小学二年级创意手工制作方法
  8. 后端技术:ELK不香了?企业级日志平台新框架 Graylog介绍
  9. 为什么说「中台」程序员将来会最值钱?
  10. ArrayList的底层实现原理
  11. 视觉SLAM笔记(54) Ceres 操作后端优化
  12. php oracle 删除 数据,oracle怎么清空表数据
  13. Docker学习总结(9)——Docker常用命令
  14. python自动化开发-[第二十四天]-高性能相关与初识scrapy
  15. mongodb慢查询记录
  16. C#/.net 中的事件与代理
  17. 趋势程序大赛第 六七 天
  18. 圆环和环形是一样的吗_饼图太丑?只需3步,立马变身成好看的环形图!
  19. 扫描工具——Nmap用法详解
  20. 内网穿透的一种方式——基于ngrok的小米球

热门文章

  1. 幼儿抽象逻辑思维举例_2岁多的孩子,需要锻炼逻辑思维吗?
  2. 用JAVA编写50以内的素数_java求50以内的素数
  3. 相同内容多个html如何合并单元格,合并具有相同内容HTML的单元格
  4. _bss_start _armboot_start
  5. 服务器文件传输过大提示错误,严重文件传输错误
  6. Fabric 1.0源代码分析(12)cryptogen(生成组织关系和身份证书)
  7. vs2010 静态库以及动态库编译实例
  8. iptables实现网络限制下ntp自定义端口同步时间
  9. 【MATLAB数学建模算法代码(六)之遗传算法】
  10. STM32正交编码器测速