uniapp div区域长按下载到手机相册为照片
1.要求
uniapp 项目发布到微信小程序端,某一区域已经写好了样式,需要长按该区域,下载为到手机相册,为照片
2.实现
const handleDownload = async () => {try {// 1. 检查并请求保存到相册的权限const setting = await new Promise((resolve, reject) => {uni.getSetting({success: resolve,fail: reject});});if (!setting.authSetting['scope.writePhotosAlbum']) {await new Promise((resolve, reject) => {uni.authorize({scope: 'scope.writePhotosAlbum',success: resolve,fail: reject});});}// 2. 创建canvas并绘制整个授权码区域// 固定canvas宽高比例以匹配弹窗样式(图二)const canvasWidth = 750; // 固定宽度为750rpxconst canvasHeight = 1100; // 固定高度为1100rpx,确保比例与弹窗样式一致const canvas = uni.createOffscreenCanvas({type: '2d',width: canvasWidth,height: canvasHeight});const ctx = canvas.getContext('2d');// 3. 绘制授权码区域(背景、文字、二维码)// 先绘制整个白色背景,确保没有透明区域ctx.fillStyle = '#FFFFFF';ctx.fillRect(0, 0, canvasWidth, canvasHeight);// 绘制蓝色背景ctx.fillStyle = '#1D1E70';ctx.fillRect(0, 0, canvasWidth, 200); // 顶部标题背景 - 增加高度ctx.fillRect(0, 210, canvasWidth, 15); // 分隔线 - 调整位置ctx.fillRect(0, canvasHeight - 200, canvasWidth, 200); // 底部文字背景 - 增加高度// 绘制标题文字ctx.fillStyle = '#FFFFFF';ctx.font = '900 90px sans-serif'; // 进一步增大字体大小,与图二类似ctx.textAlign = 'center';ctx.textBaseline = 'middle';ctx.fillText('入住授权码', canvasWidth / 2, 100); // 调整位置// 绘制小区名称 - 调整位置使上边距更加美观ctx.fillStyle = '#000000';ctx.font = '400 60px sans-serif'; // 进一步增大字体大小,与图二类似ctx.fillText(cellNameLabel.value, canvasWidth / 2, 300); // 调整位置,增加与上方分隔线的距离// 绘制二维码 - 使用微信小程序原生Canvas APIconst qrWidth = 360; // 增大二维码宽度,使其占比更大const qrHeight = 360; // 增大二维码高度,使其占比更大const qrX = (canvasWidth - qrWidth) / 2;const qrY = 350; // 调整二维码位置,与小区名称保持合适距离// 将base64转为ArrayBuffer并保存为临时文件const base64Data = baseImg.value.replace(/^data:image\/\w+;base64,/, '');const arrayBuffer = uni.base64ToArrayBuffer(base64Data);const qrTempFilePath = uni.env.USER_DATA_PATH + '/temp_qrcode.png';// 写入文件const fs = uni.getFileSystemManager();fs.writeFileSync(qrTempFilePath, arrayBuffer, 'binary');// 使用canvas绘制二维码图片// 先获取图片信息,确保图片可以正确绘制const imageInfo = await new Promise((resolve, reject) => {uni.getImageInfo({// 使用本地文件路径作为srcsrc: qrTempFilePath,success: resolve,fail: reject});});// 创建canvas 2D的Image对象const img = canvas.createImage();// 使用Promise等待图片加载完成await new Promise((resolve, reject) => {img.onload = resolve;img.onerror = reject;img.src = qrTempFilePath;});// 绘制二维码到canvasctx.drawImage(img, qrX, qrY, qrWidth, qrHeight);// 绘制房间号 - 调整位置使其距离二维码更远,距离下方蓝色底部更近ctx.fillStyle = '#000000';ctx.font = '400 60px sans-serif'; // 进一步增大字体大小,与图二类似ctx.fillText(roomNumLabel.value, canvasWidth / 2, 800); // 调整位置,增加与二维码距离,减少与底部蓝色区域距离// 绘制底部文字ctx.fillStyle = '#FFFFFF';ctx.font = '700 66px sans-serif'; // 进一步增大字体大小,与图二类似ctx.fillText('扫码授权后开门入住', canvasWidth / 2, canvasHeight - 100); // 调整位置// 4. 将canvas导出为图片并保存到相册const canvasTempFilePath = await new Promise((resolve, reject) => {uni.canvasToTempFilePath({canvas: canvas,success: (res) => resolve(res.tempFilePath),fail: reject});});// 5. 保存图片到相册 - 直接使用canvas导出的完整图片路径await new Promise((resolve, reject) => {uni.saveImageToPhotosAlbum({filePath: canvasTempFilePath,success: resolve,fail: reject});});uni.showToast({ title: '保存成功', icon: 'success', duration: 2000 });} catch (error) {console.error('保存图片失败:', error);let errorMsg = '保存失败';if (error.errMsg && error.errMsg.includes('auth deny')) {errorMsg = '请先授权保存到相册权限';}uni.showToast({ title: errorMsg, icon: 'none', duration: 2000 });}
};
3.思路
首先,要访问是否有下载到本地的权限,然后就是创建画布,将内容绘制归置进去,最后在利用uni原生方法下载到本地