var app = getApp(); let myCanvasWidth = null; let myCanvasHeight = null; let unit = ""; let canvasDpr = 1; Page({ /** * 页面的初始数据 */ data: { Data: {}, time: "", Day: "00", //剩余天 Hour: "00", //剩余小时 Min: "00", //剩余分钟 Sec: "00", //剩余秒 stop: false, //判断活动是否结束 show: false, loadingImg: true, ithumb: "", canvasWidth: "", canvasHeight: "", star_time: "1582963135", end: "", timer: null, info: {}, isSetNotice: false, postData: {}, room_id: "", shareBol: false, loadingMessage: "海报生成中", // 推广二维码id code_id:'', }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.getiPnoneBottom(); if (options.scene) { let scene = decodeURIComponent(options.scene); if (scene) { var info_arr = []; info_arr = scene.split(","); for (let i = 0; i < info_arr.length; i++) { let chil_arr = []; chil_arr = info_arr[i].split("="); if (chil_arr[0] == "id") { this.setData({ room_id: chil_arr[1], }); }else if (chil_arr[0] == "share") { this.setData({ shareBol: true, }); } else if (chil_arr[0] == "mid") { app._setMid(chil_arr[1]); } } } } else { if(options.cd) { this.setData({ code_id : options.cd }); } if (options.mid) { app._setMid(options.mid); } if (options.id) { this.setData({ room_id: options.id, }); } if (options.share) { this.data.shareBol = true; } } wx.getSystemInfo({ success: (res) => { canvasDpr = wx.getSystemInfoSync().pixelRatio; if (res.windowWidth * 2 < 750) { unit = res.windowWidth / 620; } else { unit = res.windowWidth / 750; } myCanvasWidth = 620 * canvasDpr * unit; myCanvasHeight = 883 * canvasDpr * unit; this.setData({ canvasWidth: parseInt(myCanvasWidth), canvasHeight: parseInt(myCanvasHeight), }); }, }); // this.getAvaterInfo() this.getPoster(); this.getData(); }, getiPnoneBottom() { let that = this; try { var value = wx.getStorageSync("iPhoneBottom"); if (value) { that.setData({ iPnoneBottomBol: true, }); // Do something with return value } } catch (e) { // Do something when catch error } }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () {}, /** * 生命周期函数--监听页面显示 */ onShow: function () {}, /** * 生命周期函数--监听页面隐藏 */ onHide: function () {}, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { clearTimeout(this.data.timer); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () {}, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () {}, /** * 用户点击右上角分享 */ onShareTimeline: function () { let value = wx.getStorageSync("yz_uid"); let mid = ""; if (value) { mid = value; } return { title: "欢迎进入" + this.data.postData.nickname + "的" + this.data.info.nickname + "直播间!", query: "id=" + this.data.room_id + "&share=1" + "&mid=" + mid, }; }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { var value = wx.getStorageSync("yz_uid"); var mid = ""; if (value) { mid = value; } return { title: "欢迎进入" + this.data.postData.nickname + "的" + this.data.info.nickname + "直播间!", path: "/packageD/directSeeding/foreshow/foreshow?id=" + this.data.room_id + "&share=1" + "&mid=" + mid, }; }, showCloseBtn() { this.setData({ show: false, }); }, posterBtn() { this.setData({ show: true, }); // if (this.data.ithumb){ // }else{ // this.setData({ // loadingImg: true // }) // wx.showToast({ // title: '生成海报中...', // icon: 'none', // duration: 1500 // }) // } }, initData() { this.setData({ time: "", Day: "", Hour: "", Min: "", Sec: "", }); }, checkStart(){ let urlStr = app.getNetAddresss( "plugin.room.frontend.live-list.room-notice" ); app._postNetWork({ url: urlStr, showToastIn: false, data: { id: this.data.room_id, }, success: function (resdata) { var res = resdata.data; if (res.result == 1) { if (that.data.shareBol && res.data.status == 3) { wx.showModal({ title: "提示", content: "主播正在直播中,跳转直播间", showCancel: false, success(res) { if (res.confirm) { wx.redirectTo({ url: "/packageD/directSeeding/livePage/livePage?id=" + that.data.room_id + "&playerType=live" + "&cd=" + that.data.code_id, }); } }, }); } } }, fail: function (res) { console.log(res.msg); }, }); }, //活动倒计时 countdown() { // 当前时间戳 const now = Date.parse(new Date()) / 1000; if (this.data.end - now <= 0) { this.setData({ stop: true, }); // 倒计时结束后请求接口查看是否开播,携带推广id跳转到直播,仅页面有code_id才走下面的方法,不影响原功能 if(this.data.code_id){ this.checkStart(); } return; } let msec = 0; if (now >= this.data.star_time) { // 相差的秒数 msec = this.data.end - now; } else { msec = this.data.star_time - now; } // 计算的时间 let day = parseInt(msec / 60 / 60 / 24); let hr = parseInt((msec / 60 / 60) % 24); let min = parseInt((msec / 60) % 60); let sec = parseInt(msec % 60); // 个位数前补零 hr = hr > 9 ? hr : "0" + hr; min = min > 9 ? min : "0" + min; sec = sec > 9 ? sec : "0" + sec; // 控制台打印 // this.time=`${day}天 ${hr}小时 ${min}分钟 ${sec}秒` this.setData({ Day: day, Hour: hr, Min: min, Sec: sec, }); // 一秒后递归 this.data.timer = setTimeout(() => { this.countdown(); }, 1000); }, getAvaterInfo() { let statusText = this.data.postData.status == 2 ? "预告" : this.data.postData.status == 3 ? "直播中 " : "回放"; const ctx = wx.createCanvasContext("myCanvas"); // 画banner图 ctx.fillStyle = "#FFFFFF"; ctx.fillRect(0, 0, this.data.canvasWidth, this.data.canvasHeight); let headWH = 56 * canvasDpr * unit; { let avatarurl_width = headWH; //绘制的头像宽度 let avatarurl_heigth = headWH; //绘制的头像高度 let avatarurl_x = 215 * canvasDpr * unit; //绘制的头像在画布上的位置 let avatarurl_y = 23 * canvasDpr * unit; //绘制的头像在画布上的位置 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(); //画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因 if (this.data.postData.shop_logo) { ctx.drawImage( this.data.postData.shop_logo, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth ); // 推进去图片,必须是https图片 } ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 } ctx.setFontSize(13 * canvasDpr); ctx.setFillStyle("#000"); ctx.fillText( this.data.postData.shop_name, 296 * canvasDpr * unit, 60 * canvasDpr * unit ); this.drawImg( ctx, 560 * canvasDpr * unit, 440 * canvasDpr * unit, this.data.postData.cover, this.data.postData.imgData.width, this.data.postData.imgData.height, 30 * canvasDpr * unit, 98 * canvasDpr * unit ); // ctx.drawImage(this.data.postData.cover, 30 * unit, 98 * unit, 560 * unit, 440 * unit); { let x = 437 * canvasDpr * unit, y = 117 * canvasDpr * unit, w = 127 * canvasDpr * unit, h = 42 * canvasDpr * unit, fillColor = "#ff7200", r = 10 * canvasDpr; // if (2 * r > w || 2 * r > h) { // return false; // } ctx.save(); ctx.translate(x, y); //绘制圆角矩形的各个边 this.drawRoundRectPath(ctx, w, h, r); ctx.fillStyle = fillColor; ctx.fill(); ctx.restore(); ctx.setFillStyle("#fff"); ctx.setFontSize(14 * canvasDpr); if (statusText.length == 2) { ctx.fillText( statusText, 474 * canvasDpr * unit, 148 * canvasDpr * unit ); } else { ctx.fillText( statusText, 460 * canvasDpr * unit, 148 * canvasDpr * unit ); } } let headWH_2 = 42 * canvasDpr * unit; { let avatarurl_width = headWH_2; //绘制的头像宽度 let avatarurl_heigth = headWH_2; //绘制的头像高度 let avatarurl_x = 52 * canvasDpr * unit; //绘制的头像在画布上的位置 let avatarurl_y = 117 * canvasDpr * unit; //绘制的头像在画布上的位置 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(); //画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因 ctx.drawImage( this.data.postData.avatar, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth ); // 推进去图片,必须是https图片 ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 } { let text = this.data.postData.nickname; //这是要绘制的文本'; let chr = text.split(""); //这个方法是将一个字符串分割成字符串数组 let temp = ""; let row = []; ctx.setFontSize(28 * canvasDpr * unit); ctx.setFillStyle("#fff"); for (let a = 0; a < chr.length; a++) { if (ctx.measureText(temp).width < 160 * canvasDpr) { temp += chr[a]; } else { a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比 row.push(temp); temp = ""; } } row.push(temp); //如果数组长度大于2 则截取前两个 if (row.length > 2) { let rowCut = row.slice(0, 2); let rowPart = rowCut[1]; let test = ""; let empty = []; for (let a = 0; a < rowPart.length; a++) { if (ctx.measureText(test).width < 306 * canvasDpr * unit) { test += rowPart[a]; } else { break; } } empty.push(test); let group = empty[0] + "..."; //这里只显示两行,超出的用...表示 rowCut.splice(1, 1, group); row = rowCut; } for (let b = 0; b < row.length; b++) { ctx.fillText( row[b], 108 * canvasDpr * unit, 146 * canvasDpr * unit + b * (28 * canvasDpr * unit) ); } ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 } // ctx.setFontSize(13) // ctx.setFillStyle("#fff") // ctx.fillText(this.data.postData.nickname, 108 * unit, 146 * unit) ctx.save(); { let text = this.data.postData.title; //这是要绘制的文本'; let chr = text.split(""); //这个方法是将一个字符串分割成字符串数组 let temp = ""; let row = []; ctx.setFontSize(28 * canvasDpr * unit); ctx.setFillStyle("#333333"); for (let a = 0; a < chr.length; a++) { if (ctx.measureText(temp).width < 160 * canvasDpr) { temp += chr[a]; } else { a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比 row.push(temp); temp = ""; } } row.push(temp); //如果数组长度大于2 则截取前两个 if (row.length > 2) { let rowCut = row.slice(0, 2); let rowPart = rowCut[1]; let test = ""; let empty = []; for (let a = 0; a < rowPart.length; a++) { if (ctx.measureText(test).width < 306 * canvasDpr * unit) { test += rowPart[a]; } else { break; } } empty.push(test); let group = empty[0] + "..."; //这里只显示两行,超出的用...表示 rowCut.splice(1, 1, group); row = rowCut; } for (let b = 0; b < row.length; b++) { ctx.fillText( row[b], 41 * canvasDpr * unit, 620 * canvasDpr * unit + b * (28 * canvasDpr * unit) ); } ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 ctx.setFontSize(12 * canvasDpr); ctx.setFillStyle("#ff7200"); ctx.fillText( "直播时间 " + this.data.postData.live_time, 36 * canvasDpr * unit, 730 * canvasDpr * unit ); } let headWH_3 = 48 * canvasDpr * unit; { let avatarurl_width = headWH_3; //绘制的头像宽度 let avatarurl_heigth = headWH_3; //绘制的头像高度 let avatarurl_x = 35 * canvasDpr * unit; //绘制的头像在画布上的位置 let avatarurl_y = 763 * canvasDpr * unit; //绘制的头像在画布上的位置 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(); //画好了圆 剪切 原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内 这也是我们要save上下文的原因 ctx.drawImage( this.data.postData.m_avatar, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth ); // 推进去图片,必须是https图片 ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 } { let text = this.data.postData.m_nickname + "的分享"; //这是要绘制的文本'; let chr = text.split(""); //这个方法是将一个字符串分割成字符串数组 let temp = ""; let row = []; ctx.setFontSize(28 * canvasDpr * unit); ctx.setFillStyle("#666666"); for (let a = 0; a < chr.length; a++) { if (ctx.measureText(temp).width < 160 * canvasDpr) { temp += chr[a]; } else { a--; //这里添加了a-- 是为了防止字符丢失,效果图中有对比 row.push(temp); temp = ""; } } row.push(temp); //如果数组长度大于2 则截取前两个 if (row.length > 2) { let rowCut = row.slice(0, 2); let rowPart = rowCut[1]; let test = ""; let empty = []; for (let a = 0; a < rowPart.length; a++) { if (ctx.measureText(test).width < 306 * canvasDpr * unit) { test += rowPart[a]; } else { break; } } empty.push(test); let group = empty[0] + "..."; //这里只显示两行,超出的用...表示 rowCut.splice(1, 1, group); row = rowCut; } for (let b = 0; b < row.length; b++) { ctx.fillText( row[b], 94 * canvasDpr * unit, 796 * canvasDpr * unit + b * (28 * canvasDpr * unit) ); } ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 } // ctx.setFontSize(13) // ctx.setFillStyle("#666666") // ctx.fillText(this.data.postData.m_nickname + '的分享', 94 * unit, 796 * unit) ctx.save(); ctx.drawImage( this.data.postData.qr_code, 408 * canvasDpr * unit, 581 * canvasDpr * unit, 180 * canvasDpr * unit, 180 * canvasDpr * unit ); ctx.restore(); //恢复之前保存的绘图上下文 恢复之前保存的绘图上下午即状态 还可以继续绘制 ctx.setFontSize(12 * canvasDpr); ctx.setFillStyle("#333"); ctx.fillText( "长按保存图片", 430 * canvasDpr * unit, 800 * canvasDpr * unit ); ctx.draw(false, this.toimage()); }, drawImg(ctx, cWidth, cHeight, imgPath, imgWidth, imgHeight, x, y) { console.log("cWidth", cWidth); console.log("cHeight", cHeight); console.log("imgWidth", imgWidth); console.log("imgHeight", imgHeight); let dWidth = cWidth / imgWidth; // canvas与图片的宽度比例 let dHeight = cHeight / imgHeight; // canvas与图片的高度比例 if ( (imgWidth > cWidth && imgHeight > cHeight) || (imgWidth < cWidth && imgHeight < cHeight) ) { if (dWidth > dHeight) { ctx.drawImage( imgPath, 0, (imgHeight - cHeight / dWidth) / 2, imgWidth, cHeight / dWidth, x, y, cWidth, cHeight ); } else { ctx.drawImage( imgPath, (imgWidth - cWidth / dHeight) / 2, 0, cWidth / dHeight, imgHeight, x, y, cWidth, cHeight ); } } else { if (imgWidth < cWidth) { ctx.drawImage( imgPath, 0, (imgHeight - cHeight / dWidth) / 2, imgWidth, cHeight / dWidth, x, y, cWidth, cHeight ); } else { ctx.drawImage( imgPath, (imgWidth - cWidth / dHeight) / 2, 0, cWidth / dHeight, imgHeight, x, y, cWidth, cHeight ); } } }, drawRoundRectPath(cxt, width, height, radius) { cxt.beginPath(0); //从右下角顺时针绘制,弧度从0到1/2PI cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2); //矩形下边线 cxt.lineTo(radius, height); //左下角圆弧,弧度从1/2PI到PI cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI); //矩形左边线 cxt.lineTo(0, radius); //左上角圆弧,弧度从PI到3/2PI cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2); //上边线 cxt.lineTo(width - radius, 0); //右上角圆弧 cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2); //右边线 cxt.lineTo(width, height - radius); cxt.closePath(); }, toimage() { wx.hideLoading(); this.setData({ showBtn: true, }); let that = this; setTimeout(() => { wx.canvasToTempFilePath({ x: 0, y: 0, width: this.data.canvasWidth, height: this.data.canvasHeight, destWidth: this.data.canvasWidth * 4, destHeight: this.data.canvasHeight * 4, canvasId: "myCanvas", success: function (res) { console.log(res); var tempFilePath = res.tempFilePath; that.setData({ ithumb: tempFilePath, loadingImg: false, }); }, fail: function (res) { console.log(res); }, }); }, 1500); }, saveShareImg: function () { wx.showLoading({ title: "保存中", }); wx.canvasToTempFilePath({ x: 0, y: 0, width: this.data.canvasWidth, height: this.data.canvasHeight, destWidth: this.data.canvasWidth * 4, destHeight: this.data.canvasHeight * 4, canvasId: "myCanvas", success: function (res) { console.log(res); wx.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success(result) { wx.showToast({ title: "图片保存成功", icon: "success", duration: 2000, }); }, fail: (res) => { wx.hideLoading(); }, }); }, }); }, getPoster() { let that = this; let urlStr = app.getNetAddresss("plugin.room.frontend.live-list.room-post"); app._postNetWork({ url: urlStr, showToastIn: false, data: { id: this.data.room_id, }, success: function (resdata) { var res = resdata.data; if (res.result == 1) { that.setData({ postData: res.data, }); that.downImg(); } else { wx.showToast({ icon: "none", title: res.msg, duration: 1500, }); } }, fail: function (res) { console.log(res.msg); }, }); }, //预先下载图片数据 downImg() { let that = this; if (this.data.postData.avatar) { wx.downloadFile({ url: this.data.postData.avatar, // 服务器返回的图片地址 success: (res) => { that.setData({ "postData.avatar": res.tempFilePath, }); if (that.data.postData.cover) { wx.downloadFile({ url: that.data.postData.cover, // 服务器返回的图片地址 success: (res) => { that.setData({ "postData.cover": res.tempFilePath, }); // 获取图片信息 wx.getImageInfo({ src: that.data.postData.cover, success(res) { that.setData({ "postData.imgData": res, }); if (that.data.postData.m_avatar) { wx.downloadFile({ url: that.data.postData.m_avatar, // 服务器返回的图片地址 success: (res) => { that.setData({ "postData.m_avatar": res.tempFilePath, }); if (that.data.postData.qr_code) { wx.downloadFile({ url: that.data.postData.qr_code, // 服务器返回的图片地址 success: (res) => { that.setData({ "postData.qr_code": res.tempFilePath, }); if (that.data.postData.shop_logo) { wx.downloadFile({ url: that.data.postData.shop_logo, // 服务器返回的图片地址 success: (res) => { that.setData({ "postData.shop_logo": res.tempFilePath, }); that.getAvaterInfo(); }, fail: function (res) { that.setData({ loadingMessage: "海报生成失败,商城图标下载失败", }); // 失败回调 console.log(res, "失败"); }, }); } else { that.setData({ "postData.shop_logo": "", }); that.getAvaterInfo(); } }, fail: function (res) { // 失败回调 console.log(res, "失败"); that.setData({ loadingMessage: "海报生成失败,小程序二维码下载失败", }); }, }); } }, fail: function (res) { // 失败回调 that.setData({ loadingMessage: "海报生成失败,用户头像图片下载失败", }); console.log(res, "失败"); }, }); } }, }); // res.tempFilePath是网络图片的本地地址 }, fail: function (res) { // 失败回调 that.setData({ loadingMessage: "海报生成失败,直播封面图片下载失败", }); console.log(res, "失败"); }, }); } // res.tempFilePath是网络图片的本地地址 }, fail: function (res) { that.setData({ loadingMessage: "海报生成失败,主播头像图片下载失败", }); // 失败回调 console.log(res, "失败"); }, }); } }, getData() { let that = this; let urlStr = app.getNetAddresss( "plugin.room.frontend.live-list.room-notice" ); app._postNetWork({ url: urlStr, showToastIn: false, data: { id: this.data.room_id, }, success: function (resdata) { var res = resdata.data; if (res.result == 1) { let anchor_member_id = res.data.anchor_member_id; if (that.data.shareBol && res.data.status == 3) { wx.showModal({ title: "提示", content: "主播正在直播中,跳转直播间", showCancel: false, success(res) { if (res.confirm) { wx.redirectTo({ url: "/packageD/directSeeding/livePage/livePage?id=" + that.data.room_id + "&playerType=live", }); } }, }); } else if (that.data.shareBol && res.data.status == 4) { wx.showModal({ title: "提示", content: "直播已经结束,跳转该主播页面", showCancel: false, success(res) { if (res.confirm) { wx.redirectTo({ url: "/packageD/directSeeding/anchorDetail/anchorDetail?id=" + anchor_member_id, }); } }, }); } that.setData({ info: res.data, end: res.data.live_time, isSetNotice: res.data.notice == 1 ? true : false, //是否已订阅开播提醒 }); that.countdown(); } else { wx.showToast({ icon: "none", title: res.msg, duration: 1500, }); } }, fail: function (res) { console.log(res.msg); }, }); }, showToastBtn() { let that = this; let _url = null; let _parameter = this.data.isSetNotice; if (_parameter == 1) { _url = "plugin.room.frontend.live-list.cancel-notice"; //取消开播提醒 } else { _url = "plugin.room.frontend.live-list.play-notice"; //设置开播提醒 } let urlStr = app.getNetAddresss(_url); app._postNetWork({ url: urlStr, showToastIn: false, data: { id: this.data.room_id, }, success: function (resdata) { var res = resdata.data; if (res.result == 1) { if (_parameter == 1) { that.setData({ isSetNotice: 0, }); wx.showToast({ icon: "none", title: "已取消提醒", duration: 1500, }); } else { that.setData({ isSetNotice: 1, }); wx.showToast({ icon: "none", title: "已成功订阅", duration: 1500, }); } } else { wx.showToast({ icon: "none", title: res.msg, duration: 1500, }); } }, fail: function (res) { console.log(res.msg); }, }); }, });