一、逻辑思维
- 初始化的时候加入画布,先画田字格,方法很简单,线条画
- 四种操作,点击(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>