鸿蒙ArkTS开始实例:【canvas实现签名板功能】

news2025/1/24 22:41:09

使用ArkTS中的canvas实现签名板的功能,canvas画布大家都很熟悉,我们会用它经常实现一些画板或者图表、表格之类的功能。canvas签名板是我在开发APP过程中实现的一个功能,开发过程中也是遇到比较多的问题。我会按照以下几点来讲解开发整个过程:

一、屏幕旋转

实现签名板的第一个功能就是旋转屏幕。旋转屏幕在各种框架中都有不一样的方式,比如:

  • 在H5端,我们一般是使用CSS中的transform属性中的rotate()方法来强制将网页横屏,然后实现一系列功能
  • 在嵌套第三方APP中,我们一般是调用对应的SDK提供的方法,即可实现旋转屏幕
  • .....

实现方式还有很多,各有千秋,相信HarmonyOS也会提供对应API方法来设置旋转屏幕。

而我自己则是在页面内通过 Window 对象的 setPreferredOrientation() 方法实现横竖屏切换。以下是我实现的完整代码:

// 在EntryAbility.ts中获取窗口实例并赋值给全局变量,如此所有页面都可以通过全局// 变量去修改窗口信息,不需要重新获取
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
  onWindowStageCreate(windowStage: window.WindowStage) {
    windowStage.getMainWindow((err, data) => {
      if (err.code) {
        console.error('获取失败' + JSON.stringify(err));
        return;
      }
      console.info('获取主窗口的实例:' + JSON.stringify(data));
      globalThis.windowClass = data // 赋值给全局变量windowClass
    });
  }
}

// 在具体页面中的使用
import window from '@ohos.window';
@Entry
@Componentstruct SignatureBoard {

  onPageShow() {
// 获取旋转的方向,具体可以查看对应文档
    let orientation = window.Orientation.LANDSCAPE_INVERTED;
    try {
      // 设置屏幕旋转
      globalThis.windowClass.setPreferredOrientation(orientation, (err) => {});
    } catch (exception) {
      console.error('设置失败: ' + JSON.stringify(exception));
    }
  }
}

此次开发文档参考qr23.cn/AKFP8k

搜狗高速浏览器截图20240326151547.png

二、canvas画布

解决了屏幕旋转问题,接下来实现签名功能。因为在之前就已经开发过,只要将对应的语法转成ArkTS的语法就好。以下是代码解析:

2.1 按照官方文档使用canvas组件

@Entry@Component
struct SignatureBoard {
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#fff')
        .onReady(() => {
        })
    }
    .width('100%')
    .height('100%')
  }
}

2.2 设置画笔的属性以及绑定手势功能。

在js中我们基本都是使用鼠标事件来实现的,而在ArkTS中是通过手势方法来监听手指在屏幕上的操作,有很多种,大家需要用到的可以去查看对应的文档。

build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#fff')
        .onReady(() => {
          this.context.lineWidth = 3; // 设置画笔的粗细
          this.context.strokeStyle = "#000"; // 设置画笔的颜色
          // 还可以设置很多,根据自己业务需要
        })
        .gesture(
          PanGesture(this.panOption)
            .onActionStart((event: any) => {
               // 手指按下的时候
            })
            .onActionUpdate((event: any) => {
               // 手指移动的时候
            })
            .onActionEnd(() => {
               // 手指离开的时候
            })
        )
  }

2.3 我们实现的手势的绑定,那么就可以实现手指在屏幕上滑动之后画布就绘画出对应的轨迹路线了,这里将会使用到一些画布的功能。

@Entry
@Componentstruct SignatureBoard {
  private lastX: number = 0;
  private lastY: number = 0;
  private isDown: Boolean = false;
  private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.All, distance: 1 })
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  draw(startX, startY, endX, endY) {
    // 起点
    this.context.moveTo(startX, startY);
    // 终点
    this.context.lineTo(endX, endY);
    // 调用 stroke,即可看到绘制的线条
    this.context.stroke();
  }
  build() {
    Column() {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .backgroundColor('#fff')
        .onReady(() => {
          this.context.lineWidth = 3;
          this.context.strokeStyle = "#000";
        })
        .gesture(
          PanGesture(this.panOption)
            .onActionStart((event: any) => {
              this.isDown = true;
              // 按下时的点作为起点
              this.lastX = event.localX;
              this.lastY = event.localY;
              // 创建一个新的路径
              this.context.beginPath();
            })
            .onActionUpdate((event: any) => {
              // 没有按下就不管
              if (!this.isDown) return;
              const offsetX = event.localX
              const offsetY = event.localY
              // 调用绘制方法
              this.draw(this.lastX, this.lastY, offsetX, offsetY);
              // 把当前移动时的坐标作为下一次的绘制路径的起点
              this.lastX = offsetX;
              this.lastY = offsetY;
            })
            .onActionEnd(() => {
              this.isDown = false;
              // 关闭路径
              this.context.closePath();
            })
        )
    }
    .width('100%')
    .height('100%')
  }
}

