SOURCE

console 命令行工具 X clear

                    
>
console
<!DOCTYPE html>
<html lang="zh-cmn-Hans">

<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style type="text/css">
        #settings {
            display: flex;
            margin: auto;
            margin-top: 100px;
            line-height: 27px;
            justify-content: center;
            gap: 20px;
        }

        #tablet {
            display: block;
            margin: auto;
            margin-top: 10px;
            background-color: #eee;
        }
    </style>
</head>

<body>
    <div>
        <div id="settings">
            <div>
                字体大小:
                <select id="fontSize"></select>
            </div>
            <div>
                字体颜色:
                <input type="color" id="fontColor" />
            </div>
            <button id="undo">撤销</button>
            <button id="clear">清空画布</button>
            <button id="download">生成图片</button>
        </div>
        <canvas width="800" height="300" id="tablet"></canvas>
    </div>

    <script>
        const tablet = document.getElementById('tablet')
        const ctx = tablet.getContext('2d')
        ctx.lineCap = 'round'
        ctx.lineJoin = 'round'
        ctx.lineWidth = 5
        ctx.strokeStyle = '#000'

        // 生成字体大小选项
        const fontSize = document.getElementById('fontSize')
        for (let i = 1; i <= 16; i++) {
            const option = document.createElement('option')
            option.value = i
            option.innerText = i + 'px'
            if (i == 5) {
                option.selected = true
            }
            fontSize.appendChild(option)
        }
        fontSize.addEventListener('change', (e) => {
            ctx.lineWidth = e.target.value
        })

        const fontColor = document.getElementById('fontColor')
        fontColor.addEventListener('change', (e) => {
            ctx.strokeStyle = e.target.value
        })
        let imageData
        let prex, prey
        const mousedown = (e) => {
            if (e.button != 0) return // 不是左键直接返回
            imageData = ctx.getImageData(0, 0, tablet.width, tablet.height)
            prex = e.offsetX
            prey = e.offsetY
            ctx.beginPath()
            ctx.moveTo(prex, prey)
            tablet.addEventListener('mousemove', mousemove)
            document.addEventListener('mouseup', mouseup)
            tablet.addEventListener('mouseenter', mouseenter)
        }
        const mousemove = (e) => {
            ctx.lineTo(e.offsetX, e.offsetY)
            ctx.stroke()
        }
        const mouseup = () => {
            tablet.removeEventListener('mousemove', mousemove)
            document.removeEventListener('mouseup', mouseup)
            tablet.removeEventListener('mouseenter', mouseenter)
        }
        const mouseenter = (e) => {
            prex = e.offsetX
            prey = e.offsetY
            ctx.moveTo(prex, prey)
        }
        tablet.addEventListener('mousedown', mousedown)

        const undo = document.getElementById('undo')
        undo.addEventListener('click', () => {
            ctx.putImageData(imageData, 0, 0)
        })

        const clear = document.getElementById('clear')
        clear.addEventListener('click', () => {
            ctx.clearRect(0, 0, tablet.width, tablet.height)
        })

        let a
        const download = document.getElementById('download')
        download.addEventListener('click', () => {
            if (!a) {
                a = document.createElement('a')
            }
            a.href = tablet.toDataURL()
            a.download = '签名.png'
            a.click()
        })
    </script>
</body>

</html>