直接上代码
<!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;
100px;
font-size: 17px;
}
.right-item button {
margin-right: 5px;
}
.slot {
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 = `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 = `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 = `${(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>