canvas-学写字
一、逻辑思维
- 初始化的时候加入画布,先画田字格,方法很简单,线条画
- 四种操作,点击(onmousedown),移开(onmouseup),移走(onmouseout),移动(onmousemove)
- 点击的时候进行操作:记录点击区域坐标,可以画
- 移开,移走的时候进行操作:不可以画
- 移动:记录位置变化,记录速度改变线宽,连接线条,上一次位置,上一次时间,上一次线宽不断更替
- 速度算法,自由发挥
二、代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>writeFont</title> </head> <body> <canvas id="canvas" width="500" height="500"></canvas> <script> window.onload = function () { var canvas = document.getElementById("canvas"); var context = canvas.getContext('2d'); var color = 'green'; drawGrid(); // 画田字格 function drawGrid() { context.save(); context.strokeStyle = "rgb(230,11,9)"; context.beginPath(); context.moveTo(3, 3); context.lineTo(canvas.width - 3, 3); context.lineTo(canvas.width - 3, canvas.height - 3); context.lineTo(3, canvas.height - 3); context.closePath(); context.lineWidth = 6; context.stroke(); context.beginPath(); context.moveTo(0, 0); context.lineTo(canvas.width, canvas.height); context.moveTo(canvas.width, 0); context.lineTo(0, canvas.height); context.moveTo(canvas.width / 2, 0); context.lineTo(canvas.width / 2, canvas.height); context.moveTo(0, canvas.width / 2); context.lineTo(canvas.width, canvas.height / 2); context.lineWidth = 1; context.stroke(); context.restore(); } var isMouseDown = false; //鼠标是否按下 var lastLoc = { x: null, y: null };//鼠标上一次所在位置 var lastTimestamp = 0;//时间戳 var lastLineWidth = -1;//上一次线条宽度 //鼠标按下 canvas.onmousedown = function (e) { e.preventDefault(); initLoc(e.clientX, e.clientY); isMouseDown = true; } //鼠标起来 canvas.onmouseup = function (e) { e.preventDefault(); isMouseDown = false; } //鼠标离开 canvas.onmouseout = function (e) { e.preventDefault(); isMouseDown = false; } //鼠标移动 canvas.onmousemove = function (e) { e.preventDefault(); if (isMouseDown) { //draw var curLoc = windowToCanvas(e.clientX, e.clientY);//获得当前坐标 var curTimestamp = new Date().getTime();//当前时间 var s = calcDistance(curLoc, lastLoc);//获得运笔距离 var t = curTimestamp - lastTimestamp;//运笔时间 var lineWidth = calcLineWidth(t, s); context.lineWidth = lineWidth; context.beginPath(); context.moveTo(lastLoc.x, lastLoc.y); context.lineTo(curLoc.x, curLoc.y); context.strokeStyle = color; context.lineCap = "round" context.lineJoin = "round" context.stroke(); lastLoc = curLoc; lastLineWidth = lineWidth; lastTimestamp = curTimestamp; } } //获得canvas坐标 function windowToCanvas(x, y) { var bbox = canvas.getBoundingClientRect(); return { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) }; if(!lastLoc.x){ lastLoc = { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) }; } } //初始化上一次loc坐标 function initLoc(x, y) { var bbox = canvas.getBoundingClientRect(); lastLoc = { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) }; } //求两点之间距离 function calcDistance(loc1, loc2) { return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y)); } //求速度 function calcLineWidth(t, s) { var v = s / t; var resultLineWidth; if (v <= 0.1) { resultLineWidth = 30; } else if (v >= 10) { resultLineWidth = 1; } else { resultLineWidth = 30 - (v - 0.1) / (10 - 0.1) * (30 - 1); } if (lastLineWidth == -1) { return resultLineWidth; } return lastLineWidth * 2 / 3 + resultLineWidth * 1 / 3; } } </script> </body> </html>