微信小程序使用canvas画图保存图片到手机相册

ops/2024/11/14 12:47:22/

小程序>微信小程序要实现使用canvas绘制一个图,然后保存到手机相册

**最终效果:**实现生成以下图片在这里插入图片描述

一、初始化canvas

// wxml页面设置canvas标签
<canvas style="width: {{windowW}}px; height: {{windowH}}px;" disable-scroll='true' canvas-id="myCanvas" wx:if="{{showCanvas}}"></canvas>
// js页面初始化canvas
data: {ctx: '',details: '',windowW: 375*3,windowH: 265*3,ratio:3,showCanvas:false},onLoad(options) {this.setData({ctx: wx.createCanvasContext('myCanvas'),showCanvas:true})},

二、绘制canvas

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

三、封装文字换行缩进

// 由于右侧文字较多,需要缩进和自动换行
drawText(ctx, str, leftWidth, initHeight, titleHeight, canvasWidth) {ctx.setFontSize(16);let lineWidth = 0;let lastSubStrIndex = 0; // 每次开始截取的字符串的索引const indentWidth = 20; // 定义缩进宽度let shouldIndent = false; // 是否需要缩进for (let i = 0; i < str.length; i++) {const charWidth = ctx.measureText(str[i]).width;lineWidth += charWidth;// 检查是否需要换行if (lineWidth > canvasWidth - indentWidth || str[i] === '。') {// 处理当前行文本let lineText = str.substring(lastSubStrIndex, i + 1);if (shouldIndent) {lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;shouldIndent = false; // 只在句号后的一行缩进}ctx.fillText(lineText, leftWidth, initHeight); // 绘制文本initHeight += 22; // 16为字体的高度lineWidth = 0; // 新行开始时宽度为0lastSubStrIndex = i + 1; // 更新开始截取的索引// 如果遇到句号,设置需要缩进的标志if (str[i] === '。') {shouldIndent = true;}// 更新leftWidth并考虑缩进leftWidth = leftWidth;}}// 处理最后一行文本if (lastSubStrIndex < str.length) {let lineText = str.substring(lastSubStrIndex);if (shouldIndent) {lineText = ' '.repeat(indentWidth / ctx.measureText(' ').width) + lineText;}ctx.fillText(lineText, leftWidth, initHeight);}// 标题border-bottom 线距顶部距离titleHeight += 10;return titleHeight;
},

http://www.ppmy.cn/ops/111714.html

相关文章

【MyBatis】Java 数据持久层框架:认识 MyBatis

Java 数据持久层框架&#xff1a;认识 MyBatis 1.CRUD 注解2.映射注解3.高级注解3.1 高级注解3.2 MyBatis 3 注解的用法举例 MyBatis 和 JPA 一样&#xff0c;也是一款优秀的 持久层框架&#xff0c;它支持定制化 SQL、存储过程&#xff0c;以及高级映射。它可以使用简单的 XML…

vue组件注册

项目目前的组件注册机制是按需注册&#xff0c;是在需要用到的页面才引入。 <template><Menu><SubMenu></SubMenu><Menu><menu><sub-menu></sub-menu><menu> </template> <script> import { Menu } from a…

20道经典自动化测试面试题【建议收藏】

概述 觉得自动化测试很难&#xff1f; 是的&#xff0c;它确实不简单。但是学会它&#xff0c;工资高啊&#xff01; 担心面试的时候被问到自动化测试&#xff1f; 嗯&#xff0c;你担心的没错&#xff01;确实会被经常问到&#xff01; 现在应聘软件测试工程师的岗位&…

代码随想录算法训练营第48天 | LeetCode739.每日温度、 LeetCode496.下一个更大元素I、 LeetCode503.下一个更大元素II

目录 LeetCode739.每日温度 LeetCode496.下一个更大元素I 1. 暴力解法 2. 单调栈法 LeetCode503.下一个更大元素II LeetCode739.每日温度 给定一个整数数组 temperatures &#xff0c;表示每天的温度&#xff0c;返回一个数组 answer &#xff0c;其中 answer[i] 是指对于…

中关村科金推出得助音视频鸿蒙SDK,助力金融业务系统鸿蒙化提速

鸿蒙生态大势所趋&#xff0c;各种应用适配加速 近日&#xff0c;华为纯血鸿蒙系统&#xff08;HarmonyOS NEXT&#xff09;再度引发市场高度关注。据媒体消息&#xff0c;鸿蒙NEXT Beta版将在9月24日对Mate 60系列、X5系列、Pura70系列等16款旗舰机型进行推送&#xff0c;这已…

神经网络通俗理解学习笔记(4) 深度生成模型VAE、GAN

深度生成模型 什么是生成式模型蒙特卡洛方法变分推断Variational Inference变分自编码器VAE生成对抗网络Generative Adversarial NetworkDiffusion 扩散模型 什么是生成式模型 判别式和生成式模型 判别式:CNN/RNN/transformer;生成式:AE/VAE/GAN 判别式模型学习类别边界&#…

linux-系统备份与恢复-系统恢复

Linux 系统备份与恢复&#xff1a;系统恢复 1. 概述 Linux 系统的恢复是系统管理的重要组成部分&#xff0c;它指的是在系统崩溃、硬件故障、误操作或安全问题后&#xff0c;恢复系统到可用状态的过程。良好的系统恢复计划可以有效避免数据丢失和业务中断&#xff0c;并确保系…

HarmonyOS开发5.0【骨架屏】 app界面制作

实现原理 1.定义组件和状态变量&#xff1a; 使用 Entry 和 Component 装饰器定义了一个名为 IvSkeleton 的组件。 定义了一个状态变量 translageX&#xff0c;初始值为 -100%&#xff0c;用于控制闪电效果的位置。 定义了两个数值变量 widthValue 和 heightValue&#xff0c;…