vue+canvas画布实现网页签名效果

news2025/1/20 11:58:14

1、签名自定义组件代码示例:

qianMing.vue

<template>
  <!-- 容器,包含画布和清除按钮 -->
  <div class="signature-pad-container">
    <!-- 画布元素,用于用户签名 -->
    <canvas
      ref="canvas" <!-- 用于获取canvas DOM元素的引用 -->
      class="signature-pad" <!-- 自定义类名,便于样式控制 -->
      @mousedown="startDrawing" <!-- 鼠标按下时开始绘图 -->
      @mousemove="draw" <!-- 鼠标移动时持续绘图 -->
      @mouseup="stopDrawing" <!-- 鼠标抬起时停止绘图 -->
      @mouseleave="stopDrawing" <!-- 鼠标离开画布时停止绘图 -->
      @touchstart.prevent="startDrawing" <!-- 触摸屏幕开始绘图,阻止默认行为 -->
      @touchmove.prevent="draw" <!-- 触摸滑动时绘图,阻止默认行为 -->
      @touchend="stopDrawing" <!-- 触摸结束时停止绘图 -->
    ></canvas>
    <!-- 清除画布按钮 -->
    <button @click="clearCanvas">Clear</button>
  </div>
</template>

<script>
export default {
  // 数据属性定义
  data() {
    return {
      isDrawing: false, // 绘制状态标志,true为正在绘制
      context: null, // 2D渲染上下文,用于操作画布
      lastX: 0, // 上一次鼠标或触摸点的X坐标
      lastY: 0 // 上一次鼠标或触摸点的Y坐标
    };
  },
  // 挂载后执行,用于初始化画布
  mounted() {
    const canvas = this.$refs.canvas; // 获取canvas元素
    canvas.width = canvas.offsetWidth; // 设置画布宽度为元素显示宽度
    canvas.height = canvas.offsetHeight; // 设置画布高度为元素显示高度
    this.context = canvas.getContext('2d'); // 获取2D渲染上下文
    this.context.strokeStyle = '#000'; // 设置线颜色为黑色
    this.context.lineWidth = 2; // 设置线条宽度为2
  },
  // 方法集合
  methods: {
    // 开始绘图的处理函数
    startDrawing(event) {
      this.isDrawing = true; // 设置绘制状态为true
      // 获取事件坐标
      const { offsetX, offsetY } = this.getEventCoords(event);
      this.lastX = offsetX; // 记录起始点X坐标
      this.lastY = offsetY; // 记录起始点Y坐标
      this.context.beginPath(); // 开始一条新的路径
      this.context.moveTo(this.lastX, this.lastY); // 移动到起始点
    },
    // 绘图过程中的处理函数
    draw(event) {
      // 如果不是绘制状态则返回
      if (!this.isDrawing) return;
      // 获取当前坐标
      const { offsetX, offsetY } = this.getEventCoords(event);
      // 从上一点画直线到当前位置
      this.context.lineTo(offsetX, offsetY);
      this.context.stroke(); // 绘制路径
      // 更新最后的位置坐标
      this.lastX = offsetX;
      this.lastY = offsetY;
    },
    // 停止绘图的处理函数
    stopDrawing() {
      this.isDrawing = false; // 设置绘制状态为false
      this.context.closePath(); // 结束当前路径
    },
    // 清除画布的方法
    clearCanvas() {
      const canvas = this.$refs.canvas; // 获取canvas元素
      // 清除整个画布
      this.context.clearRect(0, 0, canvas.width, canvas.height);
    },
    // 获取事件坐标的方法,兼容触控和鼠标事件
    getEventCoords(event) {
      // 如果是触控事件,则计算相对于canvas的位置
      if (event.touches && event.touches.length > 0) {
        const rect = this.$refs.canvas.getBoundingClientRect(); // 获取canvas元素的边界信息
        return {
          offsetX: event.touches[0].clientX - rect.left, // 触摸点相对画布左边界的X坐标
          offsetY: event.touches[0].clientY - rect.top // 触摸点相对画布上边界的Y坐标
        };
      } else { // 否则是鼠标事件
        return {
          offsetX: event.offsetX, // 鼠标事件直接提供相对于元素内部的坐标
          offsetY: event.offsetY
        };
      }
    }
  }
};
</script>

