小程序画布

    技术2025-07-12  13

    需要用canvas画图,导出图片,然后整了半天,才画出来,遇到了特么坑的是,官方给的demo都是报错的,文档上的示例代码不能用,这是官方的示例

    <canvas type="2d" id="myCanvas"></canvas>

    这是真正使用的

    <canvas canvas-id="myCanvas" style="width:375px;height:667px;margin:0 auto;"></canvas>

    官方并没有说明,而且给的示例用的都是id,导致花了很长时间才搞明白原因。 下面就开始画图了

    mapping() { let _this = this; //背景图 let promiseBg = new Promise(function (resolve, reject) { wx.getImageInfo({ src: 'http://classimage.goouc.com/uploads/images/1/20200630/f71a2ddc91b43bdc372b29e503d56926.png', success(res) { console.log(res) resolve(res); } }) }) //头像 let promiseHeader = new Promise(function (resolve, reject) { wx.getImageInfo({ src: 'http://classimage.goouc.com/uploads/images/1/20200702/0fb028c82c4f055ded6beb843373cb4e.jpg', success(res) { console.log(res) resolve(res); }, fail(err) { console.log(err); } }) }) // 二维码 let promiseQr = new Promise(function (resolve, reject) { wx.getImageInfo({ src: 'http://classimage.goouc.com/uploads/images/1/20200704/edcfdfecaad8d6cddddbed130e262673.png', success(res) { console.log(res) resolve(res); }, fail(err) { console.log(err); } }) }) Promise.all([promiseBg, promiseHeader, promiseQr]).then(res => { const ctx = wx.createCanvasContext('myCanvas'); ctx.clearRect(0, 0, 375, 667); // 背景 ctx.drawImage(res[0].path, 0, 0, 375, 667); //标题 证书 ctx.setFontSize(27); ctx.setFillStyle('#333') ctx.setTextAlign('center'); ctx.font = 'normal bold 27px sans-serif';//对字体进行加粗 ctx.fillText('结课证书', 187.5, 148, 235); //头像 ctx.save();//先对之前的内容进行保存 ctx.beginPath(); ctx.arc(187.5, 203, 30, 0, 2 * Math.PI); ctx.clip();//截取这部分画的图形,下面的图像就填入了画好的图形内 //图片变形处理 _this.processingDeformation(ctx,res[1].path,res[1].width,res[1].height,60,60,157.5,173); ctx.restore();//截取图形结束,恢复画布 //昵称 ctx.setFontSize(16); ctx.setFillStyle('#333') ctx.setTextAlign('center'); ctx.font = 'normal 500 16px sans-serif'; ctx.fillText('玲珑咖啡', 187.5, 258, 235); //在考试中获得 分割字体 let examText = '考试考试考试考试考试考试' let examTextArr = examText.split(''); let exam1 = ''; let exam2 = ''; for (let i = 0; i < examTextArr.length; i++) { if (ctx.measureText(exam1).width < 126) { exam1 += examTextArr[i]; } else { exam2 = exam1 + '...'; } } ctx.setFontSize(14); ctx.setFillStyle('#999') ctx.setTextAlign('center'); ctx.font = 'normal 200 14px sans-serif'; ctx.fillText('在「' + exam2 + '」获得', 187.5, 294, 235); //分数 ctx.setFontSize(60); ctx.setFillStyle('#333') ctx.setTextAlign('right'); ctx.font = 'normal 500 60px sans-serif'; ctx.fillText('90', 200, 380, 200); //分 字 ctx.setFontSize(16); ctx.setFillStyle('#333') ctx.setTextAlign('left'); ctx.font = 'normal 500 16px sans-serif'; ctx.fillText('分', 216, 380); //字体分割 评语 let fontText = '一分耕耘,一分收获,未必;九分耕耘,会有收获,一定!'; let fontTextArr = fontText.split(''); let text1 = ''; let text2 = ''; for (let i = 0; i < fontTextArr.length; i++) { if (ctx.measureText(text1).width < 235) { text1 += fontTextArr[i]; } else { text2 += fontTextArr[i]; } } ctx.setFontSize(14); ctx.setFillStyle('#333') ctx.setTextAlign('center'); ctx.font = 'normal 400 14px sans-serif'; ctx.fillText(text1, 187.5, 420, 235); ctx.fillText(text2, 187.5, 440, 235); //二维码 ctx.save(); ctx.beginPath(); // ctx.fillRect(148, 479, 80,80); // ctx.strokeRect(148, 479, 80, 80) ctx.rect(148, 479, 80, 80) ctx.clip(); //图片变形处理 _this.processingDeformation(ctx,res[2].path,res[2].width,res[2].height,80,80,148,479); ctx.restore(); //在线学院 ctx.setFontSize(14); ctx.setFillStyle('#333') ctx.setTextAlign('center'); ctx.font = 'normal 500 14px sans-serif'; ctx.fillText('在线学院', 187.5, 594, 235); //长按识别二维码关注 ctx.setFontSize(12); ctx.setFillStyle('#999') ctx.setTextAlign('center'); ctx.font = 'normal 200 12px sans-serif'; ctx.fillText('长按识别二维码关注', 187.5, 619, 235); //结束 ctx.draw(false, function () { wx.canvasToTempFilePath({ x: 0, y: 0, width: 375, height: 667, destWidth: 3000,//像素点 越密集 导出图像越清晰 destHeight: 5336, canvasId: 'myCanvas', success(res) { _this.setData({ imgurl: res.tempFilePath }) console.log(res.tempFilePath) } }) }); }) }, /** * 处理图片变形 以画好的图形短边为依据,把图片缩小到图形大小,然后对图片计算位置,以图形中心为中心进行定位,保证图片定位后正好在图形中间位置 * @param ctx 画布对象 * @param path 图片路径 * @param imgWidth 图片宽度 * @param imgHeight 图片高度 * @param containerWidth 容器宽度 * @param containerHeight 容器高度 * @param containerTop 容器上定位 * @param containerLeft 容器左定位 */ processingDeformation(ctx,path, imgWidth, imgHeight, containerWidth, containerHeight, containerTop, containerLeft) { let min = containerWidth >= containerHeight ? containerHeight : containerWidth; if (imgWidth > imgHeight) { let width = Math.floor(imgWidth / (imgHeight / min)); let height = min; ctx.drawImage(path, containerTop - (Math.floor(width / 2) - Math.floor(containerWidth / 2)), containerLeft, width, height); } else { let width = min; let height = Math.floor(imgHeight / (imgWidth / min)); ctx.drawImage(path, containerTop, containerLeft - (Math.floor(height / 2) - Math.floor(containerHeight / 2)), width, height); } }, //画好的图形保存到相册 downloadFile() { console.log() let _this = this; wx.saveImageToPhotosAlbum({ filePath: _this.data.imgurl, success(res) { console.log('res', res); wx.showToast({ title: '已保存到相册', icon: 'success', duration: 3000 }) } }) },

    效果图如下 以上就是画布全部得内容,欢迎指正!

    Processed: 0.018, SQL: 9