IT评测·应用市场-qidao123.com

标题: 微信小程序使用canvas绘图保存图片得手机相册 [打印本页]

作者: 梦应逍遥    时间: 2024-9-21 19:34
标题: 微信小程序使用canvas绘图保存图片得手机相册
微信小程序要实现使用canvas绘制一个图,然后保存得手机相册

**最终效果:**实现生成以下图片

一、初始化canvas

  1. // wxml页面设置canvas标签
  2. <canvas style="width: {{windowW}}px; height: {{windowH}}px;" disable-scroll='true' canvas-id="myCanvas" wx:if="{{showCanvas}}"></canvas>
复制代码
  1. // js页面初始化canvas
  2. data: {
  3.     ctx: '',
  4.     details: '',
  5.     windowW: 375*3,
  6.     windowH: 265*3,
  7.     ratio:3,
  8.     showCanvas:false
  9.   },
  10.   onLoad(options) {
  11.     this.setData({
  12.       ctx: wx.createCanvasContext('myCanvas'),
  13.       showCanvas:true
  14.     })
  15.   },
复制代码
二、绘制canvas

  1. // 绘制一个准考证并下载到手机相册
  2. getsaves(){
  3.     var that = this;
  4.     let rat = 3;
  5.     that.data.ctx.setFontSize(8*rat);
  6.     that.data.ctx.setFillStyle('#080808');
  7.     that.data.ctx.fillText('山东省第六届中小学生作文大赛决赛', 28*rat, 29*rat);
  8.     that.data.ctx.setFontSize(8*rat);
  9.     that.data.ctx.fillText('准考证', 81*rat, 59*rat);
  10.     that.data.ctx.setFontSize(6*rat);
  11.     that.data.ctx.fillText('考试时间:' + '10月18日(周五)上午9:00-11:00', 35*rat, 78*rat);
  12.     that.data.ctx.fillText('考试地点:山东师范大学附属小学', 35*rat, 93*rat);
  13.     that.data.ctx.fillText('济南市历下区山师北街1号', 66*rat, 104*rat);
  14.     // that.data.ctx.fillText(that.data.details.cityName=='济南市'?'考试地点:山东师范大学附属小学':'考试地点:临沂商城实验学校', 26*rat, 93*rat);
  15.     // that.data.ctx.fillText(that.data.details.cityName=='济南市'?'济南市历下区山师北街1号':'临沂市兰山区兰山街道工业大道59号', 56*rat, 104*rat);
  16.    
  17.     that.data.ctx.setFillStyle('#444444');
  18.     that.data.ctx.fillText('准考证号', 43*rat, 128*rat);
  19.     that.data.ctx.fillText('考生姓名', 43*rat, 144*rat);
  20.     that.data.ctx.fillText('考生学校', 43*rat, 160*rat);
  21.     that.data.ctx.fillText('考生组别', 43*rat, 176*rat);
  22.     that.data.ctx.fillText('考场号', 43*rat, 192*rat);
  23.     that.data.ctx.fillText('座位号', 43*rat, 208*rat);
  24.     that.data.ctx.setFillStyle('#000000');
  25.     that.data.ctx.fillText('2023005020340', 81*rat, 128*rat);
  26.     that.data.ctx.fillText('张三', 81*rat, 144*rat);
  27.     that.data.ctx.fillText('蒋庄矿区学校', 81*rat, 160*rat);
  28.     that.data.ctx.fillText('初中组', 81*rat, 176*rat);
  29.     that.data.ctx.fillText('--', 81*rat, 192*rat);
  30.     that.data.ctx.fillText('--', 81*rat, 208*rat);
  31.     that.data.ctx.setFillStyle('#080808');
  32.     that.data.ctx.setFontSize(5*rat);
  33.     that.data.ctx.fillText('请妥善保管,凭有效身份证件(身份证、户口本、护照、', 35*rat, 226*rat);
  34.     that.data.ctx.fillText('社保卡、学生证等)入场考试。', 35*rat, 238*rat);
  35.     that.data.ctx.setFontSize(8*rat);
  36.     that.data.ctx.fillText('考生守则', 255*rat, 29*rat);
  37.     const text1 = '     一、考生必须自觉服从监考员等考试工作人员管理,不得以任何理由妨碍监考员等考试工作人员履行职责,不得扰乱考场及其他考试工作地点的秩序。二、考生凭准考证、身份证(学生证、户口簿)按规定时间、地点参加考试。三、考生人场,除书写用0.5mm黑色签字笔外,其他任何物品不准带入考场。严禁携带各种通讯工具(如无线耳机、移动电话及其他无线接收、传送设备等)、手表、电子存储记忆录放设备以及涂改液、修正带等物品进人考场。考场内不得自行传递文具、用品等。四、考生入场后,对号入座,将准考证等证件放在课桌左上角以便核验,考生领到答题和试卷后,应检查答题卡和试卷是否有重印、漏印、字迹不清等印刷质量问题或缺页现象,如有,请立即举手报告,否则在开考一段时间后,考生如发现上述问题,由此延误的考试时不予弥补。考生应在指定位置和规定的时间内准确清楚地填写毕业学校、姓名准考证号、座号等栏目。五、开考信号发出后才能开始答题。六、开考15 分钟后不准人场。七、在考场内须保持安静,不准喧哗,不准交头接耳、左顾右盼,不准将试题、草稿纸带出考场。八、考试终了信号发出后,考生应立即停止答卷,并按试题、草稿纸自下而上的顺序排放好,坐在座位上,等候考员查收,无误后,根据监考员指令依次离开考场。九、如不遵守考场纪律,不服从考试工作人员管理,有违纪、作弊等行为的,将按照《国家教育考试违规处理办法》进行处理。';
  38.     that.drawText(that.data.ctx, text1, 185*rat, 49*rat, 30*rat,165*rat); // 假设每行的最大宽度为300像素
  39.     that.data.ctx.setStrokeStyle("#646464");
  40.     that.data.ctx.setLineWidth(1);
  41.     that.data.ctx.rect(35*rat, 118*rat, 127*rat, 96*rat);
  42.     that.data.ctx.stroke()
  43.     that.data.ctx.beginPath(); //创建一条路径   
  44.     that.data.ctx.moveTo(35*rat, 133*rat); //描述路径的起点为手指触摸的x轴和y轴
  45.     that.data.ctx.lineTo(162*rat, 133*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴
  46.     that.data.ctx.moveTo(35*rat, 149*rat); //描述路径的起点为手指触摸的x轴和y轴
  47.     that.data.ctx.lineTo(162*rat, 149*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴
  48.     that.data.ctx.moveTo(35*rat, 165*rat); //描述路径的起点为手指触摸的x轴和y轴
  49.     that.data.ctx.lineTo(162*rat, 165*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴
  50.     that.data.ctx.moveTo(35*rat, 181*rat); //描述路径的起点为手指触摸的x轴和y轴
  51.     that.data.ctx.lineTo(162*rat, 181*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴
  52.     that.data.ctx.moveTo(35*rat, 197*rat); //描述路径的起点为手指触摸的x轴和y轴
  53.     that.data.ctx.lineTo(162*rat, 197*rat); //绘制一条直线,终点坐标为手指触摸结束后的x轴和y轴
  54.     that.data.ctx.moveTo(73*rat,118*rat);
  55.     that.data.ctx.lineTo(73*rat, 214*rat); // 绘制一条直线到终点
  56.     that.data.ctx.stroke();
  57.    
  58.     that.data.ctx.draw(true, function () {
  59.       that.daochu();
  60.     });
  61. },
复制代码
三、封装笔墨换行缩进

  1. // 由于右侧文字较多,需要缩进和自动换行
  2. drawText(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {
  3.     ctx.setFontSize(16);
  4.     let lineWidth = 0;
  5.     let lastSubStrIndex = 0; // 每次开始截取的字符串的索引
  6.     const indentWidth = 20; // 定义缩进宽度
  7.     let shouldIndent = false; // 是否需要缩进
  8.     for (let i = 0; i < str.length; i++) {
  9.       const charWidth = ctx.measureText(str[i]).width;
  10.       lineWidth += charWidth;
  11.   
  12.       // 检查是否需要换行
  13.       if (lineWidth > canvasWidth - indentWidth || str[i] === '。') {
  14.         // 处理当前行文本
  15.         let lineText = str.substring(lastSubStrIndex, i + 1);
  16.         if (shouldIndent) {
  17.           lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;
  18.           shouldIndent = false; // 只在句号后的一行缩进
  19.         }
  20.         ctx.fillText(lineText, leftWidth, initHeight); // 绘制文本
  21.         initHeight += 22; // 16为字体的高度
  22.         lineWidth = 0; // 新行开始时宽度为0
  23.         lastSubStrIndex = i + 1; // 更新开始截取的索引
  24.   
  25.         // 如果遇到句号,设置需要缩进的标志
  26.         if (str[i] === '。') {
  27.           shouldIndent = true;
  28.         }
  29.         // 更新leftWidth并考虑缩进
  30.         leftWidth = leftWidth;
  31.       }
  32.     }
  33.     // 处理最后一行文本
  34.     if (lastSubStrIndex < str.length) {
  35.       let lineText = str.substring(lastSubStrIndex);
  36.       if (shouldIndent) {
  37.         lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;
  38.       }
  39.       ctx.fillText(lineText, leftWidth, initHeight);
  40.     }
  41.     // 标题border-bottom 线距顶部距离
  42.     titleHeight += 10;
  43.     return titleHeight;
  44. },
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4