<style scoped>
/* 容器样式 */
.signature-pad-container {
  position: relative; /* 使子元素可以绝对定位 */
  width: 100%; /* 宽度充满父容器 */
  height: 100px; /* 高度固定 */
  border: 1px solid #ccc; /* 边框样式 */
  border-radius: 15px; /* 边框圆角 */
}

/* 画布样式 */
.signature-pad {
  width: 100%; /* 宽度充满容器 */
  height: 100%; /* 高度充满容器 */
  cursor: crosshair; /* 鼠标指针为十字准星 */
  touch-action: none; /* 禁止浏览器对触摸事件的默认处理 */
}

/* 清除按钮样式 */
button {
  position: absolute; /* 绝对定位 */
  top: 10px; /* 距离顶部距离 */
  right: 10px; /* 距离右侧距离 */
  z-index: 10; /* 确保按钮在最上层 */
}
</style>

2、在script中引入自定义组件

<script>
import qianMing from "@/components/qianMing.vue";
export default {
  name: 'App',
  data() { 
    return {
     
    }
  },
  methods: {
   
  },
  components: {
    qianMing
  }
}
</script>

完成上述步骤即可实现网页签名效果。

效果图:

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

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

相关文章

后劳动经济学(PLE):AI时代的工作未来

引言 随着人工智能&#xff08;AI&#xff09;和自动化技术的飞速发展&#xff0c;我们迎来了一个新的经济范式——后劳动经济学&#xff08;PLE&#xff09;。这一概念主要讨论在AI和自动化技术超越人类能力的关键领域后&#xff0c;机器将不可避免地在许多经济活动中取代人类…

昇思25天学习打卡营第12天|ShuffleNet图像分类

1. 学习内容复盘 ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型&#xff0c;和MobileNet, SqueezeNet等一样主要应用在移动端&#xff0c;所以模型的设计目标就是利用有限的计算资源来达到最好的模型精度。ShuffleNetV1的设计核心是引入了两种操作&a…

恢复策略(上)-撤销事务(UNDO)、重做事务(REDO)

一、引言 利用前面所建立的冗余数据&#xff0c;即日志和数据库备份&#xff0c;要将数据库从一个不一致的错误状态恢复到一个一致性状态&#xff0c;还需要相关的恢复策略&#xff0c;不同DBMS的事务处理机制所采用的缓冲区管理策略可能不同&#xff0c;发生故障后的数据库不…

LeetCode刷题之HOT100之最大正方形

今天下起了暴雨&#xff0c;本以为下午就可以结束的答辩又因为老师开会被推迟。研三的学长走了后我们开始了0元购&#xff0c;收获颇丰哈哈&#xff0c;做个题 1、题目描述 2、算法分析 给定一个矩形&#xff0c;要求最大正方形。第一次见这种题目哈 2024 6/30 嘿嘿&#xff…

一区算法MPA|海洋捕食者算法原理及其代码实现(Matlab/Python))

Matlab/Python&#xff1a; 本文KAU将介绍一个2020年发表在1区期刊ESWA上的优化算法——海洋捕食者算法 (Marine Predators Algorithm&#xff0c;MPA)[1] 该算法由Faramarzi等于2020年提出&#xff0c;其灵感来源于海洋捕食者之间不同的觅食策略、最佳相遇概率策略、海洋记…

C++异常智能指针

目录 异常 异常的定义 异常的抛出和捕获 异常安全问题 异常的规范 智能指针 RAII思想 使用RAII的例子 智能指针 文件资源 在linux中管理锁资源 智能指针发展历程 auto_ptr unique_ptr shared_ptr 异常 异常的定义 异常是一种处理运行时错误的机制&#xff0c;它…

20240629在飞凌开发板OK3588-C上使用Rockchip原厂的SDK跑通I2C扩展GPIO芯片TCA6424ARGJRR

20240629在飞凌开发板OK3588-C上使用Rockchip原厂的SDK跑通I2C扩展GPIO芯片TCA6424ARGJRR 2024/6/29 18:02 1、替换DTS了&#xff1a; Z:\repo_RK3588_Buildroot20240508\kernel\arch\arm64\boot\dts\rockchip viewproviewpro-ThinkBook-16-G5-IRH:~/repo_RK3588_Buildroot2024…

Jedis、Lettuce、RedisTemplate连接中间件

