当前位置: 首页 > news >正文

鸿蒙系统(HarmonyOS)应用开发之实现电子签名效果

项目概述

DevEco 电子签名应用是一款专为移动设备设计的高效电子签名解决方案,基于 OpenHarmony 平台开发。该应用旨在满足日益增长的电子签名需求,为用户提供便捷、安全且具有法律效力的电子签名功能。在数字化转型的时代背景下,我们的应用致力于简化签名流程,提高工作效率,减少纸质文档的使用,为绿色环保贡献力量。

通过直观的用户界面和流畅的操作体验,DevEco 电子签名应用让用户能够随时随地完成签名任务,无需打印文件或亲自到场。无论是商务合同、法律文件还是日常文档,我们的应用都能提供专业的签名解决方案。

功能特点

核心功能

  • 精准手写签名:采用先进的触控算法,确保签名流畅自然,完美还原用户的笔迹特点
  • 多样化绘制选项
  • 四种标准颜色选择(黑色、红色、蓝色、绿色)
  • 可调节的线条粗细(1-10 级调节)
  • 圆润的线条连接,提供专业签名效果
  • 操作管理功能
  • 一键清除画布,快速重新开始
  • 撤销功能,方便纠正误操作
  • 即时保存签名,防止工作丢失

用户体验优势

  • 简洁直观的界面设计:遵循现代 UI 设计原则,界面清晰易懂
  • 响应式布局:自适应不同屏幕尺寸,提供一致的用户体验
  • 操作反馈:通过 Toast 提示等方式,提供及时的操作反馈
  • 轻量级应用:占用资源少,运行流畅,适合各种设备

技术架构

开发框架

  • 基于 OpenHarmony 的 ArkTS/ETS 语言开发
  • 采用声明式 UI 编程范式,提高开发效率和代码可维护性

核心技术

  • Canvas 绘图技术:利用 CanvasRenderingContext2D 实现高精度绘图
  • 触控事件处理:精确捕捉并处理多点触控事件
  • 状态管理:使用@State 装饰器进行组件状态管理
  • 离屏渲染:通过 OffscreenCanvas 技术实现高效图像处理和导出

应用场景

  • 合同签署:远程签署商业合同、协议和备忘录
  • 报价确认:快速确认商业报价和订单
  • 会议纪要:为会议纪要和决议添加签名确认
  • 法律文件:签署法律文件和声明
  • 公证材料:为需要公证的材料添加电子签名
  • 授权确认:提供授权确认的电子签名
  • 快递签收:替代传统的纸质签收单
  • 考勤签到:用于员工考勤或活动签到
  • 个人认证:在各类需要身份确认的场景中使用

完整源码

