canvas电子签名和播放划线

直接上代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>点子签名</title>
		<style type="text/css">
			#canvas {
				border: 1px solid red;
			}

			.content {
				display: flex;
			}

			.right {
				margin-left: 20px;
			}

			.right-item {
				margin-bottom: 10px;
				display: flex;
				align-items: center;
			}

			.right-item span {
				display: inline-block;
				width: 100px;
				font-size: 17px;
			}

			.right-item button {
				margin-right: 5px;
			}

			.slot {
				width: 200px;
				height: 20px;
				background-color: #eee;
				border-radius: 30px;
				overflow: hidden;
				position: relative;
			}

			.slot .slot-round {
				position: absolute;
				border-radius: 30px;
				transition: all .3s;
				background-color: deeppink;
				left: 0;
				top: 0;
				bottom: 0;
			}
		</style>
	</head>
	<body>
		<div class="content">
			<canvas id="canvas" width="1000" height="500"></canvas>
			<div class="right">
				<div class="right-item">
					<span>颜色选择:</span>
					<input type="color" onchange="colorge(this)" value="#5D1F7A" />
				</div>
				<div class="right-item">
					<span>操作:</span>
					<button type="button" id="submit" style="display: none;">确 认</button>
					<button type="button" onclick="clert(this)">清 除</button>
					<button type="button" onclick="reproduce(this)">重 现</button>
					<button type="button" onclick="down()">下 载</button>
				</div>
				<div class="right-item">
					<span>重现进度:</span>
					<div class="slot">
						<div class="slot-round" id="walk"></div>
					</div>
				</div>
			</div>
		</div>
		<script type="text/javascript">
			let canvas = document.getElementById('canvas')
			let ctx = canvas.getContext('2d')
			let walk = document.getElementById('walk')
			let submit = document.getElementById('submit')
			let solidShow = false //开关
			let walkNumb = 0 //步骤总数
			let startX = 0,
				startY = 0,
				color = '#5D1F7A',
				storage = []
			let GPS = -8 //线开始的位置调整
			let s = 0
			let reproduceS = 0
			let times = null //定时器
			let reproduceTimes = null //重现定时器
			let reproduceShow = false // 是否可重现
			ctx.lineWidth = 5 //线粗
			clert()
			// 鼠标按下
			canvas.addEventListener('mousedown', e => {
				if (s == 0) {
					times = setInterval(() => {
						s = s + 1
					}, 1)
				}
				reproduceShow = false
				submit.style = 'display:inline-block;'
				solidShow = true
				startX = e.pageX
				startY = e.pageY
				startSolid(e)
			})
			// 鼠标离开画布
			canvas.addEventListener('mouseleave', () => {
				if (solidShow) {
					solidShow = false
				}
			})
			// 鼠标抬起
			canvas.addEventListener('mouseup', () => {
				solidShow = false
			})
			// 鼠标滑动
			canvas.addEventListener('mousemove', e => {
				if (solidShow) {
					startSolid(e)
				}
			})

			submit.addEventListener('click', e => {
				e.srcElement.style = 'display:none;'
				timesStop()
			})

			function startSolid(e) { //开始画线
				let x = e.pageX,
					y = e.pageY
				storage.push({ //记录画线
					startX,
					startY,
					x,
					y,
					s
				})
				walkNumb = storage.length
				walk.style = `width:0;background-color:${color};`
				ctx.save()

				ctx.strokeStyle = color
				ctx.beginPath()
				ctx.moveTo(startX + GPS, startY + GPS)
				ctx.lineTo(x + GPS, y + GPS)
				ctx.closePath()
				ctx.stroke()

				ctx.restore()
				if (startY != y) {
					startY = y
				}
				if (startX != x) {
					startX = x
				}
			}

			function clert() { //清除
				reproduceTimesStop()
				timesStop()
				storage = []
				walk.style = `width:0;background-color:${color};`
				ctx.fillStyle = '#eee' //清空画布
				ctx.fillRect(0, 0, canvas.width, canvas.height)
			}

			function colorge(e) { //颜色选择
				color = e.value
			}

			function reproduce() {
				if (!storage.length) {
					alert('没有可重现的操作!')
					return true
				}
				if (!reproduceShow) {
					submit.style = 'display:none;'
					timesStop()
				}
				console.log('重现', storage)
				ctx.fillRect(0, 0, canvas.width, canvas.height)

				if (reproduceS != 0) {
					reproduceTimesStop()
				}

				if (reproduceS == 0) {
					walkNumb = storage.length
					storage = storage.sort((a, b) => { //排序
						return a.s - b.s
					})
					reproduceTimes = setInterval(() => {
						storage.forEach(item => {
							if (item.s == reproduceS) {
								ctx.strokeStyle = color
								ctx.beginPath()
								ctx.moveTo(item.startX + GPS, item.startY + GPS)
								ctx.lineTo(item.x + GPS, item.y + GPS)
								ctx.closePath()
								ctx.stroke()
								walkNumb = walkNumb - 1
								// walk.innerText = walkNumb
								walk.style = `width:${(storage.length-walkNumb)/storage.length*100}%;background-color:${color};`

							}
						})
						if (storage[storage.length - 1].s == reproduceS) {
							reproduceTimesStop()
						} else {
							reproduceS = reproduceS + 1
						}
					}, 1)
				}
			}

			function reproduceTimesStop() {
				clearInterval(reproduceTimes)
				reproduceS = 0
			}

			function timesStop() {
				clearInterval(times)
				s = 0
			}

			function down(){ //下载图片
				let base64 = canvas.toDataURL("image/jpeg", 0.5)
				   const a = document.createElement('a');//创建a标签
				   a.setAttribute('download', new Date().toLocaleString());// 名字
				   a.setAttribute('href', base64);// href链接
				   a.click();					 // 自执行点击事件
				   document.body.appendChild(a);//插入body里
				   document.body.removeChild(a);//从body删除

			}

			function look() { //查看定时器
				console.log('s', s)
				console.log('reproduceS', reproduceS)
			}
			
			function dataURLtoBlob(dataurl) {
			    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
			        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
			    while (n--) {
			        u8arr[n] = bstr.charCodeAt(n);
			    }
			    return new Blob([u8arr], { type: mime });
			}
		</script>
	</body>
</html>

posted @ 2021-11-17 16:43  小泽沐优声  阅读(37)  评论(0编辑  收藏  举报