// nova-werun/pages/home/share/index.js const qiniuUploader = require("../../../../utils/qiniuUploader"); const Parse = getApp().Parse; const company = getApp().globalData.company; const user = Parse.User.current() let getSportData = require('../../../service/getSportData') const dateF = require("../../../../utils/date") Page({ /** * 页面的初始数据 */ data: { sharList: [], images: [ // 'https://file-cloud.fmode.cn/qpFbRRSZrO/20250113/1p97lf053250915.png', 'https://file-cloud.fmode.cn/qpFbRRSZrO/20250113/bt19fm050427168.png' ], randomImage: '', saveimage: '', uptokenURL: '', domain: '', uploadURL: '', userList: [], }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.refersh() }, async refersh() { let { screenWidth } = wx.getWindowInfo() let rate_px_rpx = (screenWidth / 750) await this.showRandomImage() await this.setData({ user_json: user.toJSON(), rate_px_rpx }) await this.getData() this.setCanvas() }, /**随机展示图片 */ showRandomImage() { const randomIndex = Math.floor(Math.random() * this.data.images.length); this.setData({ randomImage: this.data.images[randomIndex] }); }, /**获取数据 */ async getData() { let rank = '200名之后' let step = await getSportData.getwalk('steps', '', '') || 0 let distance = await getSportData.getwalk('distance', '', '') || 0 if (distance) { let rd = await getSportData.getUserRank(user?.id, '', 'today') rank = rd[0]?.rank || 0 } console.log(rank, step, distance) this.setData({ rank, step, distance }) }, /**绘制canvas */ setCanvas() { let { rank, step, distance, user_json, randomImage } = this.data let that = this wx.createSelectorQuery() .select('#myCanvas') // 在 WXML 中填入的 id .fields({ node: true, size: true }) .exec((res) => { const canvas = res[0].node const ctx = canvas.getContext('2d') const width = res[0].width const height = res[0].height // 初始化画布大小 const dpr = wx.getWindowInfo().pixelRatio canvas.width = width * dpr canvas.height = height * dpr ctx.scale(dpr, dpr) ctx.clearRect(0, 0, width, height) //========背景===== let bg = canvas.createImage() bg.onload = () => { ctx.drawImage(bg, 0, 0, width, height) const gradient = ctx.createLinearGradient(0, 0, 0, height); gradient.addColorStop(0, 'rgba(255, 255, 255, 0)'); gradient.addColorStop(1, 'rgb(255, 255, 255)'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, width, height); //=========头像========= let avatar = canvas.createImage(); avatar.onload = () => { const radius = 20; // 圆的半径 const x = 40; const y = height - 185; ctx.save(); ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2, false); ctx.closePath(); ctx.clip(); ctx.drawImage(avatar, x - radius, y - radius, radius * 2, radius * 2); ctx.restore(); }; avatar.src = user_json.avatar; ctx.fillStyle = '#4F9AF7'; ctx.font = '15px bold Arial'; ctx.fillText(user_json.nickname, 70, height - 185); ctx.font = '10px Arial'; ctx.fillText(dateF.formatTime("YYYY.mm.dd HH:MM", user_json.createdAt), 70, height - 170); ctx.font = 'bold 20px Arial'; ctx.fillText('梦想家', 20, height - 140); ctx.font = '10px Arial'; ctx.fillText('用汗水实现想象,用脚步丈量梦想', 20, height - 125); ctx.font = '15px Arial'; ctx.fillText('今日排名', 20, height - 100); ctx.fillText('今日步数', width / 2 - 20, height - 100); ctx.fillText('公里数', width - 60, height - 100); ctx.font = 'bold 15px Arial'; ctx.fillText(rank, 20, height - 80); ctx.fillText(step, width / 2 - 20, height - 80); ctx.fillText(distance, width - 60, height - 80); ctx.font = '10px Arial'; ctx.fillText('长按二维码加入跑团', width - 170, height - 45); ctx.fillText('和我一起运动', width - 140, height - 30); let qr = canvas.createImage(); qr.onload = () => { ctx.drawImage(qr, width - 70, height - 70, 70, 70) }; qr.src = 'https://file-cloud.fmode.cn/qpFbRRSZrO/20250220/ig1167052435205.jpg?imageView2/1/w/200/h/200' } bg.src = 'https://file-cloud.fmode.cn/qpFbRRSZrO/20250113/bt19fm050427168.png' that.setData({ canvas }) }) }, /**保存图片 */ saveCanvas() { let { canvas } = this.data let that = this wx.canvasToTempFilePath({ canvas: canvas, success(res) { that.setData({ saveimage: res.tempFilePath }) wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: (res) => { console.log('success', res) wx.showToast({ title: '已下载图片', icon:'none' }) }, fail: (err) => { // console.log('err',err) } }) }, fail: (err) => { console.log(err) } }) }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { }, //绘制canvas rpxToPx(rpx) { const systemInfo = wx.getSystemInfoSync(); return rpx * (systemInfo.windowWidth / 750); }, getImageInfo(url) { console.log(url); return new Promise((result) => { wx.getImageInfo({ src: url, //服务器返回的图片地址 success: function (res) { // res.path是网络图片的本地地址 let Path = res.path; result(Path) }, fail(err) { console.log(err); result() } }); }) }, //获取用户信息 async getuser() { const currentUser = Parse.User.current(); let user = new Parse.Query('_User'); user.equalTo('company', company); user.notEqualTo('isDeleted', true); user.equalTo('objectId', currentUser.id); let P = await user.find(); let userList = P.map(item => item.toJSON()); this.setData({ userList, }) console.log('userList', this.data.userList); }, //rpx async saveImage() { // console.log('运行了'); const canvas = wx.createCanvasContext('myCanvas'); const width = this.rpxToPx(670); const height = this.rpxToPx(1100); // console.log(width, height); canvas.width = this.rpxToPx(670); canvas.height = this.rpxToPx(1100); const backgroundImage2 = await this.getImageInfo(this.data.randomImage); // 绘制背景图片 canvas.drawImage(backgroundImage2, 0, 0, width, height); // 加载背景图片 const backgroundImage1 = await this.getImageInfo('https://file-cloud.fmode.cn/qpFbRRSZrO/20250113/1r3o3q045323287.png'); // 绘制背景图片 canvas.drawImage(backgroundImage1, 0, 0, width, height); // 绘制背景 // canvas.setFillStyle('#CAE1FD'); // 背景色 // canvas.fillRect(0, 0, width, height); canvas.setFillStyle('#0178EE'); // let mainimage = await this.getImageInfo(this.data.randomImage) let avatar = Parse.User.current()?.get('avatar') console.log('avatar', avatar); let userAvatar = await this.getImageInfo(avatar) console.log('userAvatar', userAvatar); //主图片 // canvas.drawImage(mainimage, 0, 0, width, this.rpxToPx(500)); // 调整图片高度 //头像 if (userAvatar) { // 绘制带圆角的头像 const avatarX = this.rpxToPx(40); const avatarY = this.rpxToPx(540); const avatarSize = this.rpxToPx(83); const radius = avatarSize / 2; // 半径为头像大小的一半 // 绘制圆角矩形 canvas.save(); // 保存当前状态 canvas.beginPath(); // 开始路径 canvas.moveTo(avatarX + radius, avatarY); // 左上角 canvas.lineTo(avatarX + avatarSize - radius, avatarY); // 上边 canvas.arc(avatarX + avatarSize - radius, avatarY + radius, radius, 1.5 * Math.PI, 0, false); // 右上角 canvas.lineTo(avatarX + avatarSize, avatarY + avatarSize - radius); // 右边 canvas.arc(avatarX + avatarSize - radius, avatarY + avatarSize - radius, radius, 0, 0.5 * Math.PI, false); // 右下角 canvas.lineTo(avatarX + radius, avatarY + avatarSize); // 下边 canvas.arc(avatarX + radius, avatarY + avatarSize - radius, radius, 0.5 * Math.PI, Math.PI, false); // 左下角 canvas.lineTo(avatarX, avatarY + radius); // 左边 canvas.arc(avatarX + radius, avatarY + radius, radius, Math.PI, 1.5 * Math.PI, false); // 左上角 canvas.closePath(); // 关闭路径 canvas.clip(); // 剪切 // 绘制头像 canvas.drawImage(userAvatar, avatarX, avatarY, avatarSize, avatarSize); // 头像位置和大小 canvas.restore(); // 恢复状态 } // 绘制昵称和时间 const nickname = this.data.userList[0].nickname; const currentTime = this.data.sharList.currentTime; const rank = this.data.sharList.rank; const steps = this.data.sharList.totalSteps || 0; const distance = this.data.sharList.totaldistance || 0; canvas.setFontSize(this.rpxToPx(30)); canvas.fillText(nickname, this.rpxToPx(140), this.rpxToPx(580)); // 昵称位置 // console.log('昵称加载成功'); canvas.setFontSize(this.rpxToPx(28)); canvas.fillText(currentTime, this.rpxToPx(140), this.rpxToPx(610)); // 时间位置 // console.log('时间加载成功'); // 绘制其他文本 canvas.setFontSize(this.rpxToPx(55)); canvas.fillText('梦想家', this.rpxToPx(40), this.rpxToPx(720)); // console.log('梦想家加载成功'); canvas.setFontSize(this.rpxToPx(30)); canvas.fillText('用汗水实现想象,用脚步丈量梦想', this.rpxToPx(40), this.rpxToPx(780)); // console.log('汗水加载成功'); // 绘制排名、步数和公里数 canvas.setFontSize(this.rpxToPx(22)); // canvas.fillText('今日排名: ' + rank, 20, 400); canvas.fillText('今日排名', this.rpxToPx(40), this.rpxToPx(840)); // console.log('排名加载成功'); // canvas.fillText('今日步数: ' + steps, 20, 420); canvas.fillText('今日步数', this.rpxToPx(180), this.rpxToPx(840)); // console.log('步数加载成功'); // canvas.fillText('公里数: ' + distance + 'km', 20, 430); canvas.fillText('公里数', this.rpxToPx(320), this.rpxToPx(840)); // console.log('公里数加载成功'); canvas.setFontSize(this.rpxToPx(34)); canvas.fillText(rank, this.rpxToPx(70), this.rpxToPx(900)); canvas.fillText(steps, this.rpxToPx(180), this.rpxToPx(900)); canvas.fillText(distance + 'km', this.rpxToPx(320), this.rpxToPx(900)); // 加载二维码图片 const qrCodeImage = await this.getImageInfo('https://file-cloud.fmode.cn/qpFbRRSZrO/20250113/t2vst6051431547.png'); // 绘制二维码 canvas.drawImage(qrCodeImage, width - this.rpxToPx(140), height - this.rpxToPx(160), this.rpxToPx(120), this.rpxToPx(120)); canvas.setFillStyle('#0178EE'); canvas.setFontSize(this.rpxToPx(28)); canvas.fillText('长按二维码加入儒乐湖健身跑', width - this.rpxToPx(510), height - this.rpxToPx(120)); canvas.fillText('和我一起运动', width - this.rpxToPx(405), height - this.rpxToPx(80)); // 完成绘制 canvas.draw(false, () => { console.log('123'); wx.canvasToTempFilePath({ canvasId: 'myCanvas', success: (res) => { console.log('绘制完成', res); this.setData({ saveimage: res.tempFilePath }); this.getUptoken() console.log(this.data.saveimage); }, fail: (err) => { console.error('canvasToTempFilePath 失败', err); } }); }); }, uploadImageToServer() { const that = this; const tempFilePath = this.data.saveimage; // 获取本地临时文件路径 qiniuUploader.upload( tempFilePath, // 本地文件路径 (res) => { const imageURL = res.imageURL; // 上传成功后的网络地址 console.log('上传成功,网络地址:', imageURL); that.setData({ saveimage: imageURL // 更新 saveimage 为网络地址 }); }, (error) => { console.error('上传失败:', error); }, { region: "SCN", // 七牛云区域 uploadURL: that.data.uploadURL, // 上传地址 domain: that.data.domain, // 域名 uptoken: that.data.uptokenURL, // 上传凭证 } ); console.log('saveimage', this.data.saveimage); }, async getUptoken() { let res = await Parse.Cloud.run('qiniu_uptoken', { company: company }) this.setData({ uptokenURL: res.uptoken, domain: res.domain, uploadURL: res.zoneUrl }) this.uploadImageToServer() console.log(this.data.uptokenURL, this.data.domain, this.data.uploadURL); }, //点击保存图片 async savepic() { await this.saveImage() const imagePath = this.data.saveimage; // 获取保存的图片路径 if (imagePath) { // 调用保存图片到相册的方法 wx.saveImageToPhotosAlbum({ filePath: imagePath, success: () => { wx.showToast({ title: '图片已保存到相册', icon: 'success' }); }, fail: (err) => { console.error('保存失败', err); wx.showToast({ title: '保存失败', icon: 'none' }); } }); } else { wx.showToast({ title: '没有可保存的图片', icon: 'none' }); } }, //保存图片到相册 savepic2: function () { let that = this; wx.canvasToTempFilePath({ x: 0, y: 0, width: 670, height: 1100, destWidth: 670, destHeight: 1100, canvasId: 'myCanvas', success: function (result) { wx.getSetting({ success(res) { if (!res.authSetting['scope.writePhotosAlbum']) { wx.authorize({ scope: 'scope.writePhotosAlbum', success() { //这里是用户同意授权后的回调 // that.saveImgToLocal(); wx.saveImageToPhotosAlbum({ filePath: result.tempFilePath, success(res) { wx.showToast({ title: '图片已保存到相册', icon: 'success' }); } }) }, fail() { //这里是用户拒绝授权后的回调 wx.showToast({ title: '打开相册授权,才能保存图片哦~', icon: 'none', duration: 2000 }) that.setData({ openSettingBtnHidden: false }) } }) } else { //调取小程序当中获取图片 console.log(result.tempFilePath); wx.saveImageToPhotosAlbum({ filePath: result.tempFilePath, success(res) { wx.showToast({ title: '图片已保存到相册', icon: 'success' }); } }) } } }) }, fail: function (res) { console.log(res) } }) }, shar() { wx.downloadFile({ url: this.data.saveimage, //图片服务器地址 success: (res) => { wx.showShareImageMenu({ path: res.tempFilePath, //转为本地地址showShareImageMenu进行分享 success: (res) => { uni.hideLoading(); this.modalShare = null; }, fail: (err) => { uni.hideLoading(); this.modalShare = null; }, }); }, }); }, sharecircle() { wx.showLoading({ title: '保存图片', }) this.saveCanvas() setTimeout(() => { wx.hideLoading() wx.navigateTo({ url: '../../circle/send-circle/index' }); }, 1500); // wx.navigateTo({ // url: '../../circle/send-circle/index?image=' + this.data.saveimage // 目标页面的路径 // }); } })