Ionic5手写签名SignaturePad
测试程序下载:https://hanzhe.lanzous.com/itt47kncw3a
初始化项目
1. 首先新建一个Ionic5的项目:
ionic start test-1 blank
2. 安装对应的npm依赖:
npm install angular2-signaturepad --save
3. 依赖安装完成后在app.module.ts
中注册该模块:
// 模块路径
import { SignaturePadModule } from 'angular2-signaturepad';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
// 在imports中进行注册
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, SignaturePadModule],
providers: [
StatusBar,
SplashScreen,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule { }
创建签名页
1. 签名需要屏幕上有足够的空间,我们新建一个Page页面专门用于签名:
ionic g page sign
2. 然后编辑sign.page.html
文件,针对这个页面布局做一些修改(小弟UI功底贼差,这里可以自行发挥)
<ion-content>
<!-- 撑满全屏的DIV,用于测量手机屏幕尺寸 -->
<div #div class="rule"></div>
<!-- 画布 -->
<signature-pad *ngIf="isShowPad" [options]="options" class="sign"></signature-pad>
<!-- 操作按钮 -->
<div class="div-btn">
<ion-button (click)="clear()" class="btn">重 绘</ion-button>
<ion-button (click)="back()" class="btn">返 回</ion-button>
<ion-button (click)="ok()" class="btn">确 认</ion-button>
</div>
</ion-content>
3. 页面的CSS样式:
.rule { // 起到格尺的作用
// 宽高撑满
width: 100%;
height: 100%;
// 透明
opacity: 0;
// 脱离文档流
position: absolute;
top: 0;
left: 0;
// 设置鼠标穿透
pointer-events: none;
// 防止拖拽报错
touch-action: none;
}
.sign { // 画布添加下边框起到分割线作用
border-bottom: 1px solid #eaeaea;
}
.div-btn{ // 底部三个操作按钮居中显示
text-align: center;
}
.btn { // 设置每个按钮的大小、间隔
width: 85px;
height: 40px;
margin: 30px 10px;
}
4. 开始写JS代码(代码都写了注释,就不再解释了):
import { SignaturePad } from 'angular2-signaturepad';
@Component({
selector: 'app-sign',
templateUrl: './sign.page.html',
styleUrls: ['./sign.page.scss'],
})
export class SignPage {
@ViewChild("div")
private div: any; // 尺子DIV对象
@ViewChild(SignaturePad)
private pad: SignaturePad; // 画布
private options: any; // 宽高参数
private isShowPad: boolean; // 是否显示
private otherPage = {that: null, callBack: null}; // 其他页面传来的参数(回调)
constructor(private navCtrl: NavController, private navParam: ActivatedRoute) {
// 设置初始值
this.options = { canvasWidth: 200, canvasHeight: 200 };
this.isShowPad = false;
// 接收传参
this.otherPage.that = navParam.snapshot.queryParams.that;
this.otherPage.callBack = navParam.snapshot.queryParams.callBack;
}
// 页面加载完成在调用初始化方法
ionViewWillEnter() {
this.canvasResize();
}
// 设置画布大小
canvasResize() {
// 获取当前屏幕宽高,留出100高度(下边框有1px)显示操作按钮,
let dom = this.div.nativeElement;
this.options.canvasWidth = dom.offsetWidth;
this.options.canvasHeight = dom.offsetHeight - 99;
// 等待属性设置完成之后再显示画布
this.isShowPad = true;
}
// 清空画布内容
clear() {
this.pad.clear();
}
// 确认按钮
ok() {
// 点击确认后将图片转换为Base64传给回调、然后关闭该页面
this.otherPage.callBack(this.otherPage.that, this.pad.toDataURL());
this.navCtrl.back();
}
// 返回按钮
back() {
this.navCtrl.back();
}
}
首页的调用测试
1. 签名页面已经绘制好了,接下来在Home组件中进行调用,编辑home.page.html
:
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>请输入签名</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<div style="text-align: center;">
<ion-button (click)="openPage()">点击开始签名</ion-button>
<br />
<img [src]="base64" style="border: 1px solid rgb(196, 196, 196); width: 80%;">
</div>
</ion-content>
2. 首页这里就不修改样式了,能用就行,接下来是JS代码:
export class HomePage {
private base64: string = "";
constructor(private navCtrl: NavController) {}
// 打开画布页面
openPage() {
this.navCtrl.navigateForward("sign", {queryParams: {
// 传入当前组件的this指向和回调
that: this,
callBack: this.setBase64
}});
}
// 获取base64图像然后显示在页面上
setBase64(that, base64) {
that.base64 = base64;
}
}
这样最简单的手写签名程序就完成了,运行查看效果:
Base图片旋转
从测试效果上来看,我们已经实现了目标功能,但是客户签字时肯定是横着签的,然后回显到Home页之后显示也会出现问题,如果把画布修改为宽大于高,画布是横过来了,但是局限于手机屏幕大小根本没办法签名,这里我在网上找了一个Base64的图像旋转代码可以使用:
1. 创建Ionic服务:
ionic g service service/util
2. 在服务中添加Base64图片旋转代码(代码来源:https://blog.csdn.net/qq_38082304/article/details/85287718):
export class UtilService {
constructor() { }
rotateBase64Img(src, edg, callback) {
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
var imgW;//图片宽度
var imgH;//图片高度
var size;//canvas初始大小
if (edg % 90 != 0) {
console.error("旋转角度必须是90的倍数!");
throw '旋转角度必须是90的倍数!';
}
(edg < 0) && (edg = (edg % 360) + 360)
const quadrant = (edg / 90) % 4; //旋转象限
const cutCoor = {sx: 0, sy: 0, ex: 0, ey: 0}; //裁剪坐标
var image = new Image();
image.crossOrigin = "anonymous"
image.src = src;
image.onload = function () {
imgW = image.width;
imgH = image.height;
size = imgW > imgH ? imgW : imgH;
canvas.width = size * 2;
canvas.height = size * 2;
switch (quadrant) {
case 0:
cutCoor.sx = size;
cutCoor.sy = size;
cutCoor.ex = size + imgW;
cutCoor.ey = size + imgH;
break;
case 1:
cutCoor.sx = size - imgH;
cutCoor.sy = size;
cutCoor.ex = size;
cutCoor.ey = size + imgW;
break;
case 2:
cutCoor.sx = size - imgW;
cutCoor.sy = size - imgH;
cutCoor.ex = size;
cutCoor.ey = size;
break;
case 3:
cutCoor.sx = size;
cutCoor.sy = size - imgW;
cutCoor.ex = size + imgH;
cutCoor.ey = size + imgW;
break;
}
ctx.translate(size, size);
ctx.rotate(edg * Math.PI / 180);
ctx.drawImage(image, 0, 0);
var imgData = ctx.getImageData(cutCoor.sx, cutCoor.sy, cutCoor.ex, cutCoor.ey);
if (quadrant % 2 == 0) {
canvas.width = imgW;
canvas.height = imgH;
} else {
canvas.width = imgH;
canvas.height = imgW;
}
ctx.putImageData(imgData, 0, 0);
callback(canvas.toDataURL())
};
}
}
3. 然后在Home组件中引入这个服务,在显示图片的回调中将Base进行旋转:
export class HomePage {
// 这里引入刚刚写好的工具类服务
constructor(private navCtrl: NavController, private util: UtilService) {}
// ....省略代码
// 获取base64图像然后旋转270度后显示在页面上
setBase64(that, base64) {
// 第一个参数:Base64字符串
// 第二个参数:旋转角度
// 第三个参数:回调,接收返回的参数就是旋转后的Base64图片字符串
that.util.rotateBase64Img(base64, 270, res=>that.base64 = res);
}
}
这样图片旋转也已经处理好了,再来测试一下:
Ionic5手写签名SignaturePad的更多相关文章
- canvas画布实现手写签名效果
最近项目中涉及到移动端手写签名的功能需求,将实现代码记录于此,供小伙伴们参考指摘哦~ HTML代码: <!--手写区--> <div class="mSign_signMa ...
- uni-app通过canvas实现手写签名
分享一个uni-app实现手写签名的方法 具体代码如下: <template> <view > <view class="title">请在下面 ...
- Blazor组件自做二 : 使用JS隔离制作手写签名组件
Blazor组件自做二 : 使用JS隔离制作手写签名组件 本文相关参考链接 JavaScript 模块中的 JavaScript 隔离 Viewer.js工程 Blazor组件自做一 : 使用JS隔离 ...
- html5手写签名
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta co ...
- 用canvas实现手写签名功能
最近开发网站有一个需求,要求页面上有一块区域,用户能用鼠标在上面写字,并能保存成图片 base64 码放在服务器.这样的需求用 canvas 实现是最好的.需要用到 canvas 的以下几个属性: b ...
- WORD2003电子签名插件(支持手写、签章)
1.引言 WORD电子签名插件,支持手写.本地电子图章.以及网络图章功能.软件使用VC6,以ATL方式编写,软件小巧精致. 这是我学习ATL的成果,学习过程及程序的编写,前前后后共用了一个多月的时间, ...
- android-------手写签名系统的设计与实现之实现画笔设置
引自:http://www.xuebuyuan.com/1754358.html 既然我们实现了画布和画笔,也实现了手写,为了提高可用性,我们增加了对画笔风格的设置功能,这样就可以根据自己的需要选择画 ...
- Atitit s2018.2 s2 doc list on home ntpc.docx \Atiitt uke制度体系 法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别 讯飞科大 语音云.docx \Atitit 代码托管与虚拟主机.docx \Atitit 企业文化 每日心灵 鸡汤 值班 发布.docx \Atitit 几大研发体系对比 Stage-Gat
Atitit s2018.2 s2 doc list on home ntpc.docx \Atiitt uke制度体系 法律 法规 规章 条例 国王诏书.docx \Atiitt 手写文字识别 ...
- React深入 - 手写redux api
简介: 手写实现redux基础api createStore( )和store相关方法 api回顾: createStore(reducer, [preloadedState], enhancer) ...
随机推荐
- javaMail (java代码发送邮件)
第一在邮件账户设置开启以下两个 需要发送短信获取 授权码. 代码如下: package com.hjb.javaMail; import javax.mail.*; import javax.mai ...
- spring boot的 yml和properties的对比
Spring Boot 虽然做了大量的工作来简化配置,但其配置依然是相当的复杂!支持的外部配置方式就有很多种,笔者没有去统计,也许是为了灵活使用吧. application.yml 和 appli ...
- HashSet为什么可以有序输出?
首先HashSet是不保证有序,而不是保证无序,因为在HashSet中,元素是按照他们的hashCode值排序存储的.对于单个字符而言,这些hashCode就是ASCII码,因此,当按顺序添加自然数或 ...
- 基于docker快速搭建hbase集群
一.概述 HBase是一个分布式的.面向列的开源数据库,该技术来源于 Fay Chang 所撰写的Google论文"Bigtable:一个结构化数据的分布式存储系统".就像Bigt ...
- POJ-2387(原始dijkstra求最短路)
Til the Cows Come Home POJ-2387 这题是最简单的最短路求解题,主要就是使用dijkstra算法,时间复杂度是\(O(n^2)\). 需要注意的是,一定要看清楚题目的输入要 ...
- [源码分析] 消息队列 Kombu 之 启动过程
[源码分析] 消息队列 Kombu 之 启动过程 0x00 摘要 本系列我们介绍消息队列 Kombu.Kombu 的定位是一个兼容 AMQP 协议的消息队列抽象.通过本文,大家可以了解 Kombu 是 ...
- 【老孟Flutter】Flutter 2.0 重磅更新
老孟导读:昨天期待已久的 Flutter 2.0 终于发布了,Web 端终于提正了,春季期间我发布的一篇文章,其中的一个预测就是 Web 正式发布,已经实现了,还有一个预测是:2021年将是 Flut ...
- 初窥MyBatis-普通的CRUD操作
编写接口 编写对应的Mapper.xml中的sql语句 测试(增删改需要提交事务) <mapper namespace="com.perwrj.dao.UserMapper" ...
- Codeforces Round #699 (Div. 2)
A Space Navigation #include <bits/stdc++.h> using namespace std; typedef long long LL; #define ...
- 【Azure Developer】Python 获取Micrisoft Graph API资源的Access Token, 并调用Microsoft Graph API servicePrincipals接口获取应用ID
问题描述 在Azure开发中,我们时常面临获取Authorization问题,需要使用代码获取到Access Token后,在调用对应的API,如servicePrincipals接口. 如果是直接调 ...