前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >因业务需要,我用canvas写了一个签名板

因业务需要,我用canvas写了一个签名板

原创
作者头像
一起重学前端
发布于 2024-11-21 03:42:37
发布于 2024-11-21 03:42:37
1350
举报

在文章开始之前,推荐一些很值得阅读的好文章!感兴趣的也可以去看一下哦!

今日推荐:一段代码,如何解决图片懒加载的优雅需求?

文章链接:https://cloud.tencent.com/developer/article/2468390

通过滚动加载捕捉用户的交互意图,通过分页控制分步加载数据,这种懒加载方案不仅能有效缓解性能压力,还能提供流畅的用户体验。在实现的过程中,代码与逻辑的结合需要我们持续优化,为每一帧滚动画面注入丝滑的灵动感。

需求做不完了

需求是做不完了,福利也被砍了,旅游也泡汤了,手上有2个需求,还没做完,PM就来新需求了。开发一个签名板:要求PC端/移动端都能用、扫码签名、实时同步、可以改变笔画粗细、笔画颜色、可以生成base64图片。

方案分析canvas

  1. 获取页面canvas元素,设置宽高(800*200)
  2. 通过HTMLCanvasElement.getContext()  方法返回canvas 的上下文ctx
  3. 初始化ctx基础属性
    • 线条颜色
    • 线条宽度
    • 线条末端形状
  4. 开始绘画
    • 监听鼠标事件
    • 绘制起点、终点
  5. 生成一个移动端链接二维码
  6. 在移动端签名时,通过WebSocket,实时传递数据给PC端。

涉及知识点

Canvas涉及特性:

  • 基本属性
    • getContext()
    • strokeStyle
    • fillStyle
    • lineCap
    • lineJoin
  • 路径绘制
    • beginPath()
    • lineTo()
    • moveTo()
  • 其他方法(生成base64,清除画板)
    • toDataURL()
    • clearRect()

涉及鼠标事件:

  • mousemove
  • mousedown
  • mouseup
  • mouseout

涉及移动端触摸事件:

  • touchstart
  • touchend
  • touchmove

代码

代码语言:html
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>canvas-sign</title>
	<style>
		html,
		body {
			margin: 0;
		}

		.container {
			width: calc(100vw - 40px);
			height: calc(100vh - 40px);
			padding: 20px;
		}

		.canvas-body {
			width: calc(80vw);
			height: calc(80vh);
			margin: 20px auto;
		}

		#sign {
			background-color: #f3f5f7;
			border-radius: 4px;
			border: 1px dashed #0F6BFF;
		}

		#img {
			margin: 20px;
			border-radius: 4px;
			background-color: #f3f5f7;
			display: none;
		}

		#img.show {
			display: inline-block;
		}

		.btns {
			width: calc(80vw - 40px);
			text-align: right;
			margin: 0 auto;
		}

		@media screen and (orientation: portrait) {
			.qrcode {
				display: none;
			}
		}
	</style>
	<script type="text/javascript" src="https://static.runoob.com/assets/qrcode/qrcode.min.js"></script>
</head>

<body>
	<div class="container">
		<div id="canvas-body" class="canvas-body">
			<canvas id="sign" style="width: 100%; height: 100%;"></canvas>
			<div class="qrcode">
				扫码签名
				<div id="qrcode"></div>
			</div>
		</div>
		<div class="btns">
			<button id="reset">重置</button>
			<button id="showImg">生成图片</button>
		</div>
	</div>
	<div id="img">

	</div>
	<script>
		let canvasBody = document.getElementById('canvas-body');
		let canvas = document.getElementById('sign');
		let reset = document.getElementById('reset');
		let showImg = document.getElementById('showImg');
		let img = document.getElementById('img');
		canvas.width = canvasBody.clientWidth;
		canvas.height = canvasBody.clientHeight;
		let ctx = canvas.getContext('2d');
		ctx.lineWidth = 10;
		ctx.strokeStyle = '#333';
		ctx.lineCap = 'round';
		ctx.lineJoin = 'round';
		let isDrawing = false;
		let dataURL = '';
		let initX;
		let initY;
		// 事件监听
		canvas.addEventListener('mousedown', (e) => {
			isDrawing = true;
			initX = e.offsetX;
			initY = e.offsetY
		});
		canvas.addEventListener('mousemove', draw);
		canvas.addEventListener('mouseup', () => isDrawing = false);
		canvas.addEventListener('mouseout', () => isDrawing = false);

		// 绘制
		function draw(e) {
			if (!isDrawing) return
			ctx.beginPath();
			// 起点
			ctx.moveTo(initX, initY);
			// 终点
			ctx.lineTo(e.offsetX, e.offsetY);
			ctx.stroke();
			initX = e.offsetX;
			initY = e.offsetY
		}

		function clear() {
			ctx.clearRect(0, 0, canvas.width, canvas.height);
			if (dataURL) {
				dataURL = '';
				img.innerHTML = '';
				img.classList.remove('show');
			}
		}

		function canvasToBase64() {
			dataURL = canvas.toDataURL();
			// let oGrayImg = new Image();
			// oGrayImg.src = dataURL;
			// img.classList.add('show');
			// img.appendChild(oGrayImg)
			alert(`${dataURL}`)
		}

		reset.addEventListener('click', clear);
		showImg.addEventListener('click', canvasToBase64);
	</script>
	<script>
		let qrcode = new QRCode(document.getElementById('qrcode'), {
			width: 96,
			height: 96
		})

		qrcode.makeCode('https://canvas-sign.vercel.app/');

	</script>
