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

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

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

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

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

文章链接: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 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
h5逐步实现 <<canvas系统>>
第三:让canvas绘图可以画整个body.并且要设置线条的宽度+线条结束时候的形状+两天线条相交时的形状.+线条的颜色.
贵哥的编程之路
2020/10/28
3700
h5逐步实现 <<canvas系统>>
几十行代码搞定兔年刮刮乐
刮刮乐大家都知道,无论是实体票子的刮奖还是虚拟活动的电子刮奖基本都使用这种方式。我们先来做下刮刮乐的设计。
嘿嘿不务正业
2023/05/09
1.2K0
几十行代码搞定兔年刮刮乐
canvas 系列学习笔记三实战例子《图片上画标注》
imgae 是一个底图,上面是canvans 操作画图,底部层级可以是标签或者canvans 加载都可以。因为练习,所以选用canvans。
星宇大前端
2022/09/08
6510
【canvas】30行代码教你画一个刮刮乐
粥六快乐!! 💌 摸鱼时间,点进了充满童年回忆的4399,页面还是那个味道一点也没变。 突发奇想,要不尝试做个4399小游戏玩玩?太复杂的也费事,就整个简单的刮刮乐吧。 ✔开整~ 分析 🎨 刮刮乐游戏肯定需要两张图片,通过鼠标的移动控制图片的绘制路径 🕐步骤1 准备1个canvas容器: <canvas width="800px" height="600px"></canvas> 🕑 步骤2 注册图片 const one = new Image() one.src = './1
且陶陶
2023/04/12
7330
【canvas】30行代码教你画一个刮刮乐
《最新出炉》系列初窥篇-Python+Playwright自动化测试-64 - Canvas和SVG元素推拽
今天宏哥分享的在实际测试工作中很少遇到,比较生僻,如果突然遇到我们可能会脑大、懵逼,一时之间不知道怎么办?所以宏哥这里提供一种思路供大家学习和参考。
北京-宏哥
2024/06/29
3200
《最新出炉》系列初窥篇-Python+Playwright自动化测试-64 - Canvas和SVG元素推拽
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
8960
Canvas 进阶(四)实现一个“刮刮乐”游戏
我们创建一个 ScrapAward 类,通过传入 option 和调用其 restart() 方法实现重新开始。
小皮咖
2019/11/05
1K0
《最新出炉》系列初窥篇-Python+Playwright自动化测试-65 - Canvas元素推拽-番外篇
上一篇宏哥想了好多办法都没有演示成功的拖拽Canvas元素,宏哥也说的太绝对了,给大家造成困惑或者误导。一连好几天吃饭睡觉都不怎么香了,脑子中始终对这件事耿耿于怀,自己问自己难道就真的没有办法了吗?突然想到了一种办法抱着试一下的心态,结果出乎意料但是又在情理之中:成功推拽了!!!此刻地心情无以言表,直接来睡一篇Canvas元素拖拽的番外篇来分享一下宏哥的喜悦心情。好了言归正传下边进入今天的主题。
北京-宏哥
2024/07/05
5960
《最新出炉》系列初窥篇-Python+Playwright自动化测试-65 - Canvas元素推拽-番外篇
利用 Canvas 实现 Valine 评论画板涂鸦
前几天在 Joe(https://ae.js.cn/)网站上留言的时候发现了一个叫“画图模式”的东西,点进去后自动切换文本框到画板了(类似QQ涂鸦,你画我猜那种画板),然后可以在画板上画画,还可以选择画笔粗细、颜色等等,画错了还能撤销各种功能,欸感觉挺有意思的,当时也猜到了应该是用 canvas 做的,不过自己也不太了解这块,但就是感觉挺有意思的,加上我又喜欢魔改 valine 评论,所以立下计划决定给评论系统加上这么一个好玩的功能。
2Broear
2024/03/12
1760
利用 Canvas 实现 Valine 评论画板涂鸦
canvas 实现签名小 demo
现在使用网页进行签名的业务场景非常多,自己用到的就有银行和移动办理业务的时候使用电子签名。网页实现电子签名其实也挺容易的,canvas 标签非常容易实现,再加上可以导出签名图片,几十行代码就实现了。
wade
2023/09/01
2310
canvas 实现签名小 demo
Canvas跟随鼠标炫彩小球
通过创建函数收纳小球所有的样式,再通过实例化函数,将鼠标当前的位置传递给Ball函数,让通过实例化创建出来的小球,最后将创建出来的小球存入数组中,数组中以对象形式存放着每个小球的属性和属性值
小丞同学
2021/08/16
1.9K1
【H5游戏实例】JS+canvas实现人机大战之五子棋
html代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>五子棋</title> <link rel="stylesheet" type="text/css" href="css/style.css"/> </head> <body> <canvas id="chess" width="450px" height="450px"><
李海彬
2018/03/27
1.9K0
【H5游戏实例】JS+canvas实现人机大战之五子棋
用 CodeBuddy 打造一张属于她的 520 刮刮乐,程序员的浪漫可以这么强大!
520 马上就要来了,作为一个程序员,除了发红包还能干点啥?你可能会觉得,发个红包是最省事的选择,可是,多少有点“没诚意”的味道。尤其是在这个仪式感爆棚的日子里,直接塞个 1314 元红包过去,虽然看起来挺大气,但终究少了点心思和惊喜。
不惑
2025/05/19
1830
用 CodeBuddy 打造一张属于她的 520 刮刮乐,程序员的浪漫可以这么强大!
[移动端抽奖刮刮卡] Html5 Canvas 实现的可刮涂层效果
亲,像下面这种有关移动互联网迅猛发展的报告,最近见得很多吧?在座各位作为互联网行业的弄潮儿,看完是不是很有历史使命感和紧迫感呢?简直热血喷张、跃跃欲试,甚至有一种“不移动不成活”的冲动吧?!
李维亮
2021/07/09
1.2K0
【CodeBuddy】三分钟开发一个实用小功能之:万花筒图案生成器
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接: 腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴
Jimaks
2025/05/21
1040
【CodeBuddy】三分钟开发一个实用小功能之:万花筒图案生成器
Canvas画板
Html5Canvas打造的画图板,利用鼠标点击移动画图,完成之后可以保存为png格式的图片。 小杰鼠标画的,见谅,代码如下 <!doctype html> <html> <head> <me
Youngxj
2018/06/06
1.5K0
原生小案例:如何使用HTML5 Canvas构建画板应用程序
HTML canvas标签是一个HTML元素,它提供了一个空白的绘图表面,可以使用JavaScript来渲染图形、形状和图像。绘图应用程序利用HTML5 canvas的功能,使用户能够以数字方式创建艺术作品、草图和插图。此外,使用HTML5 canvas构建的绘图应用程序允许用户与画布进行交互,捕捉鼠标移动和点击事件,实时绘制、擦除或操作元素。
前端达人
2023/08/31
9750
原生小案例:如何使用HTML5 Canvas构建画板应用程序
vue使用canvas签名之PC端
在一些项目业务中,经常会使用到画板,让用户自己去写/画一些东西做标示,比如说在线签电子合约、签名等,如果不用插件,那么如何使用h5的canvas画布来实现这一需求呢?【本篇只讨论PC端,移动端期待下篇】
流眸
2020/02/14
1.5K0
vue使用canvas签名之PC端
原 canvas小案例集合(小画板、画的回
作者:汪娇娇 日期:2016.12.8 在现在这个公司呆了4个多月,也是研究了canvas将近4个月,前两周心里就痒痒的想写这方面的博客,但一直没时间。可一直拖着也不是个办法,就这样抽抽空来写吧。 c
jojo
2018/05/03
1.4K1
原                                                                                canvas小案例集合(小画板、画的回
手写原生代码专题 | 简易手写画板(二)
如视频所示,在这个示例中,我们用到了画布 canvas 相关的知识,比如创建画布、画圆形、画直线的基础知识,有了这些基础后,我们就能轻松完成本示例,示例效果如下视频所示。
前端达人
2021/07/16
1.6K0
推荐阅读
相关推荐
h5逐步实现 <<canvas系统>>
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档