小程序设置中开启相册权限(canvas实现微信小程序的图片分享功能)

首页教程更新时间:2023-06-22 01:22:30
业务场景

二轮充电业务中,用户充电完成后在订单详情页展示订单相关信息,用户点击分享按钮唤起微信小程序分享菜单,将生成的图片海报分享给微信好友或者下载到本地,好友可通过扫描海报中的二维码加群领取优惠。

使用场景及功能:微信小程序 生成海报图片 分享好友 下载图片

使用技术:Taro vue vant Canvas

实现效果图

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(1)

重点步骤拆分

1、封装一个海报分享组件 poster-share.vue

2、用canvas画图,将背景图、费用、二维码等信息绘制在一张图上,其中费用、二维码是动态获取的

3、生成一张本地缓存图片

4、唤起微信分享功能,实现分享和下载功能

重点步骤有了,那么就开干吧!

核心代码实现1、模版部分

需要一个画布dom用来绘制图片,一个用来存放生成图片的dom

问:canvasId为什么需要动态生成呢?

答:避免一个页面中使用多个组件引起的canvasId重复问题

<template> <div class="poster-share__content"> <!-- canvas生成的海报图片 --> <img v-if="posterImg" class="poster-share__content--img" mode="aspectFit" :src="posterImg" > <!-- 分享海报canvas绘制部分 --> <canvas class="poster-share__content--cvs" :canvas-id="canvasId" ></canvas> </div> </template>2、样式部分

该业务场景下,不能让用户看到画布,但是设置canvas的display为none将不能进行绘制,会报如下错误,导致绘制失败。

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(2)



实现方式:采用定位的方式,将canvas定位到可视区域外,具体代码如下。

.poster-share__content { position: absolute; right: -9999px; top: -9999px; width: 560px; height: 852px; opacity: 0; z-index: -1; &--img { width: 100%; height: 100%; } &--cvs { width: 100%; height: 100%; } } 3、核心js部分

开始写核心实现啦~

父组件传参控制子组件是否开始绘制,子组件绘制完成后通知父组件改变状态。

