- 小程序中实现页面截图
最近接到一个需求,需要在小程序中实现页面截图,我一开始的考虑是使用官方提供的扩展组件wxml-to-canvas,但是实际体验下来效果很糟糕,首先它并不能截取实际的页面,而是必须传入[代码]wxml[代码]和[代码]wxss[代码];然后他能支持的效果也很少,并不能满足需求中稍微复杂的效果。最终我决定用web-view加载的网页中使用html2canvas来实现功能。 实际代码 网页部分我用了[代码]vue[代码],首先需要安装[代码]html2canvas[代码] [代码]npm install html2canvas [代码] 页面中引入 [代码]import html2canvas from 'html2canvas'; [代码] 需要截图的dom节点上添加ref属性 [代码]<div ref="page"> [代码] 截图代码 [代码]... document.body.scrollTop = 0; // 将页面滚动至顶部后再开始截图,才能保证截图的完整 html2canvas(this.$refs.page, { allowTaint: false, useCORS: true, width: document.body.scrollWidth, height: document.body.scrollHeight // 实际体验中发现最好设置宽高为页面的宽高才能获得完整的截图 }).then(canvas => { this.savedPic = canvas.toDataURL('images/png') // 用于在页面中展示的截图完成的网址 ... // 以下代码为模拟a标签的点击直接下载截图 // 但是这部分代码在移动端网页和小程序中并不会生效 let a = document.createElement('a'), blob = this.dataURLToBlob(canvas.toDataURL('images/png')); a.setAttribute('href', URL.createObjectURL(blob)); a.setAttribute('download', 'pic.png'); document.body.appendChild(a); a.click(); URL.revokeObjectURL(blob); document.body.removeChild(a); }); ... [代码] 兼容性 网页毕竟不是原生小程序,还是会存在一些兼容性问题,比如网页中不能使用小程序的wx.saveImageToPhotosAlbum直接保存生成好的截图。移动端和微信中也不支持模拟a标签的点击来下载图片,最终只能通过展示生成的截图并提示用户长按图片来实现保存图片的功能,用户体验会差点,但是考虑到截图效果比[代码]wxml-to-canvas[代码]好太多了,还是可以接受的。 最后说一下[代码]html2canvas[代码]的支持度,目前实际用下来发现不支持的样式为阴影和伪元素,其他基本上都支持。网页中的图片必须为本地图片或者支持跨域的网络图片。用到图片的地方建议直接使用[代码]img[代码]标签,而不是背景图片,[代码]img[代码]标签展示的图片清晰度远远高于背景图片。
2021-07-13 - 登录接口又双叕变了,三行代码挑战全网最少修改工作量
小程序登录、用户信息样关接口又双叕变了。 https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801 几家悲伤几家愁。。。 微信的一小步,人猿的一大步。。。 没办法,改吧。。。 翻出以前小程序这部分的代码,惊喜地发现,只需要三行代码,就能平滑过渡; 感谢我以前看似丑陋却很省事的登录代码逻辑!!! 登录逻辑如下: 1、判断库里有用户的信息没有,没有,则wx.navigateTo一个专门的授权页面:auth 2、授权成功后获得userInfo,保存到库里; auth页代码修改如下: auth.wxml: 修改一行代码 <button style='margin:15px;font-size:16px' type='primary' size="mini" bindtap='getUserProfile'>授权微信头像和昵称</button> auth.js: 修改两行代码 //原wx.getUserInfo接口 getUserInfo: function (e) { let userInfo = e.detail.userInfo if (userInfo) this.onSaveUserInfo(userInfo) }, //新增wx.getUserProfile接口 getUserProfile: function (e) { wx.getUserProfile({ desc: '业务需要', success: res => this.onSaveUserInfo(res.userInfo) }) }, //保存userInfo到DB onSaveUserInfo:function(userInfo){ console.log(app.globalData.userInfo = userInfo) db.collection('user') .where({ _id: this.openid }) .count() .then(res => { if (res.total > 0) { //doc.update db.collection('user').doc(this.openid).update({ data: userInfo }).then(res => console.log(res)) } else { //doc.add db.collection('user').doc(this.openid).add({ data: userInfo }).then(res => console.log(res)) } }) wx.navigateBack() }, 以下是判断用户信息是否存在的代码: xxxx.js: onSubmit:async function () { if (await app.hasUserInfo()) { } else return //其他代码 }, app.js: hasUserInfo: async function () { if (this.globalData.userInfo && this.globalData.userInfo.nickName && this.globalData.userInfo.avatarUrl) return true let res = await wx.cloud.database().collection('user').doc(this.openid).get().catch(err => console.log(err)) if (res && res.data && res.data.nickName && res.data.avatarUrl) { this.globalData.userInfo = res.data return true } else { wx.navigateTo({ url: '/base/auth/auth' }) return false } }, 关于用户信息自动更新: 我们一直以来的方法如下: 1、留给用户手动授权的入口,用户更换头像后,发现自己的头像不显示,则需要手动授权刷新userInfo; 2、一般会在这个页面:我的--个人信息--授权微信头像和昵称,用户点击后,wx.navigateTo到授权页。 笔者团队认为:用户信息自动更新其实是个伪需求。理由如下: 假设某用户修改了头像: 1、用户自己打开小程序,发现头像和昵称怎么没有改过来,那么手动更新一下。用户体验没毛病,没必要非要自动更新; 2、用户如果后来不再进入小程序,别人看到的都是一张碎的头像,那么此时,自动更新也毫无作用,因为该用户都不打开小程序。 3、微信团队肯定考虑过自动更新这种要求,但他们宁愿千夫所指,也依然坚持推出新的登录接口,那就肯定是已经经过了中国最牛逼团队的全面考衡了。 补充: 登录和授权其实是两码事,可以毫无关系这么说,以上的内容主要都是关于授权微信用户信息的,下面补充一下登录的内容: 登录其实就是获取用户的openid,我们一直采用云函数来获取openid。方案如下: 在每个页面:page.js: onLoad: async function (options) { this.openid = await app.getOpenid() }, 在app.js: getOpenid: async function () { if (this.openid) return this.openid let res = await this.globalData.cloud.callFunction({ name: 'login' }) console.log(res) return this.openid = res.result.FROM_OPENID||res.result.OPENID },
2021-04-07 - 小程序登录、用户信息相关接口调整说明
公告更新时间:2021年04月15日考虑到近期开发者对小程序登录、用户信息相关接口调整的相关反馈,为优化开发者调整接口的体验,回收wx.getUserInfo接口可获取用户授权的个人信息能力的截止时间由2021年4月13日调整至2021年4月28日24时。为优化用户的使用体验,平台将进行以下调整: 2021年2月23日起,若小程序已在微信开放平台进行绑定,则通过wx.login接口获取的登录凭证可直接换取unionID2021年4月28日24时后发布的小程序新版本,无法通过wx.getUserInfo与<button open-type="getUserInfo"/>获取用户个人信息(头像、昵称、性别与地区),将直接获取匿名数据(包括userInfo与encryptedData中的用户个人信息),获取加密后的openID与unionID数据的能力不做调整。此前发布的小程序版本不受影响,但如果要进行版本更新则需要进行适配。新增getUserProfile接口(基础库2.10.4版本开始支持),可获取用户头像、昵称、性别及地区信息,开发者每次通过该接口获取用户个人信息均需用户确认。具体接口文档:《getUserProfile接口文档》由于getUserProfile接口从2.10.4版本基础库开始支持(覆盖微信7.0.9以上版本),考虑到开发者在低版本中有获取用户头像昵称的诉求,对于未支持getUserProfile的情况下,开发者可继续使用getUserInfo能力。开发者可参考getUserProfile接口文档中的示例代码进行适配。请使用了wx.getUserInfo接口或<button open-type="getUserInfo"/>的开发者尽快适配。开发者工具1.05.2103022版本开始支持getUserProfile接口调试,开发者可下载该版本进行改造。 小游戏不受本次调整影响。 一、调整背景很多开发者在打开小程序时就通过组件方式唤起getUserInfo弹窗,如果用户点击拒绝,无法使用小程序,这种做法打断了用户正常使用小程序的流程,同时也不利于小程序获取新用户。 二、调整说明通过wx.login接口获取的登录凭证可直接换取unionID 若小程序已在微信开放平台进行绑定,原wx.login接口获取的登录凭证若需换取unionID需满足以下条件: 如果开发者帐号下存在同主体的公众号,并且该用户已经关注了该公众号如果开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用2月23日后,开发者调用wx.login获取的登录凭证可以直接换取unionID,无需满足以上条件。 回收wx.getUserInfo接口可获取用户个人信息能力 4月28日24时后发布的新版本小程序,开发者调用wx.getUserInfo或<button open-type="getUserInfo"/>将不再弹出弹窗,直接返回匿名的用户个人信息,获取加密后的openID、unionID数据的能力不做调整。 具体变化如下表: [图片] 即wx.getUserInfo接口的返回参数不变,但开发者获取的userInfo为匿名信息。 [图片] 此外,针对scope.userInfo将做如下调整: 若开发者调用wx.authorize接口请求scope.userInfo授权,用户侧不会触发授权弹框,直接返回授权成功若开发者调用wx.getSetting接口请求用户的授权状态,会直接读取到scope.userInfo为true新增getUserProfile接口 若开发者需要获取用户的个人信息(头像、昵称、性别与地区),可以通过wx.getUserProfile接口进行获取,该接口从基础库2.10.4版本开始支持,该接口只返回用户个人信息,不包含用户身份标识符。该接口中desc属性(声明获取用户个人信息后的用途)后续会展示在弹窗中,请开发者谨慎填写。开发者每次通过该接口获取用户个人信息均需用户确认,请开发者妥善保管用户快速填写的头像昵称,避免重复弹窗。 插件用户信息功能页 插件申请获取用户头像昵称与用户身份标识符仍保留功能页的形式,不作调整。用户在用户信息功能页中授权之后,插件就可以直接调用 wx.login 和 wx.getUserInfo 。 三、最佳实践调整后,开发者如需获取用户身份标识符只需要调用wx.login接口即可。 开发者若需要在界面中展示用户的头像昵称信息,可以通过<open-data>组件进行渲染,该组件无需用户确认,可以在界面中直接展示。 在部分场景(如社交类小程序)中,开发者需要在获取用户的头像昵称信息,可调用wx.getUserProfile接口,开发者每次通过该接口均需用户确认,请开发者妥善处理调用接口的时机,避免过度弹出弹窗骚扰用户。 微信团队 2021年4月15日
2021-04-15 - 05.适配 wx.getUserProfile 的一点简单想法
先看官方的最新通知 周知:getUserInfo 开发版和体验版 已对齐 getUserInfo 匿名表现,正式版将于 4月13日 正式对齐 getUserInfo 匿名表现。 请开发者使用 getUserProfile 获取用户信息。 小程序登录、用户信息相关接口调整说明:https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801 原先的getUserInfo能力 原先的 getUserInfo 的能力,具体看这里:https://developers.weixin.qq.com/community/develop/doc/000c2424654c40bd9c960e71e5b009?highline=getUserInfo [图片] [图片] 我对 getUserInfo 的理解 我们一般开发者,会用 wx.getUserInfo 来实现 openId 和 用户信息的获取,是非常的便捷的。 并且还能通过 wx.getSetting 获取 "scope.userInfo" 判断用户用户是否已经授权。 wx.getSetting + wx.getUserInfo 能近似完美解决用户登陆授权场景 华丽的分割线 2021-02-04 官方要对小程序登录、用户信息相关接口调整说,具体链接:https://developers.weixin.qq.com/community/develop/doc/000cacfa20ce88df04cb468bc52801?blockType=1 这样我们开发者会面临的用户登陆授权的调整,会比较痛,但也必须要去改,因为没办法。 怎么改呢 先不要着急去适配 getUserProfile,先要弄清楚自己的小程序用 getUserInfo 获取那些能力?实现哪些能力? 我的理解,如果是用 wx.getSetting + wx.getUserInfo 来实现获取用户的openId(unioinId) 和用户头像昵称信息的话,可以这样去调整? wx.login 可以拿到用户的 openId,流程如下: [图片] 如果绑定了开发平台,还可以通过 wx.login 静默获取用户的 uninonId [图片] 这个过程是静默的,不需要用户参与。 然后对于需要用户头像信息的时候,在使用 wx.getUserProfile 能力即可。 小结 1.wx.login + wx.getUserProfile 能实现 wx.getUserInfo 的能力,也能满足我们的业务场景。 2.看到官方的调整,先不要着急去调整,先弄清楚要我们的业务场景使用了那些API获取那些能力 3.关于wx.getSetting 返回 "scope.userInfo" 为 undefined。我记得社区有人提问了,等官方回复就好,其实我们可以不依赖这个,原因留给你 4.用户头像更新不及时的问题,我们看看微信聊天记录,当你好友更新头像,当你不点击时,有时候展示的还是老头像,当你点击时,会显示新头像(我们何不借鉴一下,提供给用户更新的能力即可)
2021-04-09 - weapp-qrcode-canvas-2d在微信小程序中生成二维码,新版canvas-2d接口
weapp-qrcode-canvas-2d weapp-qrcode-canvas-2d 是使用新版canvas-2d接口在微信小程序中生成二维码(外部二维码)的js包。canvas 2d 接口支持同层渲染且性能更佳,建议切换使用,可大幅提升生成图片的速度。 仓库地址 weapp-qrcode-canvas-2d【码云gitee】 weapp-qrcode-canvas-2d【github】 [图片] 测试环境 微信小程序基础库版本:2.10.4 开发者工具版本:Stable 1.03.2101150 Usage 先在 wxml 文件中,创建绘制的 [代码]canvas[代码],并定义好 [代码]width[代码], [代码]height[代码], [代码]id[代码] , [代码]type[代码] ,其中type的值必须为[代码]2d[代码] [代码]<canvas type="2d" style="width: 260px; height: 260px;" id="myQrcode"></canvas> [代码] 安装方法1:直接引入 js 文件 直接引入 js 文件,使用 [代码]drawQrcode()[代码] 绘制二维码 [代码]// 将 dist 目录下,weapp.qrcode.esm.js 复制到项目中。路径根据实际引用的页面路径自行改变 import drawQrcode from '../../utils/weapp.qrcode.esm.js' [代码] 安装方法2:npm安装 [代码]npm install weapp-qrcode-canvas-2d --save [代码] // 然后需要在小程序开发者工具中:构建npm [代码]import drawQrcode from 'weapp-qrcode-canvas-2d' [代码] 安装完成后调用 例子1:没有使用叠加图片 [代码]const query = wx.createSelectorQuery() query.select('#myQrcode') .fields({ node: true, size: true }) .exec((res) => { var canvas = res[0].node // 调用方法drawQrcode生成二维码 drawQrcode({ canvas: canvas, canvasId: 'myQrcode', width: 260, padding: 30, background: '#ffffff', foreground: '#000000', text: 'abc', }) // 获取临时路径(得到之后,想干嘛就干嘛了) wx.canvasToTempFilePath({ canvasId: 'myQrcode', canvas: canvas, x: 0, y: 0, width: 260, height: 260, destWidth: 260, destHeight: 260, success(res) { console.log('二维码临时路径:', res.tempFilePath) }, fail(res) { console.error(res) } }) }) [代码] 例子2:使用叠加图片(在二维码中加logo) [代码]const query = wx.createSelectorQuery() query.select('#myQrcode') .fields({ node: true, size: true }) .exec((res) => { var canvas = res[0].node var img = canvas.createImage(); img.src = "/image/logo.png" img.onload = function () { // img.onload完成后才能调用 drawQrcode方法 var options = { canvas: canvas, canvasId: 'myQrcode', width: 260, padding: 30, paddingColor: '#fff', background: '#fff', foreground: '#000000', text: '123456789', image: { imageResource: img, width: 80, // 建议不要设置过大,以免影响扫码 height: 80, // 建议不要设置过大,以免影响扫码 round: true // Logo图片是否为圆形 } } drawQrcode(options) // 获取临时路径(得到之后,想干嘛就干嘛了) wx.canvasToTempFilePath({ x: 0, y: 0, width: 260, height: 260, destWidth: 600, destHeight: 600, canvasId: 'myQrcode', canvas: canvas, success(res) { console.log('二维码临时路径为:', res.tempFilePath) }, fail(res) { console.error(res) } }) }; }) [代码] API drawQrcode([options]) options Type: Object 参数 必须 说明 示例 canvas 必须 画布标识,传入 canvas 组件实例 canvasId 非 绘制的[代码]canvasId[代码] [代码]'myQrcode'[代码] text 必须 二维码内容 ‘123456789’ width 非 二维码宽度,与[代码]canvas[代码]的[代码]width[代码]保持一致 260 padding 非 空白内边距 20 paddingColor 非 内边距颜色 默认与background一致 background 非 二维码背景颜色,默认值白色 [代码]'#ffffff'[代码] foreground 非 二维码前景色,默认值黑色 [代码]'#000000'[代码] typeNumber 非 二维码的计算模式,默认值-1 8 correctLevel 非 二维码纠错级别,默认值为高级,取值:[代码]{ L: 1, M: 0, Q: 3, H: 2 }[代码] 1 image 非 在 canvas 上绘制图片,层级高于二维码,v1.1.1+版本支持。具体使用见:例子2 [代码]{imageResource: '', width:80, height: 80, round: true}[代码]
2023-04-02 - 小程序注销问题汇总
1、注销成功后,流程不可逆? 帐号一旦成功注销,流程不可逆。 2、小程序注销过程中,是否可以撤销注销,恢复使用? 冻结期间可登录小程序后台,点击“取消注销”,可恢复帐号正常使用。 3、组织类型如何修改打款信息? 在发起注销申请后,需自行填写帐号主体正确的对公账户信息。若您不小心填写错,建议等待验证失败或者超时未验证后再次重新填写。 4、组织类型支付验证打款后,多久验证成功? 若打款账户信息和金额正确,1个工作日内会验证成功。 5、小额打款验证成功后,退款到账时间多久? 验证成功后,打款金额退回具体到账时间视银行而定,一般为3-10个工作日内,原路退回。 6、管理员手机端的注销帐号确认,不小心删除,是否支持补发? 不支持。目前管理员确认注销有效期为7天,且每天都会下发提醒,建议您留意下一次的消息提醒。 注:若已确认,将不会再下发消息提醒。 7、注销流程中是否会通知小程序项目成员? 在进入冻结期、取消注销、注销成功时会下发模板消息通知小程序项目成员。 8、小程序注销成功后已关联该小程序的的公众号是否会收到通知? 在冻结期、注销成功时会下发模板消息通知关联该小程序的公众号管理员。 9、小程序冻结期间,用户可以正常访问吗? 已发布小游戏冻结期间用户可正常访问小游戏,每日首次访问,弹窗提示用户该小游戏即将下架;其余类型小程序用户无法访问。 10、已发布的小游戏,在注销期间,虚拟支付如何结算? 虚拟支付延期30天结算。 11、已发布的小游戏,在注销期间,用户可以进行支付吗? 不可以。 12、小程序注销条件是什么? ①小程序必须是已注册成功的帐号。 ②已开通广告主服务的小程序广告投放账户余额须为零。 ③须自主暂停线上小程序版本服务(除已发布小游戏帐号外)。 温馨提示: 海外小程序不支持注销。 小程序帐号内已发布插件线上版本的不支持注销。 13、小程序注销冻结期内,帐号还可以使用吗? 普通小程序、未发布的小游戏: 冻结期7天,帐号所有功能不可用,资源仍为占用 已发布的小游戏: ①冻结期为30天,资源仍为占用 ②已发布的小游戏冻结期内部分功能可用,但需关闭充值功能 ③虚拟支付延期30天结算 温馨提示:冻结期间可登录小程序后台,点击“取消注销”,可恢复帐号正常使用。 14、注销成功后可以释放哪些资源? ①管理员确认注销后,立即释放以下资源: 绑定邮箱、主体名称、管理员信息(姓名、身份证号、手机号码、微信号)、项目成员信息、关联关系。 ②成功注销后,原来的昵称有2*24小时(即2天)的保护期,在此期间,符合命名唯一规则情况下,同一主体下的其他帐号可以使用该名称,主体不一致的,则需要在保护期满后才能申请使用该名称。 温馨提示:冻结期内,资源仍处于占用状态
2020-03-18