这里是我用html5制作的web APP,功能比较少,待扩充。
这个web APP是通过慕课网,学习liuyubobobo老师的《学写一个字》课程而制作的,功能还比较简单,我可能会慢慢完善它。传送门
<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="red_btn" class="color_btn"></div>
<div id="yellow_btn" class="color_btn"></div>
<div id="green_btn" class="color_btn"></div>
<div id="orange_btn" class="color_btn"></div>
<div id="clear_btn" class="op_btn">清 除</div>
<div class="clearfix"></div>
</div>
#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: 5px 5px 0 0;
border: 5px solid white;
border-radius: 5px 5px;
cursor: pointer;
}
.color_btn:hover{
border: 5px solid violet;
}
.color_btn_selected{
border: 5px solid violet;
}
#black_btn{
background-color: black;
}
#blue_btn{
background-color: blue;
}
#red_btn{
background-color: red;
}
#yellow_btn{
background-color: yellow;
}
#green_btn{
background-color: green;
}
#orange_btn{
background-color: orange;
}
$(function(){
var canvasWidth = Math.min(700, $(window).width() - 70);
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');
$('.color_btn').css({'width':canvasWidth/10 + 'px','height':canvasWidth/10 + '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;
lastLoc = windowsToCanvas(point.x,point.y);
lastTimestamp = new Date().getTime();
};
function endStroke(){
isMouseDown = false;
};
function moveStroke(point){
var curLoc = windowsToCanvas(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();
// console.log('mouse down');
beginStroke({x:e.clientX,y:e.clientY});
};
canvas.onmouseup = function(e){
e.preventDefault();
// console.log('mouse up');
endStroke();
};
canvas.onmouseout = function(e){
e.preventDefault();
// console.log('mouse out');
endStroke();
};
canvas.onmousemove = function(e){
e.preventDefault();
if(isMouseDown){
// console.log('mouse move');
moveStroke({x:e.clientX,y:e.clientY})
}
};
canvas.addEventListener('touchstart',function(e){
e.preventDefault();
touch = e.touches[0];
beginStroke({x:touch.clientX,y:touch.clientY});
});
canvas.addEventListener('touchmove',function(e){
e.preventDefault();
touch = e.touches[0];
moveStroke({x:touch.clientX,y:touch.clientY});
});
canvas.addEventListener('touchend',function(e){
e.preventDefault();
endStroke();
});
// 线条粗细
function calcLineWidth(t,s){
var maxLineWidth = Math.min(30, canvasWidth / 30);
var minLineWidth = 1;
var maxStrokeV = 10;
var minStrokeV = 0.1;
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;
}
else{
return lastLineWidth * 0.9 + resultLineWidth * 0.1;
}
};
// 两点间距离
function calcDistance(loc1,loc2){
return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y))
};
// 窗口坐标转canvas坐标
function windowsToCanvas(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.lineWidth = 6;
context.strokeRect(3,3,canvasWidth - 6,canvasHeight - 6);
context.lineWidth = 1;
drawDashes(context, 0, 0, canvasWidth, canvasHeight);
drawDashes(context, canvasWidth, 0, 0, canvasHeight);
drawDashes(context, canvasWidth / 2, 0, canvasWidth / 2, canvasHeight);
drawDashes(context, 0, canvasHeight / 2, canvasWidth, canvasHeight / 2);
context.restore();
};
// 绘制虚线
function drawDashes(ctx, x1, y1, x2, y2, dashLength){
ctx.beginPath();
var dashLen = dashLength === undefined ? 5:dashLength;
xpos = x2 - x1;
ypos = y2 - y1;
numDashs = Math.floor(Math.sqrt(xpos*xpos + ypos*ypos)/dashLen);
for (var i = 0; i < numDashs; i++) {
if(i%2 === 0){
ctx.moveTo(x1 + (xpos/numDashs)*i, y1 + (ypos/numDashs)*i);
}
else{
ctx.lineTo(x1 + (xpos/numDashs)*i, y1 + (ypos/numDashs)*i);
}
};
ctx.stroke();
ctx.closePath();
};
});