name: 'CpPosterShare', model: { prop: 'value', event: 'update:value', }, props: { value: { type: Boolean, default: false, }, config: { type: Object, default: () => ({}), }, }, data () { return { isDraw: false, // 是否开始绘制海报 posterImg: '', // 生成的海报图片地址 canvasId: `canvasId${ Math.random() }`, screenWidth: null, // 屏幕宽度 } }, watch: { value: { handler (val) { this.isDraw = val }, immediate: true, }, isDraw (val) { this.$emit('update:value', val) if (val) { this.init() } }, },

首先,我们做的是一个小程序,将图片放在小程序源码中会加大包的体积,需要从网络上下载图片,因此需要封装一个公共的方法来获取图片的信息。Taro提供getImageInfo方法返回图片的原始宽高、本地路径等信息。

// 加载图片 loadImg (src) { return newPromise((resolve, reject) => { Taro.getImageInfo({ src, }).then((res) => { resolve({ ...res }) }).catch((err) => { reject(err) }) }) }

该业务场景中涉及绘制多张图片,包括背景图片和二维码图片,需要将多张图片都load完成后才能开始绘制。

const promiseParams = [this.loadImg(BgImage), this.loadImg(QRcode)] const promiseAll = Promise.all(promiseParams.map((item) =>item.catch(() =>null))) promiseAll.then((res) => { this.draw(res) }).catch((err) => { console.log(err) })

开始绘制啦~

创建canvas绘图上下文CanvasContext对象,调用Taro提供的方法Taro.createCanvasContext(canvasId)绘制背景图、绘制价格、绘制二维码,这里就不一一赘述了。全部绘制完成后,将画布中的内容导出生成图片,Taro提供了canvasToTempFilePath方法,需要在draw()回调中调用才能保证图片导出成功,返回生成图片的临时路径。

ctx.draw(false, () => { Taro.canvasToTempFilePath({ canvasId:this.canvasId, }).then((res) => { this.posterImg = res.tempFilePath // 唤起分享菜单 this.showShareImageMenu() }).catch((err) => { console.log('海报生成失败', err) Taro.showToast({ title: '海报生成失败', icon: 'error', }) }).finally(() => { Taro.hideLoading() this.isDraw = false }) })

本地图片生成成功后,唤起微信提供的分享菜单弹窗,可以将图片发送给朋友、收藏、保存到相册。Taro提供showShareImageMenu方法唤起分享菜单弹窗,入参为本地图片路径。

showShareImageMenu () { if (Taro.showShareImageMenu) { Taro.showShareImageMenu({ path:this.posterImg, }).then().catch((err) => { console.log(err) const { errMsg } = err // 取消操作 errMsg === 'showShareImageMenu:fail cancel' // 拒绝授权 errMsg: "showShareImageMenu:fail auth deny" if (errMsg === 'showShareImageMenu:fail auth deny') { authorize({ scope:'writePhotosAlbum', showModal:true, authName:'保存图片到相册', success: () => { this.downloadImg() }, }) } }).finally(() => { this.isDraw = false }) } else { Taro.showToast({ title:'小程序版本不支持该功能', icon:'error', }) } }

用户点击发送给朋友,会调起微信对话框,将生成的海报图片粘贴分享给朋友;

点击收藏,会将海报图片添加到收藏列表中,方便下次查看;

点击保存到相册,会唤起保存图片授权弹窗,用户点击允许,会将海报图片保存在本地相册中。

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(3)



如果用户在保存图片授权弹窗中第一次点击拒绝,之后再次点击分享下载时,需要有授权提示弹窗,提示用户是否打开设置去授权,具体展示如下。

Taro提供Taro.openSetting方法调起小程序设置页面,用户开启“添加到相册”授权后成功后,调用Taro提供的下载图片的方法Taro.saveImageToPhotosAlbum将图片下载到本地。

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(4)

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(5)

小程序设置中开启相册权限,canvas实现微信小程序的图片分享功能(6)

授权提示弹窗

设置页面

下载提示

其中判断用户是否开启授权的方法具体实现如下:

/** * 权限获取流程 * @param scope 权限英文名称 * @param success 授权成功的回调 * @param fail 授权失败的回调 * @param showModal 授权失败是否展示对话框提示 * @param authName 授权失败是否展示对话框提示展示的授权名称 * // 例子:开启用户的相册权限 authorize({ scope: 'writePhotosAlbum', showModal: true, authName: '保存图片到相册', success () { console.log('授权成功') }, }) */ export async function authorize (options) { const { scope, success, fail, showModal = false, authName = '', } = options try { const scopeName = `scope.${ scope }` const auth = await Taro.getSetting() if (!auth.authSetting[scopeName]) { Taro.authorize({ scope: scopeName }).then((res) => { if (res.errMsg === 'authorize:ok' && success) success() }, () => { if (showModal && authName) { Taro.showModal({ title: '授权提示', content: `您拒绝了${ authName }权限,是否打开设置去授权?`, }).then((res) => { if (res.confirm) { Taro.openSetting().then((res2) => { if (res2.authSetting[scopeName] && success) { success() } else if (fail) { fail() } }) } else { fail && fail() } }).catch((res) => { fail && fail(res) }) } else { fail && fail() } }) } else { success && success() } } catch (err) { fail && fail(err) } }

至此,具体实现完结撒花~ 可以将组件用到页面中了

组件引用

<poster-share v-model="draw" // 是否开始绘制海报海报 config="config" // 海报配置信息 /> 问题记录

在开发过程中遇到了一些问题,记录一下

现象:点击分享,生成canvas图片。开发者工具上每次都正常,ios机每次都正常,部分安卓机每次都正常,部分安卓机,点击分享之后取消,操作多次,有几次会生成图片失败

报错信息:"errMsg": "canvasToTempFilePath:fail :create bitmap failed"

错误定位解决:canvas需要一直显示,不能有display:none的情况

作者:京东零售 张梦雨

内容来源:京东云开发者社区

,
点此查看全文
图文教程
相关文章
热门专题
推荐软件
奇热小说
奇热小说
下载
QQ2019手机版
QQ2019手机版
下载
王者荣耀
王者荣耀
下载
百度浏览器迷你版
百度浏览器迷你版
下载
2345浏览器手机版
2345浏览器手机版
下载
网易邮箱
网易邮箱
下载
爱奇艺
爱奇艺
下载
网易云音乐
网易云音乐
下载
WPSOffice
WPSOffice
下载
优酷
优酷
下载
谷歌浏览器(Chrome)
谷歌浏览器(Chrome)
下载
迅雷看看播放器
迅雷看看播放器
下载
UC浏览器
UC浏览器
下载
QQ音乐
QQ音乐
下载
阿里旺旺买家版v9.12.10C官方版
阿里旺旺买家版v9.12.10C官方版
下载
360安全卫士v12.1官方版
360安全卫士v12.1官方版
下载
猜你喜欢
E滁州
E滁州
下载
雪瓣私教
雪瓣私教
下载
雄霸武神之霸刀战魂
雄霸武神之霸刀战魂
下载
太阳帝国的原罪反叛和谐修改虐待电脑的MOD
太阳帝国的原罪反叛和谐修改虐待电脑的MOD
下载
荒野卡车模拟驾驶
荒野卡车模拟驾驶
下载
怪兽大厦
怪兽大厦
下载
呱呱学琴
呱呱学琴
下载
油友
油友
下载
雀小宝
雀小宝
下载
普拉多汽车冒险
普拉多汽车冒险
下载
极客应用
极客应用
下载
lifecalendarapp
lifecalendarapp
下载
问天诀
问天诀
下载
生化危城ios版
生化危城ios版
下载
海尔智控app
海尔智控app
下载
趣旅行
趣旅行
下载