基于canvas写一个字的效果

页面html:

<!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>

页面css:

#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;
}

页面js:

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();
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值