</body>

</html>

代码地址

https://github.com/aisiqilove/sign-npm

在线预览效果

以上代码,未开发的点

  1. 移动端触摸事件,禁止移动端屏幕,修改笔画粗细、笔画颜色
  2. 实时同步WebSocket
  3. 实时同步笔画时,如何让笔画有实时同步一笔一画的效果?下图

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
canvas实现在线签名
<body> <div style="margin:20px auto; text-align:center;">签名版</div> <canvas id="canvasbox" width="500" height="250" style="border:1px solid green; margin:20px auto;display:block;"></canvas> <div class="btn" style="margin:0 auto; text-align:center;
用户1349575
2022/01/26
9090
h5逐步实现 <<canvas系统>>
第三:让canvas绘图可以画整个body.并且要设置线条的宽度+线条结束时候的形状+两天线条相交时的形状.+线条的颜色.
贵哥的编程之路
2020/10/28
3810
h5逐步实现 <<canvas系统>>
Canvas画板
Html5Canvas打造的画图板,利用鼠标点击移动画图,完成之后可以保存为png格式的图片。 小杰鼠标画的,见谅,代码如下 <!doctype html> <html> <head> <me
Youngxj
2018/06/06
1.6K0
canvas 系列学习笔记三实战例子《图片上画标注》
imgae 是一个底图,上面是canvans 操作画图,底部层级可以是标签或者canvans 加载都可以。因为练习,所以选用canvans。
星宇大前端
2022/09/08
6560
CodeBuddy 设计电子签名工具,让每一个签名,都能体现你的风格
✍️ 在这个一切都开始数字化的时代,连“签字”这件事,也早已从纸笔之间搬到了屏幕上。合同、发票、协议、简历,甚至电子请柬上,越来越多的地方在使用电子签名。
不惑
2025/07/02
430
CodeBuddy 设计电子签名工具,让每一个签名,都能体现你的风格
手写原生代码专题 | 简易手写画板(二)
如视频所示,在这个示例中,我们用到了画布 canvas 相关的知识,比如创建画布、画圆形、画直线的基础知识,有了这些基础后,我们就能轻松完成本示例,示例效果如下视频所示。
前端达人
2021/07/16
1.6K0
Canvas跟随鼠标炫彩小球
通过创建函数收纳小球所有的样式,再通过实例化函数,将鼠标当前的位置传递给Ball函数,让通过实例化创建出来的小球,最后将创建出来的小球存入数组中,数组中以对象形式存放着每个小球的属性和属性值
小丞同学
2021/08/16
2K1
Canvas 绘图技术:如何实现签名板签名功能以及导出图片
大家好,我是腾讯云开发者社区的 Front_Yue,本篇文章将带领大家学习利用Canvas实现签名板签名功能以及导出图片。
Front_Yue
2024/01/24
1.7K3
Canvas 绘图技术:如何实现签名板签名功能以及导出图片
【canvas】30行代码教你画一个刮刮乐
粥六快乐!! 💌 摸鱼时间,点进了充满童年回忆的4399,页面还是那个味道一点也没变。 突发奇想,要不尝试做个4399小游戏玩玩?太复杂的也费事,就整个简单的刮刮乐吧。 ✔开整~ 分析 🎨 刮刮乐游戏肯定需要两张图片,通过鼠标的移动控制图片的绘制路径 🕐步骤1 准备1个canvas容器: <canvas width="800px" height="600px"></canvas> 🕑 步骤2 注册图片 const one = new Image() one.src = './1
且陶陶
2023/04/12
7550
【canvas】30行代码教你画一个刮刮乐
几十行代码搞定兔年刮刮乐
刮刮乐大家都知道,无论是实体票子的刮奖还是虚拟活动的电子刮奖基本都使用这种方式。我们先来做下刮刮乐的设计。
嘿嘿不务正业
2023/05/09
1.2K0
几十行代码搞定兔年刮刮乐
原生小案例:如何使用HTML5 Canvas构建画板应用程序
HTML canvas标签是一个HTML元素,它提供了一个空白的绘图表面,可以使用JavaScript来渲染图形、形状和图像。绘图应用程序利用HTML5 canvas的功能,使用户能够以数字方式创建艺术作品、草图和插图。此外,使用HTML5 canvas构建的绘图应用程序允许用户与画布进行交互,捕捉鼠标移动和点击事件,实时绘制、擦除或操作元素。
前端达人
2023/08/31
1.2K0
原生小案例:如何使用HTML5 Canvas构建画板应用程序
我希望按照我的思路尽可能将canvas基础讲明白
写在前面 canvas很多人写过,我之前的博客里面也写过关于canvas的教程,但是后面我觉得其实不太好,因为很多东西都是很模糊的,没有非常直观清晰的将canvas讲解明白,究其原因,还是这个属性使用的不够多,导致很多属性不够熟练,但是我希望这篇文章可以将这个属性彻底的讲明白,毕竟只是一个标签而已,怎么讲都不会太复杂,他之所以不太好学原因就在于他自带的方法太多,加上很多的效果都是需要方法之间的相互配合使用,所以难度和复杂度就直接升高了很多,它不像html的其他标签一样,比如p、span等都只是自带了一些样
何处锦绣不灰堆
2022/05/31
3780
我希望按照我的思路尽可能将canvas基础讲明白
《最新出炉》系列初窥篇-Python+Playwright自动化测试-64 - Canvas和SVG元素推拽
今天宏哥分享的在实际测试工作中很少遇到,比较生僻,如果突然遇到我们可能会脑大、懵逼,一时之间不知道怎么办?所以宏哥这里提供一种思路供大家学习和参考。
北京-宏哥
2024/06/29
3480
《最新出炉》系列初窥篇-Python+Playwright自动化测试-64 - Canvas和SVG元素推拽
利用 Canvas 实现 Valine 评论画板涂鸦
前几天在 Joe(https://ae.js.cn/)网站上留言的时候发现了一个叫“画图模式”的东西,点进去后自动切换文本框到画板了(类似QQ涂鸦,你画我猜那种画板),然后可以在画板上画画,还可以选择画笔粗细、颜色等等,画错了还能撤销各种功能,欸感觉挺有意思的,当时也猜到了应该是用 canvas 做的,不过自己也不太了解这块,但就是感觉挺有意思的,加上我又喜欢魔改 valine 评论,所以立下计划决定给评论系统加上这么一个好玩的功能。
2Broear
2024/03/12
2090
利用 Canvas 实现 Valine 评论画板涂鸦
解锁前端难题:亲手实现一个图片标注工具
业务中涉及图片的制作和审核功能,审核人员需要在图片中进行标注,并说明存在的问题,标注过程中需要支持放大缩小,移动等交互,将业务剥离,这个需求,可以定义为实现一个图片标注功能。
winty
2024/04/15
1.3K0
解锁前端难题:亲手实现一个图片标注工具
vue使用canvas签名之PC端
在一些项目业务中,经常会使用到画板,让用户自己去写/画一些东西做标示,比如说在线签电子合约、签名等,如果不用插件,那么如何使用h5的canvas画布来实现这一需求呢?【本篇只讨论PC端,移动端期待下篇】
流眸
2020/02/14
1.5K0
vue使用canvas签名之PC端
通过canvas画板学习PointerEvent、MouseEvent和TouchEvent
最近想开发个草稿纸功能, 所以学习了下canvas实现简单的画板功能, 但是我们知道在PC端我们可以用MouseEvent来监听我们的鼠标点按相关操作, 移动端可以使用TouchEvent来监听我们手指触摸相关操作, 所以我们做画板的时候要想兼顾鼠标点按和手指触摸就得写两套逻辑. 但是别忘了, 还存在PointerEventer, 它可以监听鼠标, 手指触摸以及触摸笔, 支持多点触控, 它还有个特殊的参数, 即压感, 在压感屏上可以获取获取压感笔的压感值, 只要根据压感值, 我们可以控制笔画的粗细
治电小白菜
2021/04/27
1.8K0
通过canvas画板学习PointerEvent、MouseEvent和TouchEvent
原 canvas小案例集合(小画板、画的回
作者:汪娇娇 日期:2016.12.8 在现在这个公司呆了4个多月,也是研究了canvas将近4个月,前两周心里就痒痒的想写这方面的博客,但一直没时间。可一直拖着也不是个办法,就这样抽抽空来写吧。 c
jojo
2018/05/03
1.4K1
原                                                                                canvas小案例集合(小画板、画的回
Canvas 进阶(四)实现一个“刮刮乐”游戏
我们创建一个 ScrapAward 类,通过传入 option 和调用其 restart() 方法实现重新开始。
小皮咖
2019/11/05
1.1K0
【JS】936- File、Blob、dataURL 和 canvas 的应用与转换
(1) 通常情况下, File 对象是来自用户在一个 input 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。
pingan8787
2021/04/26
2.6K0
【JS】936- File、Blob、dataURL 和 canvas 的应用与转换
推荐阅读
相关推荐
canvas实现在线签名
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档