SOURCE

console 命令行工具 X clear

                    
>
console
var mouse = false
var lastPt = {}
var drawInfo = {
    color: 'green',
    size: 5
}

let colorInput = document.getElementById('myColor')
let sizeInput = document.getElementById('mySize')
let createBtn = document.getElementById('myPic')
colorInput.onchange = function (e) {
    drawInfo.color = e.target.value
}

sizeInput.onchange = function (e) {
    drawInfo.size = e.target.value
}
createBtn.onclick = () => {
    onSave()
}



let canvas = document.getElementById('canvas')
let { clientWidth, clientHeight } = document.body
canvas.width = clientWidth
canvas.height = clientHeight
let ctx = canvas.getContext('2d')
// console.log(5,clientHeight ,canvas );

if (window.PointerEvent) {
    canvas.addEventListener('pointerdown', handleMouseDown, false)
    canvas.addEventListener('pointermove', handleMouseMove, false)
    canvas.addEventListener('pointerup', handleMouseUp, false)
} else {
    canvas.addEventListener('mousedown', handleMouseDown, false)
    canvas.addEventListener('mousemove', handleMouseMove, false)
    canvas.addEventListener('mouseup', handleMouseUp, false)
}

function handleMouseDown(event) {
    mouse = true
    let { pageX, pageY } = event
    ctx.beginPath()
    ctx.moveTo(pageX, pageY)
}

function handleMouseMove(event) {
    if (mouse) {
        lastPt = {
            x: event.pageX,
            y: event.pageY
        }
        draw(lastPt)
    }
}

function handleMouseUp(event) {
    mouse = false
    lastPt = {}
    ctx.closePath()
}


function draw(info) {
    let { x, y } = info
    ctx.lineTo(x, y)
    ctx.strokeStyle = drawInfo.color || 'green'
    ctx.lineWidth = drawInfo.size || 3
    ctx.stroke()
}

// http://t.zoukankan.com/goloving-p-15325085.html   文件下载
async function onSave() {
    console.log(window.showSaveFilePicker)   // canvas.toDataURL('image/png')
    let cont = converBase64ToBlob(canvas.toDataURL('image/png'))
    if (window.showSaveFilePicker) {
        const handle = await window.showSaveFilePicker({
            suggestedName: "test.png",  // 生成文件默认名
            types: [
                {
                    description: "PNG file",
                    accept: {
                        "image/png": [".png"],
                    },
                },
                // {
                //     description: 'Text file',
                //     accept: {'text/plain': ['.txt']},
                // }
            ],
        });
        const writable = await handle.createWritable();
        await writable.write(cont);
        await writable.close();
        return handle;
    }else{
        // console.log(cont)
        const a = document.createElement('a')
        a.download = 'test.png' 
        a.href = URL.createObjectURL(cont) 
        console.log(102,a.href)
        a.click()
        URL.revokeObjectURL(a.href)
    }
}

// base64 转 blob
function converBase64ToBlob(base64) {
    var base64 = base64.split(','),
        imgtype = '',
        base64String = ''
    if (base64.length > 1) {
        base64String = base64[1]
        imgtype = base64[0].substring(base64[0].indexOf(':') + 1, base64[0].indexOf(';'))
    }

    var bytes = atob(base64String)
    bytesCode = new ArrayBuffer(bytes.length),
        byteArr = new Uint8Array(bytesCode)
    for (let i = 0; i < bytes.length; i++) {
        byteArr[i] = bytes.charCodeAt(i)
    }
    return new Blob([bytesCode], { type: imgtype })
}








/**
 canvas有三种清空方式
(1) 简单填充 使用一个新的背景色简单地填充整个画布,这样就可以清除当前内容 
    ctx.fillStyle = '#fff';  
    
    let rect = this.canvas.getBoundingClientRect();  
    
    ctx.fillRect(rect.x, rect.y, rect.width, rect.height)
(2)重置画布高度 当画布的宽或高被重置时,当前画布内容就会被移除。
    let rect = this.canvas.getBoundingClientRect();  
    
    canvas.width = rect.width;  
    
    canvas.height = rect.height;
(3)使用clearRect函数 clearRect() 函数可以指定起始点的x, y 位置以及宽度和高度来清除画布
    let rect = this.canvas.getBoundingClientRect();  
    
    this.ctx.clearRect(rect.x, rect.y, rect.width, rect.height);
 */












<canvas class='canvas' id="canvas" ></canvas>

<div id="opt">
    color : <input type="color" id="myColor" />
    size : <input type="number" id="mySize" />
    生成 : <button id ="myPic">生成</button>
</div>
html , body {
    width: 100vw;
    height: 100vh;
    overflow:hidden;
}

.canvas{  
    width: 90vw;  
    height: 90vh;
    border: 1px solid red;
}