import promptAction from '@ohos.promptAction';
import image from '@ohos.multimedia.image';
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
import router from '@ohos.router';// 定义点的接口
interface Point {x: number;y: number;
}// 定义路径的接口
interface PathData {path: Point[];color: string;width: number;
}@Entry
@Component
struct SignaturePage {// Canvas相关状态@State canvasWidth: number = 0;@State canvasHeight: number = 0;@State isDrawing: boolean = false;@State lineColor: string = '#000000';@State lineWidth: number = 3;@State lastX: number = 0;@State lastY: number = 0;// 用于保存绘制历史,支持撤销功能@State drawHistory: PathData[] = [];@State currentPath: Point[] = [];// 画布上下文private settings: RenderingContextSettings = new RenderingContextSettings(true);private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);// 获取应用上下文,用于保存图片private context16: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);private appContext: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;aboutToAppear() {// 页面加载时的初始化操作}// 开始绘制startDrawing(event: TouchEvent) {this.isDrawing = true;this.lastX = event.touches[0].x;this.lastY = event.touches[0].y;// 开始新路径this.context.beginPath();this.context.moveTo(this.lastX, this.lastY);// 记录当前路径的起点this.currentPath = [{ x: this.lastX, y: this.lastY }];}// 绘制中drawing(event: TouchEvent) {if (!this.isDrawing) {return;}const currentX = event.touches[0].x;const currentY = event.touches[0].y;// 绘制线条this.context.lineWidth = this.lineWidth;this.context.strokeStyle = this.lineColor;this.context.lineJoin = 'round';this.context.lineCap = 'round';this.context.lineTo(currentX, currentY);this.context.stroke();// 更新最后位置this.lastX = currentX;this.lastY = currentY;// 记录当前路径点this.currentPath.push({ x: currentX, y: currentY });}// 结束绘制endDrawing() {if (!this.isDrawing) {return;}this.isDrawing = false;// 保存当前路径到历史记录if (this.currentPath.length > 1) {this.drawHistory.push({path: [...this.currentPath],color: this.lineColor,width: this.lineWidth});}this.currentPath = [];}// 清除画布clearCanvas() {this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);this.drawHistory = [];this.currentPath = [];}// 撤销上一步undo() {if (this.drawHistory.length === 0) {promptAction.showToast({message: '没有可撤销的操作',duration: 2000});return;}// 移除最后一个路径this.drawHistory.pop();// 重新绘制所有路径this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);for (let item of this.drawHistory) {this.context.beginPath();this.context.lineWidth = item.width;this.context.strokeStyle = item.color;this.context.lineJoin = 'round';this.context.lineCap = 'round';if (item.path.length > 0) {this.context.moveTo(item.path[0].x, item.path[0].y);for (let i = 1; i < item.path.length; i++) {this.context.lineTo(item.path[i].x, item.path[i].y);}this.context.stroke();}}}// 保存签名async saveSignature() {try {// 创建离屏Canvaslet offscreenCanvas = new OffscreenCanvas(this.canvasWidth, this.canvasHeight);let offContext = offscreenCanvas.getContext("2d");// 将当前画布内容绘制到离屏CanvasoffContext.fillStyle = '#FFFFFF';offContext.fillRect(0, 0, this.canvasWidth, this.canvasHeight);// 重新绘制所有路径到离屏Canvasfor (let item of this.drawHistory) {offContext.beginPath();offContext.lineWidth = item.width;offContext.strokeStyle = item.color;offContext.lineJoin = 'round';offContext.lineCap = 'round';if (item.path.length > 0) {offContext.moveTo(item.path[0].x, item.path[0].y);for (let i = 1; i < item.path.length; i++) {offContext.lineTo(item.path[i].x, item.path[i].y);}offContext.stroke();}}// 转换为图片 - 使用transferToImageBitmap替代toDataURLlet imageBitmap = offscreenCanvas.transferToImageBitmap();// 显示成功消息promptAction.showToast({message: '签名已保存',duration: 2000});return imageBitmap;} catch (error) {console.error('保存签名失败:', error);promptAction.showToast({message: '保存签名失败',duration: 2000});return null;}}build() {Column() {// 标题栏Row() {Text('电子签名').fontSize(20).fontWeight(FontWeight.Medium).margin({ left: 16 })Blank()Button('保存').fontSize(16).height(36).backgroundColor('#007DFF').borderRadius(18).onClick(() => {this.saveSignature();})}.width('100%').height(56).padding({ left: 16, right: 16 }).backgroundColor('#FFFFFF')// 签名区域Column() {Text('请在下方区域签名').fontSize(16).fontColor('#666666').margin({ top: 20, bottom: 10 })// 签名画布Canvas(this.context).width('100%').layoutWeight(4) // 增加Canvas的权重,给予更多空间.backgroundColor('#F5F5F5').borderRadius(8).margin({ bottom: 16 }) // 添加底部间距.onAreaChange((oldArea: Area, newArea: Area) => {// 使用新区域的尺寸this.canvasWidth = newArea.width as number;this.canvasHeight = newArea.height as number;}).onReady(() => {// Canvas准备就绪}).onTouch((event: TouchEvent) => {if (event.type === TouchType.Down) {this.startDrawing(event);} else if (event.type === TouchType.Move) {this.drawing(event);} else if (event.type === TouchType.Up) {this.endDrawing();}})// 工具栏容器Column() {// 按钮和颜色选择器行Row() {Button('清除').fontSize(16).height(40).backgroundColor('#F5F5F5').fontColor('#333333').borderRadius(20).onClick(() => {this.clearCanvas();})Button('撤销').fontSize(16).height(40).backgroundColor('#F5F5F5').fontColor('#333333').borderRadius(20).margin({ left: 16 }).onClick(() => {this.undo();})Blank()// 颜色选择器Row() {ForEach(['#000000', '#FF0000', '#0000FF', '#008000'], (color: string) => {Column() {Circle({ width: 24, height: 24 }).fill(color).stroke(this.lineColor === color ? '#007DFF' : 'transparent').strokeWidth(2).margin(4).onClick(() => {this.lineColor = color;})}})}}.width('100%').height(48).margin({ top: 16 })// 线宽选择器行Row() {Text('线条粗细:').fontSize(16).fontColor('#666666')Slider({value: this.lineWidth,min: 1,max: 10,step: 1,style: SliderStyle.OutSet}).width('60%').onChange((value: number) => {this.lineWidth = value;})Text(this.lineWidth.toFixed(0)).fontSize(16).fontColor('#666666').width(24).textAlign(TextAlign.Center)}.width('100%').height(48).margin({ top: 8 })}.width('100%').layoutWeight(1).padding({ left: 16, right: 16 })}.width('100%').padding(16).backgroundColor('#FFFFFF').layoutWeight(1) // 使用layoutWeight而不是固定高度}.width('100%').height('100%').backgroundColor('#F5F5F5')}
}

