canvas 电子签名
PC端鼠标版本
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title> <style type="text/css"> * {margin: 0;padding: 0;} .music-play {margin: 100px;} .music-play canvas {border: 1px solid #ccc;} .btns {text-align: center;} .btn {width: 100px;display: inline-block;margin-right: 20px;background-color: red; height: 50px;line-height: 50px;color: #fff;} </style> </head> <body> <div class="music-play"> <canvas width="500" height="500"></canvas> </div> <div class="btns"> <div class="btn" onclick="reset()">重置</div> <div class="btn" onclick="down()">下载</div> </div> </body> <script type="text/javascript"> window.onload = function() { const oc = document.querySelector('canvas'); oc.width = document.documentElement.offsetWidth * 0.8; if (oc.getContext('2d')) { const ctx = oc.getContext('2d'); ctx.save(); ctx.fillStyle = "#FFFFFF"; ctx.fillRect(0, 0, oc.width, oc.height); ctx.restore(); ctx.strokeStyle = "#ff0000"; ctx.lineWidth = 3; oc.onmousedown = function(e) { ctx.beginPath(); ctx.moveTo(e.clientX - oc.offsetLeft, e.clientY - oc.offsetTop); oc.onmousemove = function(e) { ctx.lineTo(e.clientX - oc.offsetLeft, e.clientY - oc.offsetTop); ctx.stroke(); }; oc.onmouseup = function(e) { oc.onmousemove = null; } } } } function reset() { const oc = document.querySelector('canvas'); if (oc.getContext('2d')) { const ctx = oc.getContext('2d'); ctx.clearRect(0, 0, oc.width, oc.height); } } function down() { const oc = document.querySelector('canvas'); var a = document.createElement('a'); a.download = '电子签名'; a.href = oc.toDataURL('image/jpeg'); a.click(); } </script> </html>
移动端版本:抗锯齿
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <title></title> <style type="text/css"> * {margin: 0;padding: 0;} html, body {height: 100%;overflow: hidden;} .music-play {width: 90%;margin: 0 auto;border: 1px solid #ccc;margin-bottom: 30px;margin-top: 20px;} .btns {text-align: center;} .btn {width: 100px;display: inline-block;margin-right: 20px;background-color: red; height: 36px;line-height: 36px;color: #fff;} .btn:last-child {margin-right: 0;} </style> </head> <body> <div class="music-play"> <canvas height="600" width="1068" style="width: 356px; height: 544px;"></canvas> </div> </body> <script type="text/javascript"> window.onload = function() { const oc = document.querySelector('canvas'); if (oc.getContext('2d')) { const ctx = oc.getContext('2d'); ctx.save(); ctx.fillStyle = "#FFFFFF"; ctx.fillRect(0, 0, oc.width, oc.height); ctx.restore(); oc.ontouchstart = function(e) { ctx.beginPath(); const {clientX, clientY} = e.changedTouches[0]; ctx.moveTo(clientX - oc.offsetLeft, clientY - oc.offsetTop); oc.ontouchmove = function(e) { const {clientX, clientY} = e.changedTouches[0]; ctx.lineTo(clientX - oc.offsetLeft, clientY - oc.offsetTop); ctx.stroke(); }; oc.ontouchend = function(e) { oc.ontouchmove = null; } } // 根据设备像素比优化canvas绘图 const {width, height} = oc; const devicePixelRatio = window.devicePixelRatio; if (devicePixelRatio) { oc.style.width = `${width}px`; oc.style.height = `${height}px`; oc.height = height * devicePixelRatio; // 画布宽高放大 oc.width = width * devicePixelRatio; ctx.scale(devicePixelRatio, devicePixelRatio); // 画布内容放大相同的倍数 } else { oc.width = width; oc.height = height; } ctx.strokeStyle = "#ff0000"; ctx.lineWidth = 6; ctx.lineCap = 'round'; // 直线首尾端圆滑 ctx.lineJoin = 'round'; // 当两条线条交汇时,创建圆形边角 ctx.shadowBlur = 1; // 边缘模糊,防止直线边缘出现锯齿 ctx.shadowColor = 'black'; // 边缘颜色 } } function reset() { const oc = document.querySelector('canvas'); if (oc.getContext('2d')) { const ctx = oc.getContext('2d'); ctx.clearRect(0, 0, oc.width, oc.height); } } function down() { const oc = document.querySelector('canvas'); var a = document.createElement('a'); a.download = 'sign.jpg'; a.href = oc.toDataURL('image/jpeg'); a.click(); } </script> </html>
掌控自己,掌控命运