以上就是我们实现签名板的完整思路以及代码了,有几个需要注意的点是:

  1. new PanGestureOptions实例的时候需要把distance设置小一点,值越小灵敏度就越高

  2. PanGesture的回调方法中event参数,官方默认给的属性类型为GestureEvent。但是我在编辑器源码中查看该属性没有我们定义我们想要的localX、localY,但是实际是有返回的,如果直接用编辑器会报错。所以需要将event定为any类型,这样就可以获取且不报错了。

鸿蒙Next核心技术分享

1、鸿蒙基础知识←《鸿蒙NEXT星河版开发学习文档》

2、鸿蒙ArkUI←《鸿蒙NEXT星河版开发学习文档》

3、鸿蒙进阶技术←《鸿蒙NEXT星河版开发学习文档》

 4、鸿蒙就业高级技能←《鸿蒙NEXT星河版开发学习文档》 

 5、鸿蒙多媒体技术←《鸿蒙NEXT星河版开发学习文档》 

6、鸿蒙南向驱动开发←《鸿蒙NEXT星河版开发学习文档》  

7、鸿蒙南向内核设备开发←《鸿蒙NEXT星河版开发学习文档》  

 8、鸿蒙系统裁剪与移植←《鸿蒙NEXT星河版开发学习文档》  

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

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

相关文章

npm版本切换工具nvm

有了nvm,可以在一台机器上同时安装多个版本的nodejs,然后指定使用某个版本。 前端开发的时候,安装依赖一直是个令我头痛的问题。总是报错,或者不是少了这样就是少了那样,鸡飞狗走。以往,一般要装个enpm&am…

HCIA-Datacom H12-811 题库补充(4/7)

完整题库及答案解析,请直接扫描上方二维码,持续更新中 共享介质型网络使用哪一种技术进行数据转发? A:CDMA/CD B:CSMA/AC C:TDMA/CD D:CSMA/CD 答案:D 解析:以太网 CSMA …

SQL Server语法基础:入门到精通

博客前言 在数据库管理的世界中,SQL Server无疑是一个重要的角色。无论是初学者还是经验丰富的数据库管理员,都需要对SQL Server的查询语法有深入的理解。本文将带领大家深入解析SQL Server的查询语法,并分享一些实用的技巧,帮助…

OpenAI 推出新网络爬虫GPTBot,为GPT-5做准备

目录 一、GPTBot是什么?它是如何工作的?二、GPTBot 与 Google Bot 等搜索引擎网络爬虫有何不同?三、GPTBot 与 Perplexity AI 的网络爬虫有何不同?四、允许 GPTBot 爬取有哪些风险和好处?4.1 允许 GPTBot 的好处4.2 允…

麒麟系统ARM安装rabbitmq

简单记录下,信创服务器:麒麟系统,安装rabbitmq的踩坑记录。 本文章参考了很多大佬文章,我整理后提供。 一、安装基础依赖 yum -y install make gcc gcc-c kernel-devel m4 ncurses-devel openssl-devel unixODBC-devel 二、下载…

手机如何在线制作gif?轻松一键在线操作

现在大家都喜欢使用手机来拍摄记录有趣的事物,但是时间长了手机里的视频越来越多导致手机存储空间不够了,这些视频又不想删除时应该怎么办呢?这个很简单,下面就给大家分享一款不用下载手机就能操作的视频转gif网站-GIF中文网&…

四大生成式模型的比较——GAN、VAE、归一化流和扩散模型

比较四大模型的本质 four modern deep generative models: generative adversarial networks, variational autoencoders, normalizing flows, and diffusion models 待写

经典文章:卷积神经网络的运作原理

https://brohrer.mcknote.com/zh-Hans/how_machine_learning_works/how_convolutional_neural_networks_work.html 参考资料 https://aitechtogether.com/article/38900.html https://www.ruanyifeng.com/blog/2017/07/neural-network.html http://neuralnetworksanddeeplea…

