html手写板
js版本
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head> <body>
<div id="app">
<div class="sign-page">
<div class="canvas-box">
<div class="canvas" ontouchstart="methods.canvasTouchEvent(event,'canvasStart')"
ontouchmove="methods.canvasTouchEvent(event,'canvasMove')"
ontouchend="methods.canvasTouchEvent(event,'canvasEnd')">
<div class="title">请在该区域内工整书写您的签名</div>
</div>
</div>
<p class="clearCanvas" onclick="methods.saveOrClear('clear')">清 除</p>
<p class="saveCanvas" onclick="methods.saveOrClear('save')">保 存</p>
</div>
</div>
<script> const temp = {
canvas: null, // 画布el对象
cxt: null, // 上下文
stageInfo: null, // 返回canvas的大小及位置
isSign: false //未签名提示
} const data = new Proxy(temp, {
set(target, property, value, receiver) {
if (property === 'isSign') {
console.log(value);
document.querySelector('.title').style.display = value ? 'none' : 'block'
}
return Reflect.set(target, property, value); },
get(target, key) {
return Reflect.get(target, key);
},
}) const methods = {
/*
* 画布初始化事件
*/
initCanvas(obj) {
data.canvas = document.createElement('canvas'); // 指定canvas
obj.el.appendChild(data.canvas);
data.cxt = data.canvas.getContext('2d'); // 设置2D渲染区域
data.canvas.width = obj.el.clientWidth;
data.canvas.height = obj.el.clientHeight;
data.cxt.fillStyle = '#ffffff';
data.cxt.strokeStyle = '#000000';
data.cxt.fillRect(0, 0, data.canvas.width, data.canvas.width);
data.cxt.lineWidth = 2; // 设置线的宽度
data.cxt.lineCap = 'round';
data.stageInfo = data.canvas.getBoundingClientRect();
},
/*
* 画布touch相关事件处理
*/
canvasTouchEvent(e, type) {
const cxt = data.cxt;
const postion = [e.changedTouches[0].pageX - data.stageInfo.left, e.changedTouches[0].pageY - data.stageInfo.top]
const handle = {
canvasStart: () => {
cxt.beginPath();
cxt.moveTo(...postion);
},
canvasMove: () => {
if (!e && !e.preventDefault) return;
e.preventDefault();
cxt.lineTo(...postion);
cxt.stroke();
data.isSign = true;
},
canvasEnd: () => cxt.closePath
}
handle[type]();
}, /*
* 清除和保存事件
*/
saveOrClear(type) {
if (type === 'clear') {
data.cxt.clearRect(0, 0, data.canvas.width, data.canvas.height);
data.isSign = false;
return false;
} if (data.isSign) {
const imgBase64 = data.canvas.toDataURL();
console.log(imgBase64);
} else {
data.$dialog.alert({ title: '错误', message: '请绘制签名', messageAlign: 'center' });
}
}
} const p = new Proxy(data, {
set(target, property, value, receiver) {
console.log(key);
if (property === 'isSign') {
console.log('isSign');
}
return Reflect.set(target, key, value); }
}) setTimeout(() => {
methods.initCanvas({ el: document.querySelector('.canvas') });
}) </script>
<style>
.canvas-box {
width: calc(100% - 68px);
height: calc(100% - 180px);
margin-bottom: 38px;
position: relative;
border-radius: 6px;
background: #fff;
padding: 34px; } .canvas {
background: #fff;
height: 100%;
width: 100%;
border: 1px dashed #848588;
position: relative;
border-radius: 6px;
} .saveCanvas,
.clearCanvas {
padding: 10px 0;
background: rgba(207, 225, 245, 1);
width: 45%;
text-align: center;
float: left;
color: #3F8EE8;
} .saveCanvas {
margin-left: 10%;
} .sign-page {
background: #EDF1F6;
width: calc(100% - 60px);
height: calc(100% - 96px);
padding: 58px 30px 38px;
position: fixed;
top: 0;
left: 0;
} .title {
text-orientation: mixed;
font-size: 18px;
color: #A0ACBF;
position: absolute;
padding: 10%;
top: 0;
left: 0;
}
</style>
</body> </html>
vue版
<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head> <body>
<div id="app">
<div class="sign-page">
<div class="canvas-box">
<div class="canvas" ref="canvas" @touchstart="canvasTouchEvent($event,'canvasStart')"
@touchmove="canvasTouchEvent($event,'canvasMove')" @touchend="canvasTouchEvent($event,'canvasEnd')">
<div class="title" v-if="!isSign">请在该区域内工整书写您的签名</div>
</div>
</div>
<p class="clearCanvas" @click="saveOrClear('clear')">清 除</p>
<p class="saveCanvas" @click="saveOrClear('save')">保 存</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script> const app = new Vue({
el: '#app',
data: {
canvas: null, // 画布el对象
cxt: null, // 上下文
stageInfo: null, // 返回canvas的大小及位置
isSign: false //未签名提示
},
methods: {
/*
* 画布初始化事件
*/
initCanvas(obj) {
this.canvas = document.createElement('canvas'); // 指定canvas
obj.el.appendChild(this.canvas);
this.cxt = this.canvas.getContext('2d'); // 设置2D渲染区域
this.canvas.width = obj.el.clientWidth;
this.canvas.height = obj.el.clientHeight;
this.cxt.fillStyle = '#ffffff';
this.cxt.strokeStyle = '#000000';
this.cxt.fillRect(0, 0, this.canvas.width, this.canvas.width);
this.cxt.lineWidth = 2; // 设置线的宽度
this.cxt.lineCap = 'round';
this.stageInfo = this.canvas.getBoundingClientRect();
},
/*
* 画布touch相关事件处理
*/
canvasTouchEvent(e, type) {
const cxt = this.cxt;
const postion = [e.changedTouches[0].pageX - this.stageInfo.left, e.changedTouches[0].pageY - this.stageInfo.top]
const handle = {
canvasStart: () => {
cxt.beginPath();
cxt.moveTo(...postion);
},
canvasMove: () => {
if (!e && !e.preventDefault) return;
e.preventDefault();
cxt.lineTo(...postion);
cxt.stroke();
this.isSign = true;
},
canvasEnd: () => cxt.closePath
}
handle[type]();
}, /*
* 清除和保存事件
*/
saveOrClear(type) {
if (type === 'clear') {
this.cxt.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.isSign = false;
return false;
} if (this.isSign) {
const imgBase64 = this.canvas.toDataURL();
console.log(imgBase64);
} else {
this.$dialog.alert({ title: '错误', message: '请绘制签名', messageAlign: 'center' });
}
}
},
mounted() {
setTimeout(() => {
this.initCanvas({ el: this.$refs.canvas });
})
}
})
</script>
<style>
.canvas-box {
width: calc(100% - 68px);
height: calc(100% - 180px);
margin-bottom: 38px;
position: relative;
border-radius: 6px;
background: #fff;
padding: 34px; } .canvas {
background: #fff;
height: 100%;
width: 100%;
border: 1px dashed #848588;
position: relative;
border-radius: 6px;
} .saveCanvas,
.clearCanvas {
padding: 10px 0;
background: rgba(207, 225, 245, 1);
width: 45%;
text-align: center;
float: left;
color: #3F8EE8;
} .saveCanvas {
margin-left: 10%;
} .sign-page {
background: #EDF1F6;
width: calc(100% - 60px);
height: calc(100% - 96px);
padding: 58px 30px 38px;
position: fixed;
top: 0;
left: 0;
} .title {
text-orientation: mixed;
font-size: 18px;
color: #A0ACBF;
position: absolute;
padding: 10%;
top: 0;
left: 0;
}
</style>
</body> </html>
效果图

