前端实现电子签名(web、移动端)通用组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<canvas></canvas>
<div>
<button onclick="cancel()">取消</button>
<button onclick="save()">保存</button>
</div>
</body>
<script>
// 配置内容
const config = {
width: 400, // 宽度
height: 200, // 高度
lineWidth: 5, // 线宽
strokeStyle: 'red', // 线条颜色
lineCap: 'round', // 设置线条两端圆角
lineJoin: 'round', // 线条交汇处圆角
} // 获取canvas 实例
const canvas = document.querySelector('canvas')
// 设置宽高
canvas.width = config.width
canvas.height = config.height
// 设置一个边框
canvas.style.border = '1px solid #000'
// 创建上下文
const ctx = canvas.getContext('2d') // 设置填充背景色
ctx.fillStyle = 'transparent'
// 绘制填充矩形
ctx.fillRect(
0, // x 轴起始绘制位置
0, // y 轴起始绘制位置
config.width, // 宽度
config.height // 高度
); // 保存上次绘制的 坐标及偏移量
const client = {
offsetX: 0, // 偏移量
offsetY: 0,
endX: 0, // 坐标
endY: 0
} // 判断是否为移动端
const mobileStatus = (/Mobile|Android|iPhone/i.test(navigator.userAgent)) // 初始化
const init = event => {
// 获取偏移量及坐标
const {offsetX, offsetY, pageX, pageY} = mobileStatus ? event.changedTouches[0] : event // 修改上次的偏移量及坐标
client.offsetX = offsetX
client.offsetY = offsetY
client.endX = pageX
client.endY = pageY // 清除以上一次 beginPath 之后的所有路径,进行绘制
ctx.beginPath()
// 根据配置文件设置相应配置
ctx.lineWidth = config.lineWidth
ctx.strokeStyle = config.strokeStyle
ctx.lineCap = config.lineCap
ctx.lineJoin = config.lineJoin
// 设置画线起始点位
ctx.moveTo(client.endX, client.endY)
// 监听 鼠标移动或手势移动
window.addEventListener(mobileStatus ? "touchmove" : "mousemove", draw)
}
// 绘制
const draw = event => {
// 获取当前坐标点位
const {pageX, pageY} = mobileStatus ? event.changedTouches[0] : event
// 修改最后一次绘制的坐标点
client.endX = pageX
client.endY = pageY // 根据坐标点位移动添加线条
ctx.lineTo(pageX, pageY) // 绘制
ctx.stroke()
}
// 结束绘制
const cloaseDraw = () => {
// 结束绘制
ctx.closePath()
// 移除鼠标移动或手势移动监听器
window.removeEventListener("mousemove", draw)
}
// 创建鼠标/手势按下监听器
window.addEventListener(mobileStatus ? "touchstart" : "mousedown", init)
// 创建鼠标/手势 弹起/离开 监听器
window.addEventListener(mobileStatus ? "touchend" : "mouseup", cloaseDraw) // 取消-清空画布
const cancel = () => {
// 清空当前画布上的所有绘制内容
ctx.clearRect(0, 0, config.width, config.height)
}
// 保存-将画布内容保存为图片
const save = () => {
// 将canvas上的内容转成blob流
canvas.toBlob(blob => {
// 获取当前时间并转成字符串,用来当做文件名
const date = Date.now().toString()
// 创建一个 a 标签
const a = document.createElement('a')
// 设置 a 标签的下载文件名
a.download = `${date}.png`
// 设置 a 标签的跳转路径为 文件流地址
a.href = URL.createObjectURL(blob)
// 手动触发 a 标签的点击事件
a.click()
// 移除 a 标签
a.remove()
})
}
</script>
</html>
前端实现电子签名(web、移动端)通用组件的更多相关文章
- 饿了么基于Vue2.0的通用组件开发之路(分享会记录)
Element:一套通用组件库的开发之路 Element 是由饿了么UED设计.饿了么大前端开发的一套基于 Vue 2.0 的桌面端组件库.今天我们要分享的就是开发 Element 的一些心得. 官网 ...
- 前端文摘:Web 开发模式演变历史和趋势
今天的<前端文摘>给大家分享一篇玉伯的文章.文章详细介绍了 Web 开发的四种常用模式以及未来可能成为流行趋势的 Node 全栈开发模式,相信你看了以后一定会有收获. 您可能感兴趣的相关文 ...
- Web服务端软件的服务品质概要
软件品质概述 提供同样功能.产品和服务的服务者中, 竞争力来自功能的多样化和服务品质的差异化, 无论是个体.企业还是国家. 这里的服务指功能.产品的实现程度和处理能力,以及研发/客服提供的技术支持程度 ...
- Vue2.0的通用组件
饿了么基于Vue2.0的通用组件开发之路(分享会记录) Element:一套通用组件库的开发之路 Element 是由饿了么UED设计.饿了么大前端开发的一套基于 Vue 2.0 的桌面端组件库. ...
- JS前端图形化插件之利器Gojs组件(php中文网)
JS前端图形化插件之利器Gojs组件(php中文网) 一.总结 一句话总结:php中文网我可以好好走一波 二.JS前端图形化插件之利器Gojs组件 参考: JS前端图形化插件之利器Gojs组件-js教 ...
- 关于如何提高Web服务端并发效率的异步编程技术
最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...
- HT for Web的HTML5树组件延迟加载技术实现
HT for Web的HTML5树组件有延迟加载的功能,这个功能对于那些需要从服务器读取具有层级依赖关系数据时非常有用,需要获取数据的时候再向服务器发起请求,这样可减轻服务器压力,同时也减少了浏览器的 ...
- Openstack的web管理端相关
openstack的web管理端技术方面要关注的问题. 同步?异步 先说浏览器的同步和异步,我们知道的浏览器可以使用ajax实现异步请求,就是浏览器在请求数据的时候,我们管理员还能对浏览器就行其他操作 ...
- 从web移动端布局到react native布局
在web移动端通常会有这样的需求,实现上中下三栏布局(上下导航栏位置固定,中间部分内容超出可滚动),如下图所示: 实现方法如下: HTML结构: <div class='container'&g ...
- 【译】编写支持SSR的通用组件指南
原文来自:https://blog.lichter.io/posts/the-guide-to-write-universal-ssr-ready-vue-compon?utm_campaign=Vu ...
随机推荐
- 新下载了一个框架,然后npm install时候报错npm ERR! Maximum call stack size exceeded
今天遇到这个npm ERR! Maximum call stack size exceeded报错 解决方案如下: 1.更新npm版本 //查看版本 npm -v //更新 npm install - ...
- 【Regex】判断密码强度的正则表达式
原文地址 https://www.cnblogs.com/younShieh/p/17082522.html 如果本文对你有所帮助,不妨点个关注和推荐呀,这是对笔者最大的支持~ 需求 最近 ...
- 默认方法:negate-集合信息筛选
默认方法:negate "与"."或"已经了解了,剩下的"非"(取反)也会简单.默认方法negate的JDK源代码为︰ 集合信息筛选 数组当 ...
- java入门与进阶 P-3.2+P-3.3+P3.4
数数字 例如:Scanner sc = new Scanner(System.in);int number = sc.nextInt();int count= 0;while(number>0) ...
- 1月9日内容总结——linux相关知识简介、虚拟化软件vmware、远程链接工具xshell
目录 一.linux常见岗位 二.计算机的种类与服务器 三.服务器品牌 四.服务器内部组成 五.服务器磁盘阵列 六.linux简介 1.什么是linux 2.linux发展史 3.Linux系统的特点 ...
- socket模块实现网络编程及struct模块解决黏包问题
目录 一.socket模块 1.简介 2.基于文件类型的套接字家族 3.基于网络类型的套接字家族 二.socket代码简介 三.socket代码优化 1.聊天内容自定义 2.让聊天循环起来 3.用户输 ...
- 【译】使用 ML.NET 进行机器学习 - 集群完整指南
原文 | Nikola M. Zivkovic 翻译 | 郑子铭 在之前的几篇文章中,我们探索了一些基本的机器学习算法.到目前为止,我们介绍了一些简单的回归算法,分类 算法.我们使用 ML.NET 实 ...
- Nginx10 Lua入门 + openresty
1 Idea中创建Lua项目 lua官网:https://www.lua.org/ 1.1 添加插件,重启idea 1.2 创建项目 file-New Project 1.3 创建lua文件 1.4 ...
- 制作 2D 素材|基于 AI 5 天创建一个农场游戏,第 4 天
欢迎使用 AI 进行游戏开发! 在本系列中,我们将使用 AI 工具在 5 天内创建一个功能完备的农场游戏.到本系列结束时,您将了解到如何将多种 AI 工具整合到游戏开发流程中.本系列文章将向您展示如何 ...
- Docker挂载
1.挂载的概念 预备:你需要了解docker的基本知识 docker实现了容器部署,那当我们需要配置或者查看容器生成的日志文件怎么办? docker提供了挂载机制:挂载能够将容器内的目录/文件和外部的 ...