drawio画图编辑图形颜色

drawio画图编辑图形颜色 团队的安全第一图表。将您的存储空间带到我们的在线工具中,或使用桌面应用程序进行本地保存。 1.安装准备 1.1安装平台 多平台 1.2在线使用 浏览器打开网页使用 1.3软件下载 drawio官网github仓库下载 2.在浏览器的网页中使用drawio…

遥感影像处理利器:PyTorch框架下CNN-Transformer,地物分类、目标检测、语义分割和点云分类

目录 专题一 深度卷积网络知识详解 专题二 PyTorch应用与实践(遥感图像场景分类) 专题三 卷积神经网络实践与目标检测 专题四 卷积神经网络的遥感影像目标检测任务案例【FasterRCNN】 专题五 Transformer与遥感影像目标检测 专题六 Transformer的遥…

升级xcode15 报错Error (Xcode): Cycle inside Runner

升级xcode15后报错 Could not build the precompiled application for the device. Error (Xcode): Cycle inside Runner; building could produce unreliable results. This usually can be resolved by moving the shell script phase Thin Binary so that it runs before th…

Java(JDBC)

一、DriverManager 注册驱动 Class.forName("com.mysql.jdbc.Driver"); 获取连接 static Connection connection null; connection DriverManager.getConnection(url, user, password); 1.ur:连接路径 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数…

配置vscode用于STM32编译,Debug

配置环境参考: Docs 用cubemx配置工程文件,用VScode打开工程文件。 编译的时候会有如下报错: vscode出现process_begin :CreateProcess failed 系统找不到指定文件 解决方案:在你的makefile中加上SHELLcmd.exe就可以了 参考…

汇编——SSE打包整数

SSE也可以进行整数向量的加法,示例如下: ;sse_integer.asm extern printfsection .datadummy db 13 align 16pdivector1 dd 1dd 2dd 3dd 4pdivector2 dd 5dd 6dd 7dd 8fmt1 db "Packed Integer Vector 1: %d, %d, %d, %d",…

6_6_SQL

//名词 Candidate key:若表中记录的某一字段或字段组合能够唯一标志记录,则称该字段或字段组合为候选关键字 Primary key:若一个表有多个候选关键字,则选定其中一个为主关键字,也称为主键 Foreignkey:若某字段或字段组合不是数据库中A表的关键…

【大数据】安装hive-3.1.2

1、上传HIVE包到/opt/software目录并解压到/opt/modules/ tar -zxvf apache-hive-3.1.2-bin.tar.gz -C /opt/modules/ 2、修改路径 mv /opt/modules/apache-hive-3.1.2-bin/ /opt/modules/hive 3、将hIVE下的bin目录加入到/etc/profile中 export HIVE_HOME/opt/module…

大数据学习第十三天(mysql不会的查询2)

1、数据 CREATE TABLE Student (s_id VARCHAR(20) COMMENT 学生编号,s_name VARCHAR(20) NOT NULL DEFAULT COMMENT 学生姓名,s_birth VARCHAR(20) NOT NULL DEFAULT COMMENT 出生年月,s_sex VARCHAR(10) NOT NULL DEFAULT COMMENT 学生性别,PRIMARY KEY (s_id) ) ENG…

激光雷达和相机的联合标定工具箱[cam_lidar_calibration]介绍

激光雷达和相机的联合标定工具箱[cam_lidar_calibration]介绍 写在前面安装过程调试过程标定成功可视化展示 写在前面 激光雷达和相机联合标定工具 论文地址:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber9564700 github地址: https://github.com…

模块十 面向对象

模块十 重点 知道继承的好处会使用继承知道继承之后成员变量以及成员方法的访问特点会方法重写以及知道方法重写的使用场景会使用 this 关键字调用当前对象中的成员会使用super关键字调用父类中的成员会定义抽象类方法以及抽象类会重写抽象方法 第一章 继承 1.1 什么是继承 …

simulink 的stm32 ADC模块输出在抽筋,不知为何

% outtypecast(uint16(1000),uint8) % 10003E8,E8232,out232 3 function [y,len] myfcn(u1) headuint8([255 85]);%帧头 out1typecast(uint16(u1),uint8); % out2typecast(uint16(u2),uint8); y[head,out1]; lenuint16(length(y)); 2023b版本,stm32硬件支持…