uniapp写微信小程序实现电子签名

news2024/11/26 10:44:43

写电子签名一定要注意的是一切全部按照手机上的适配来,为啥这么说呢,因为你在微信开发者工具中调试的时候认为是好的,正常的非常nice,当你发布版本的时候你会发现问题出来了。我下边的写法你可以直接用很简单。就是要记住canvas的几个属性和用法。

直接上干货

1.签名样式页面


      <!-- 签名 -->
      <view class="wrapper n-sign">
        <view class="h3">人员签字</view>
        <view class="handCenter">
          <canvas class="handWriting" :disable-scroll="true" @touchstart="uploadScaleStart" @touchmove="uploadScaleMove"
            canvas-id="handWriting"></canvas>
        </view>
        <view class="footer">
          <view :class="{ button: 1, 'n-sign-disabled': (startX == null && startY == null) }" @tap="retDraw">清除</view>
          <view :class="{ button: 1, 'n-sign-disabled': (startX == null && startY == null) }" @tap="saveCanvasAsImg">提交
          </view>
        </view>
      </view>

2.记得定义

  data() {
    return {
      canvasName: 'handWriting',
      ctx: '',
      startX: null,
      startY: null,
      canvasWidth: 0,
      canvasHeight: 0,
      selectColor: 'black',
      lineColor: '#1A1A1A', // 颜色
      lineSize: 5, // 笔记倍数
      name: '', //用来区分多个签字
     
    };
  },

3.事件


  methods: {
// 笔迹开始
    uploadScaleStart(e) {
      this.startX = e.changedTouches[0].x
      this.startY = e.changedTouches[0].y
      //设置画笔参数
      //画笔颜色
      this.ctx.setStrokeStyle(this.lineColor)
      //设置线条粗细
      this.ctx.setLineWidth(this.lineSize)
      //设置线条的结束端点样式
      this.ctx.setLineCap("round") //'butt'、'round'、'square'
      //开始画笔
      this.ctx.beginPath()
    },
    // 笔迹移动
    uploadScaleMove(e) {
      //取点
      let temX = e.changedTouches[0].x
      let temY = e.changedTouches[0].y
      //画线条
      this.ctx.moveTo(this.startX, this.startY)
      this.ctx.lineTo(temX, temY)
      this.ctx.stroke()
      this.startX = temX
      this.startY = temY
      this.ctx.draw(true)
    },
    /**
     * 重写
     */
    retDraw() {
      if (this.startX == null && this.startY == null) {
        return;
      }
      this.ctx.clearRect(0, 0, 700, 730);
      this.ctx.draw();
      //设置canvas背景
      this.setCanvasBg('#fff');
      this.startX = null;
      this.startY = null;
    },


    //生成图片
    async saveCanvasAsImg() {
      if (this.startX == null && this.startY == null) {
        return;
      }
      uni.showLoading({
        mask: true
      })
      var res = await uni.canvasToTempFilePath({
        canvasId: 'handWriting',
        fileType: 'png',
        quality: 1, //图片质量

      });
      for (var i = 0; i < res.length; i++) {
        if (res[i] && res[i].tempFilePath) {
          res = await this.nupload(res[i].tempFilePath, 14);
          break;
        }
      }
      // res = await this.nupload(path, 13);
      uni.hideLoading();
      uni.showToast({ title: "已上传" })
    },

    //设置canvas背景色  不设置  导出的canvas的背景为透明
    //@params:字符串  color
    setCanvasBg(color) {

      /* 将canvas背景设置为 白底,不设置  导出的canvas的背景为透明 */
      //rect() 参数说明  矩形路径左上角的横坐标,左上角的纵坐标, 矩形路径的宽度, 矩形路径的高度
      //这里是 canvasHeight - 4 是因为下边盖住边框了,所以手动减了写
      this.ctx.rect(0, 0, this.canvasWidth, this.canvasHeight - 4);
      // ctx.setFillStyle('red')
      this.ctx.setFillStyle(color);
      this.ctx.fill(); //设置填充
      this.ctx.draw(); //开画
    },
    // 上传图片并返回上传结果
    async nupload(filePath, imgType) {
      if (!filePath) return; //如果 filePath 不存在,直接返回

      // 调用 postWaitWorkImage 方法发送 POST 请求上传图片,并传递了文件路径、参数等信息。
      // 若上传成功,将返回结果解析为 JSON 格式(如果不是JSON格式,则直接使用原始结果)。



      const res = await postWaitWorkImage({
        filePath,
        name: "file",
        params: { imgType, id: this.merInfo.id, },
      }).catch((e) => (console.log(e), false));
      let res_;
      try {
        res_ = JSON.parse(res);
      } catch {
        res_ = res;
      }

      if (res_.code === 200) {
        return res_;
      } else {
        uni.showToast({ title: "上传失败", icon: "error" });
        return false;
      }
    },
  },

