首頁 > 軟體

JS前端使用canvas編寫一個簽名板

2022-08-02 14:05:32

需求

需求是做不完了,福利也被砍了,旅遊也泡湯了,手上有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

程式碼

<!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>

以上程式碼,未開發的點

  • 行動端觸控事件,禁止行動端螢幕,修改筆畫粗細、筆畫顏色
  • 實時同步WebSocket
  • 實時同步筆畫時,如何讓筆畫有實時同步一筆一畫的效果?下圖

以上就是JS前端使用canvas編寫一個簽名板的詳細內容,更多關於JS canvas簽名板的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com