鸿蒙系统(HarmonyOS)应用开发之实现手工签名效果 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

http://www.dtcms.com/a/264167.html

相关文章:

  • jQuery EasyUI 安装使用教程
  • 苹果AR/VR头显路线图曝光,微美全息推进AI/AR智能眼镜新品开启视觉体验篇章
  • 视频断点续播全栈实现:基于HTML5前端与Spring Boot后端
  • C++编程语言:标准库:STL算法(Bjarne Stroustrup)
  • Python学习Day48
  • 3.1.1.9 安全基线检查项目九:检查是否设置限制su命令用户组
  • 微软服务器安全问题
  • 代码随想录day21二叉树8
  • 可信数据空间:概念、架构与应用实践
  • kafka自定义分区器
  • Webpack的插件机制Tapable
  • 华为认证二选一:物联网 VS 人工智能,你的赛道在哪里?
  • 打造 AI 产品的前端架构:响应式、流式、智能交互三合一
  • uv介绍以及与anaconda/venv的区别
  • C#系统学习第七章——数组
  • python 继承
  • 《UE5_C++多人TPS完整教程》学习笔记39 ——《P40 远程过程调用(Remote Procedure Calls)》
  • 增材制造研究领域:3D 打印设计国际会议
  • 责任链模式 Go 语言实战
  • 电脑系统重装有什么用?
  • 动手实践:如何提取Python代码中的字符串变量的值
  • AI问答-vue3:如何选择使用reactive或ref
  • 【HarmonyOS】鸿蒙使用仓颉编程入门
  • 基于Halcon平台的常规OCR与深度OCR性能对比分析
  • 设计模式(行为型)-访问者模式
  • python训练day46 通道注意力
  • 【kernel8】spi协议,验证,模型,设备树处理,spidev,衍生协议
  • AI人工客服实战指南:基于大模型构建生产级智能对话系统
  • Hadoop、Spark、Flink 三大大数据处理框架的能力与应用场景
  • ESP32-S3开发板深度评测:AI语音识别与图像处理全面解析