4.页面触发


  onReady() {
    this.$nextTick(() => {
      this.name = 'handWriting1'
      this.ctx = uni.createCanvasContext("handWriting");
      this.$nextTick(() => {
        uni.createSelectorQuery().select('.handCenter').boundingClientRect(rect => {
          this.canvasWidth = rect.width;
          this.canvasHeight = rect.height;
          /* 将canvas背景设置为 白底,不设置  导出的canvas的背景为透明 */
          this.setCanvasBg('#fff');
        })
          .exec();
      });
    })
  },

5.样式

.handWriting {
  background: #fff;
  width: 640rpx;
  height: 783rpx;
  border-radius: 20rpx;
  border: 1px solid #ff791c;
  overflow: hidden;
}

.handCenter {
  margin-bottom: 36rpx;

}

6.需要注意的是

实现签名我们用的是画布,不可能知道100%完美。所以这里我已经很合适的在设计了有啥问题可以留言。我把我的效果图看下看下希望对大家有帮助

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1393410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

探索数据之美:深入Seaborn的数据可视化艺术与技巧【第26篇—python:Seaborn】

文章目录 1. 引言2. Seaborn基础2.1 安装和环境设置2.2 常用数据可视化函数2.3 设置样式和颜色主题 3. 数据准备与导入3.1 使用Pandas库加载和处理数据3.2 数据清理和缺失值处理 4. Seaborn中的常见图表4.1 折线图和散点图&#xff1a;展示趋势和变量关系4.2 条形图和箱线图&am…

【昕宝爸爸小模块】深入浅出之针对大Excel做文件读取问题

➡️博客首页 https://blog.csdn.net/Java_Yangxiaoyuan 欢迎优秀的你&#x1f44d;点赞、&#x1f5c2;️收藏、加❤️关注哦。 本文章CSDN首发&#xff0c;欢迎转载&#xff0c;要注明出处哦&#xff01; 先感谢优秀的你能认真的看完本文&…

Nestjs 图片下载

一、download直接下载 1、添加下载代码 uploadController.ts import { Controller, Get, Post, Body, Patch, Param, Delete, UseInterceptors, UploadedFile, Res } from nestjs/common; import { UploadService } from ./upload.service; import { CreateUploadDto } from…

STM32WLE5JC介绍

32位 ARM Cotrex-M4 CPU 32MHz晶体振荡器 32 kHz RTC振荡器与校准 20x32位备份寄存器 引导程序支持USART和SPI接口 介绍 STM32WLE5/E4xx远程无线和超低功耗器件嵌入了强大的超低功耗LPWAN兼容无线电解决方案&#xff0c;支持以下调制&#xff1a;LoRa&#xff0c;&#xff08…

C++类与对象【对象的初始化和清理】

&#x1f308;个人主页&#xff1a;godspeed_lucip &#x1f525; 系列专栏&#xff1a;C从基础到进阶 C类与对象&#x1f384;1 对象的初始化和清理&#x1f955;1.1 构造函数和析构函数&#x1f955;1.2 构造函数的分类及调用&#x1f955;1.3 拷贝构造函数调用时机&#x1f…

C# 读取ini文件示例

一般使用一个相关win32 api的封装类&#xff1b;我用的如下&#xff1b; using System; using System.Runtime.InteropServices; using System.Text;namespace DotNet.Utilities {/// <summary>/// INI文件读写类。/// </summary>public class INIFile{public str…

大数据毕业设计:基于python美食推荐系统+爬虫+Echarts可视化+协同过滤推荐算法+Django框架(源码)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

4D毫米波雷达——原理、对比、优势、行业现状

前言 4D 毫米波雷达是传统毫米波雷达的升级版&#xff0c;4D指的是速度、距离、水平角度、垂直高度四个维度。 相比传统 3D 毫米波雷达&#xff0c;4D 毫米波雷达增加了“高度”的探测&#xff0c;将第四个维度整合到传统毫米波雷达中。 4D毫米波雷达被视为未来车载雷达的一…

【计算机网络】【Python】【练习题】【新加坡南洋理工大学】【Computer Control Network】

一、题目描述 该题目描述一个网络中数据包交换&#xff08;Packet Switching&#xff09;的例子。题目如下&#xff1a; 二、问题解答&#xff08;使用Python&#xff09; Q1&#xff1a;如何求出0.0004这个值&#xff1f; &#xff08;1&#xff09;、公式推导过程&#xf…