jedis就像jdbc一样&#xff0c;用于两个端直接的连接。 1.创建Spring项目 这里不过多赘述... 2.导入连接工具jedis 在pom文件中导入jedis的依赖。 <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version&…

【雷达原理】雷达测角原理及实现方法

目录 一、雷达测角原理1.1 测角研究历史和现状1.2 测角方法总结1.3 3DFFT测角1.3.1 基本原理1.2.2 测角性能 二、MATLAB仿真案例参考文献 一、雷达测角原理 1.1 测角研究历史和现状 &#xff08;1&#xff09;早期采用窄波束对准目标&#xff0c;目标的角度对应于天线的角度读…

Unity3D 转换微信小游戏指引 01

Unity3D 转换微信小游戏指引系列&#xff08;第一期&#xff09; 搭建环境 安装 WebGL 模块 首先&#xff0c;Unity 要安装WebGL Build Support模块。 在 Hub 找到安装的引擎&#xff0c;点击设置按钮&#xff0c;点击Add modules添加模块。 勾选WebGL Build Support&#…

股指期权交割日期是什么时候?在每个月几号?

今天带你了解股指期权交割日期是什么时候&#xff1f;在每个月几号&#xff1f;期权交割日是指合约到期之日&#xff0c;即投资者需要履行买卖合约的义务。 股指期权的交割日期通常是期权合约到期日的第三个星期五。如果这一天是公共假日&#xff0c;则交割日可能会提前到前一…

检索增强生成RAG系列3--RAG优化之文档处理

在上一章中罗列了对RAG准确度的几个重要关键点&#xff0c;主要包括2方面&#xff0c;这一章就针对其中一方面&#xff0c;来做详细的讲解以及其解决方案。 目录 1 文档解析1.1 文档解析工具1.2 实战经验1.3 代码演示 2 文档分块2.1 分块算法2.2 实战经验2.3 代码演示 3 文档e…

Workerman在线客服系统源码,附搭建教程

源码介绍&#xff1a; Workerman在线客服系统源码。 workerman是一个高性能的PHP socket 服务器框架&#xff0c;workerman基于PHP多进程以及libevent事件轮询库&#xff0c;PHP开发者只要实现一两个接口&#xff0c;便可以开发出自己的网络应用&#xff0c;例如Rpc服务、聊天…

基于Java的会员制医疗预约服务管理信息系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java技术ssm框架&#xff0c;结合JSPM工作流引擎 工具&#xff1a;IDEA/Eclipse、Navicat、Maven …

每日一题——Python实现PAT乙级1090 危险品装箱(举一反三+思想解读+逐步优化)4千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 题目链接&#xff1a;https://pintia.cn/problem-sets/994805260223102976/exam/problems/typ…

2024 vue3入门教程:windows系统下部署node环境

一、打开下载的node官网 Node.js — 下载 Node.js 二、根据个人喜好的下载方法&#xff0c;下载到自己的电脑盘符下 三、我用的是方法3下载的压缩包&#xff0c;解压到E盘nodejs目录下&#xff08;看个人&#xff09; 四、配置电脑的环境变量&#xff0c;新建环境变量的时候…

树莓派4B学习笔记17:RBG_LED全色域灯的驱动模块编写

今日继续学习树莓派4B 4G&#xff1a;&#xff08;Raspberry Pi&#xff0c;简称RPi或RasPi&#xff09; 本人所用树莓派4B 装载的系统与版本如下: 版本可用命令 (lsb_release -a) 查询: ​ Python 版本3.7.3&#xff1a; ​ 今日学习&#xff1a;RBG_LED全色域灯的驱动模块编写…

初学者轻松搞定19个经典的Python程序以及代码演示

Python的经典程序展示了Python语言基本特性和功能的简单示例,这些程序在学习和理解Python编程语言的过程中起着至关重要的作用. 一些常见的经典Python程序及其在学习Python时的功能&#xff1a; 1.Hello, World! print("Hello, World!")解释:这是Python的基本输出…

(单机架设教程)凯旋|当年的QQ游戏

前言 今天给大家带来一款单机游戏的架设&#xff1a;凯旋 &#xff0c; 当年的QQ游戏 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; 凯旋单机 搭建教程 此游戏架设需要安装虚拟机&#xff0c; 没有…

【面试系列】Python 高频面试题

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…