SOURCE

console 命令行工具 X clear

                    
>
console
var canvasWidth = Math.min(800, $(window).width() - 20);//如果屏幕小于800px,则取值为屏幕大小宽度,便于移动端的展示,-20是为了使得米字格不紧贴于边缘
var canvasHeight = canvasWidth;

var strokeColor = "black";
var isMouseDown = false; //鼠标按下时候的状态
var lastLoc = { x: 0, y: 0 }; //鼠标上一次结束时的位置
var lastTimestamp = 0; //上一次时间,与笔刷粗细有关
var lastLineWidth = -1; //笔刷粗细

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

canvas.width = canvasWidth;
canvas.height = canvasHeight;

$("#controller").css("width", canvasWidth + "px");
drawGrid();//画米字格

$("#clear_btn").click(
    function (e) {
        context.clearRect(0, 0, canvasWidth, canvasHeight);
        drawGrid();
    }
)
$(".color_btn").click(
    function (e) {
        $(".color_btn").removeClass("color_btn_selected");
        $(this).addClass("color_btn_selected");
        strokeColor = $(this).css("background-color");
    }
)
//适用于移动端触控
function beginStroke(point) {

    isMouseDown = true
    //console.log("mouse down!");
    lastLoc = windowToCanvas(point.x, point.y); //上一次坐标位置
    lastTimestamp = new Date().getTime();

}
function endStroke() {
    isMouseDown = false;
}
function moveStroke(point) {

    var curLoc = windowToCanvas(point.x, point.y);
    var curTimestamp = new Date().getTime();
    var s = calcDistance(curLoc, lastLoc);
    var t = curTimestamp - lastTimestamp;

    var lineWidth = calcLineWidth(t, s);

    //draw
    context.beginPath();
    context.moveTo(lastLoc.x, lastLoc.y);
    context.lineTo(curLoc.x, curLoc.y);

    context.strokeStyle = strokeColor;
    context.lineWidth = lineWidth;
    context.lineCap = "round";
    context.lineJoin = "round";
    context.stroke();

    lastLoc = curLoc;
    lastTimestamp = curTimestamp;
    lastLineWidth = lineWidth;
}

canvas.onmousedown = function (e) {
    e.preventDefault();
    beginStroke({ x: e.clientX, y: e.clientY });
};
canvas.onmouseup = function (e) {
    e.preventDefault();
    endStroke();
};
canvas.onmouseout = function (e) {
    e.preventDefault();
    endStroke();
};
canvas.onmousemove = function (e) {
    e.preventDefault();
    if (isMouseDown) {
        moveStroke({ x: e.clientX, y: e.clientY })
    }
};

canvas.addEventListener('touchstart', function (e) {
    e.preventDefault();
    touch = e.touches[0];
    beginStroke({ x: touch.pageX, y: touch.pageY })
});
canvas.addEventListener('touchmove', function (e) {
    e.preventDefault();
    if (isMouseDown) {
        touch = e.touches[0];
        moveStroke({ x: touch.pageX, y: touch.pageY });
    }
});
canvas.addEventListener('touchend', function (e) {
    e.preventDefault();
    endStroke();
});

var maxLineWidth = 30;
var minLineWidth = 1;
var maxStrokeV = 10;
var minStrokeV = 0.1;
function calcLineWidth(t, s) {

    var v = s / t;

    var resultLineWidth;
    if (v <= minStrokeV)
        resultLineWidth = maxLineWidth;
    else if (v >= maxStrokeV)
        resultLineWidth = minLineWidth;
    else {
        resultLineWidth = maxLineWidth - (v - minStrokeV) / (maxStrokeV - minStrokeV) * (maxLineWidth - minLineWidth);
    }

    if (lastLineWidth == -1)
        return resultLineWidth;

    return resultLineWidth * 1 / 3 + lastLineWidth * 2 / 3;
}

function calcDistance(loc1, loc2) {

    return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y));
}

function windowToCanvas(x, y) {
    var bbox = canvas.getBoundingClientRect();
    return { x: Math.round(x - bbox.left), y: Math.round(y - bbox.top) }
}
function drawGrid() {

    context.save();

    context.strokeStyle = "rgb(230,11,9)";

    context.beginPath();
    context.moveTo(3, 3);
    context.lineTo(canvasWidth - 3, 3);
    context.lineTo(canvasWidth - 3, canvasHeight - 3);
    context.lineTo(3, canvasHeight - 3);
    context.closePath();
    context.lineWidth = 6;
    context.stroke();

    context.beginPath();
    context.moveTo(0, 0);
    context.lineTo(canvasWidth, canvasHeight);

    context.moveTo(canvasWidth, 0);
    context.lineTo(0, canvasHeight);

    context.moveTo(canvasWidth / 2, 0);
    context.lineTo(canvasWidth / 2, canvasHeight);

    context.moveTo(0, canvasHeight / 2);
    context.lineTo(canvasWidth, canvasHeight / 2);

    context.lineWidth = 1;
    context.stroke();

    context.restore();
}
<!DOCTYPE html>
<html>

<head lang="en">
	<meta charset="UTF-8">
	<title>学写一个字</title>
	<script src="jquery-2.1.3.min.js" type="text/javascript">
	</script>
	<link href="handwriting.css" rel="stylesheet" type="text/css" />
	<meta name="viewport" content=" height = device-height,
     width = device-width,
     initial-scale = 1.0,
     minimum-scale = 1.0,
     maximum-scale = 1.0,
     user-scalable = no" /> //兼容移动端

</head>

<body>

	<canvas id="canvas">
		您的浏览器不支持canvas
	</canvas>//写字区域
	<div id="controller">
		<div id="black_btn" class="color_btn color_btn_selected"></div>
		<div id="blue_btn" class="color_btn"></div>
		<div id="green_btn" class="color_btn"></div>
		<div id="red_btn" class="color_btn"></div>
		<div id="orange_btn" class="color_btn"></div>
		<div id="yellow_btn" class="color_btn"></div>

		<div id="clear_btn" class="op_btn">清 除</div>
		<div class="clearfix"></div>
	</div>

	<script src="handwriting.js">
	</script>
</body>

</html>
#canvas{
 display:block;
 margin:0 auto;
}
#controller{
 margin:0 auto;
}
.op_btn{
 float: right;
 margin:10px 0 0 10px;
 border:2px solid #aaa;
 width:80px;
 height:40px;
 line-height:40px;
 font-size:20px;
 text-align:center;
 border-radius: 5px 5px;
 cursor:pointer;
 background-color: white;
 font-weight:bold;
 font-family: Microsoft Yahei, Arial;
}
.op_btn:hover{
 background-color:#def;
}
.clearfix{
 clear:both;
}
 
.color_btn{
 float: left;
 margin: 10px 10px 0 0;
 border:5px solid white;
 width:40px;
 height:40px;
 border-radius: 5px 5px;
 cursor:pointer;
}
.color_btn:hover{
 border: 5px solid violet;
}
.color_btn_selected{
 border: 5px solid blueviolet;
}
#black_btn{
 background-color: black;
}
#blue_btn{
 background-color: blue;
}
#green_btn{
 background-color: green;
}
#red_btn{
 background-color: red;
}
#orange_btn{
 background-color: orange;
}
#yellow_btn{
 background-color: yellow;
}

本项目引用的自定义外部资源