072:vue+mapbox 点击某图层feature,高亮这部分

第072个 点击查看专栏目录 本示例是介绍如何在vue+mapbox中点击某图层feature,高亮这部分。思路是通过点击,获取点击部分的feature信息,生成一个新的source和layer,如果这个图层不为空,则清除之,相当于点击了别的地方,原有的高亮会删除掉,在别的地方高亮。 直接复制下…

ubuntu系统(10):使用samba共享linux主机中文件

目录 一、samba安装步骤 1、Linux主机端操作 &#xff08;1&#xff09;安装sabma &#xff08;2&#xff09;修改samba配置文件 &#xff08;3&#xff09;为user_name用户设置samba访问的密码 &#xff08;4&#xff09;重启samba服务 2、Windows端 二、使用 1、代码…

google网站流量怎么获取?

流量是一个综合性的指标&#xff0c;可以说做网站就是为了相关流量&#xff0c;一个网站流量都没有&#xff0c;那其实就跟摆饰品没什么区别 而想从谷歌这个搜索引擎里获取流量&#xff0c;一般都分为两种方式&#xff0c;一种是网站seo&#xff0c;另一种自然就是投广告&#…

《C++ Primer》第15章 面向对象程序设计(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 15.1 OOP&#xff1a;概述&#xff08;P526&#xff09; **面向对象程序设计&#xff08;object-oriented programming&#xff09;**的核心思想是数据抽象、继承和动态绑定。 继承 通过继承&#xff08;…

逆变器之变压器基础知识

1 基础知识 我们的磁芯要工作的话&#xff0c;必须要有磁场&#xff0c;有磁场就就会有磁力线。 磁场我们是看不着摸不见的&#xff0c;为了好的描述磁场&#xff0c;我们就用磁力线来表示&#xff0c; 磁力线是有方向的&#xff0c;在一个磁铁的内部磁力线是从 S指向N的&…

Elasticsearch:和 LIamaIndex 的集成

LlamaIndex 是一个数据框架&#xff0c;供 LLM 应用程序摄取、构建和访问私有或特定领域的数据。 LlamaIndex 是开源的&#xff0c;可用于构建各种应用程序。 在 GitHub 上查看该项目。 安装 在 Docker 上设置 Elasticsearch 使用以下 docker 命令启动单节点 Elasticsearch 实…

【创作活动】ChatGPT 和文心一言哪个更好用?

文章目录 文心一言优点缺点 ChatGPT优点缺点 Java编码能力比较对人工智能的看法 ChatGPT是由OpenAI开发的交互式AI大模型&#xff0c; 文心一言是由百度研发的知识增强大语言模型&#xff0c;本文从Java开发的角度对比一下哪个更好用&#xff08;本文仅用于投稿CSDN创造活动&am…

【playwright】新一代自动化测试神器playwright+python系列课程15_playwright网页相关操作_网页截图

Playwright 网页截图 在做web自动化测试时&#xff0c;脚本执行时会出现执行失败的情况&#xff0c;这个时候就需要分析失败的原因&#xff0c;由于脚本执行时是不需要人工盯着执行的&#xff0c;这个时候就需要在脚本执行失败时保留某些信息方便脚本执行完成后来分析失败的原…

SpringMVC(全局异常处理.动态接收Ajax请求)

1.全局异常处理 1 异常处理器 基于AOP 用户发起请求, SpringMVC接受请求, SpringMVC加载静态资源问题说明 请求过去了,但没有处理 规则说明:静态资源进入SpringMVC框架之后,没有找到要怎样处理静态资源的方法,所以他们就不解决,也就不显示 解决方法:SpringMVC基于Servlet处理…

添加边界值分析测试用例

1.1创建项目成功后会自动生成封装好的函数&#xff0c;在这些封装好的函数上点击右键&#xff0c;添加边界值分析测试用例&#xff0c;如下图所示。 1.2生成的用例模版是不可以直接运行的&#xff0c;需要我们分别点击它们&#xff0c;让它们自动生成相应测试用例。如下图所示&…

华为路由器配置访问控制列表ACL用例

配置要求 如组网图所示&#xff0c;R3为服务器&#xff0c;R1为客户端&#xff0c;客户端与服务器 之间路由可达。其中R1和R2间互联物理接口地址分别为 10.1.2.1/24和10.1.2.2/24&#xff0c;R2和R3间互联物理接口地址分别 为10.1.3.2/24和10.1.3.1/24。另外&#xff0c;R1上创…