html手写板的更多相关文章
- Python3使用PyQt5制作简单的画板/手写板
0.目录 1.前言 2.简单的画板1.0 在定点和移动中的鼠标所在处画一条线 3.简单的画板2.0 在定点和移动中的鼠标所在处画一条线 并将画过的线都保留在窗体上 4.简单的画板3.0 将按住鼠标后移 ...
- 【微信小程序canvas】实现小程序手写板用户签名(附代码)
工作中公司业务需要的微信小程序用户签字功能 先看效果图: wxml: <view class="wrapper"> <view class="handB ...
- h5简易手写板
............. 我该说点什么呢,开头居然不知道想说点什么!好吧不知道说什么,我们就来说说这个手写板吧,虽然这个手写板现在没什么用,但是.....,好像的确没什么用啊! 只是存粹哪里练手的的 ...
- Android 实现手写板技术
Android手写板和涂鸦的功能,代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/andro ...
- 在 浏览器中调用外接设备— —手写板 【win10 x64 手动注册ocx控件的方法】
PPAXSignToolSDK.ocx 浏览器下使用手写板时调用的控件,使用前必须先注册,,不然浏览器下版本无法正常工作. ocx 控件在安装包运行时会自动注册,如果安装包没有注册成功,需要进行手动注 ...
- 吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货
吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货 摘要: 目前,AI技术做出的经济贡献几乎都来自监督学习,也就是学习从A到B,从输入到输出的映射.现在,监督学习.迁移学习.非监督学习. ...
- C# Winform 中如何获取本机安装输入法,并设置为默认输出语言,如何打开搜狗输入法和手写板
一.问题: 今天,我整理了一下两个问题 1.如何获取本机安装所有输入法,并设置为系统输出语言 2.如何打开搜狗拼音输入法工具栏和手写板: 二.解决方法 比如:我们要设置搜狗输入法为本机输入语言,要怎么 ...
- C# ASP.NET 手写板并生成图片保存
前端: @{ Layout = null; } <!DOCTYPE html> <html lang="zh-CN"> <head> <t ...
- myScript调研,电子手写板使用,纯干货
第二天进公司,就叫我调研myScript作为手写板的可行性,又不能不做,哎~ myScript效果十分的奈斯,前端用canvas手写的文字.数学字符,都可以识别然后转换,不知道myScript是不是你 ...
- 基于myscript.js的web手写板(支持中文识别)
网上的手写板模板不少,但是支持中文识别的却不多,而且基本上都收费的,毕竟别人的中文库凭什么免费提供给你(说好的开源呢?说好的开源呢? ←_←) 好了,进入主题,myscript.js,在官网其实我并没 ...
随机推荐
- KGDB调试Linux内核与模块
前言 内核 5.10 版本 openEuler 使用 yum install 下载了源码,并且通过两个 VMware 虚拟机进行调试 ubuntu 直接使用 git 拉取了https://kernel ...
- soapUI参数化总结
1.新建项目目录 以获取用户贡献等级为例,目录如下: 2.添加DataSource和DataSource Loop 选中Test Step右键分别新建DataSource和DataSource Loo ...
- jmeter使用时报错问题
一.打开时命令行提示按任意键继续图形界面无法打开 如图,打开时jmeter命令行报错 根据报错内容,是Java没有安装好. jdk安装好后,需要在环境变量中配置. 但是jdk安装配置好后打开还是报错, ...
- 指向const的指针和const指针的区别
1. 指向常量的指针(指向const的指针) 指向const的指针,不能改变其所指变量(对象)的值,或者说不能通过这个指向const的指针去改变所指的变量(对象)的值 // 指向const的指针,不能 ...
- 使用IDEA管理服务器Docker及远程仓库
目录 配置连接Docker服务器及远程仓库 连接服务器Docker 远程仓库(可选) IDEA管理 确保docker服务器已经开启了远程守护进程访问.[1] 配置连接Docker服务器及远程仓库 连接 ...
- Java 多例设计模式
/** * 多例设计模式:可以根据输入的参数不同返回不同的实例化对象 * 1.构造私有化 * 2.输入的参数不同 * 2017-09-11 * @author Junwei Zhu * */ clas ...
- codeup之字符串比较
Description 比较两个字符串s1和s2的大小,如果s1>s2,则输出一个正数:若s1=s2,则输出0:若s1<s2,则输出一个负数. 要求:不用strcpy函数:两个字符串用ge ...
- POWERBI_创建工作区应用_协同办公能力 up up up
在powerbi中,我们往往会创建很多不同模型的报表,他们分别独立,但是在业务决策过程中,我们需要跨报表查看数据,反复切换报表,低效且忙乱 这个时候,合并展示报表是至关重要的 今天就一起学习一下,如何 ...
- 第5讲、Transformer 编码器(Encoder)处理过程详解
Transformer 编码器(Encoder)处理过程详解 Transformer Encoder 是一个由 N 层(一般为 6 层)堆叠而成的模块结构.每一层的本质是两个核心子模块: 多头自注意力 ...
- 解决Git异常 Access denied your account has 2FA enabled
摘要:解决Git双因子身份验证问题. 问题背景 在使用账号和密码的方式拉取公司GitLab代码时,遇到了以下错误提示问题: remote: HTTP Basic: Access denied. T ...