利用canvas实现田字格里写字,并适配移动端

结构:

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>我们一起学写字</title>
    <script type="text/javascript" src="js/jquery.js"></script>
    <link type="text/css" rel="stylesheet" href="css/handwrite.css" />
    <meta name="viewport"
            content = "
            height = device-height,
            width = device-width,
            initial-scale = 1.0,
            mininum-scale = 1.0,
            maxnum-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 type="text/javascript" src="js/handwrite.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:white;
    font-weight:bold;
    font-family: Microsoft Yahi,Arial;
}
.op_btn:hover{
    background:#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;
}
行为:

/**
 * Created by liubowen on 16/4/11.
 */
var canvasWidth =Math.min(700,$(window).width() - 20);
var strokeColor = "black";
var LastLoc = {x:0,y:0};
var LastTime = 0;//利用时间戳的做法
var LastLineWidth = -1;
var canvasHeight = canvasWidth;
var isMouseDown = false;



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

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

//动态控制controller大小
$("#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 begainStroke(point){
    isMouseDown =true;
    LastLoc = windowToCanvas(point.x, point.y);
    LastTime = new Date().getTime();//返回当前时间戳
}
function endStroke(){
    isMouseDown = false;
}
function moveStroke(point){
    var curLoc = windowToCanvas(point.x, point.y);//得到当前鼠标点击的坐标
    var curTime = new Date().getTime();
    var  s = calcDistance(curLoc,LastLoc);
    var t = curTime - LastTime;
    var lineWidth = calcLineWidth(t,s);

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

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

    LastLoc = curLoc;
    LastTime = curTime;
    LastLineWidth = lineWidth;
}
canvas.onmousedown = function(e){
    e.preventDefault();//当用于移动端是阻止默认的事件响应
    //isMouseDown =true;
    //console.log("mouse down");
    //alert(e.clientX+","+ e.clientY);
    //LastLoc = windowToCanvas(e.clientX, e.clientY);
    //LastTime = new Date().getTime();//返回当前时间戳
    //alert(loc.x+","+loc.y);
    begainStroke({x:e.clientX,y:e.clientY});
};
canvas.onmouseup = function(e){
    e.preventDefault();//当用于移动端是阻止默认的事件响应
    //isMouseDown = false;
    //console.log("mouse up");
    endStroke();
};
canvas.onmouseout = function(e){
    e.preventDefault();//当用于移动端是阻止默认的事件响应
    //isMouseDown = false;
    //console.log("mouse out");
    endStroke();
};
canvas.onmousemove = function(e){
    e.preventDefault();//当用于移动端是阻止默认的事件响应
    if(isMouseDown){

        //console.log("mouse move");
        //var curLoc = windowToCanvas(e.clientX, e.clientY);//得到当前鼠标点击的坐标
        //var curTime = new Date().getTime();
        //var  s = calcDistance(curLoc,LastLoc);
        //var t = curTime - LastTime;
        //var lineWidth = calcLineWidth(t,s);
        //
        draw
        //context.beginPath();
        //context.moveTo(LastLoc.x , LastLoc.y);
        //context.lineTo(curLoc.x , curLoc.y);
        //
        //context.lineWidth = lineWidth;
        //context.lineCap = "round";
        //context.lineJoin = "round";
        //context.strokeStyle = strokeColor;
        //context.stroke();
        //
        //LastLoc = curLoc;
        //LastTime = curTime;
        //LastLineWidth = lineWidth;
        moveStroke({x: e.clientX,y: e.clientY});
    }
};

//触控相关的代码,利用监听器
canvas.addEventListener("touchstart",function(e){
    e.preventDefault();
    var touch = e.touches[0];//防止多点触控,以第0个触控为准
    begainStroke({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();
});

//找出适当的lineWidth

var maxLineWidth = 20;
var minLineWidth = 1;
var maxStrokeV = 10;
var minStrokeV = 0.1;
function calcLineWidth(t,s){
    var v = s/t;
    var resultLineWidth = 0;
    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 LastLineWidth*2/3 + resultLineWidth*1/3;
}
//找出mouseMove前后两点的距离
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();//拿到canvas的包围盒
    return {x:Math.round(x-bbox.left),y:Math.round(y-bbox.top)};
}
//drawGrid函数画出田字格
function drawGrid(){
    var curWidth = canvas.width;
    var curHeight = canvas.height;
    //。save()和.restore()让drawDrid()里面设置的状态不会影响以后的状态设置
    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);
    drawBash(0,0,10,10,700,700);
    drawBash1(curWidth,0,curHeight-10,10,700,700);
    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();
}
function drawBash(x1,y1,x2,y2){
    for(var i = 0;i<50;i++){
        context.beginPath();
        context.moveTo(x1,y1);
        context.lineTo(x2,y2);

        context.lineWidth =1;
        context.strokeStyle = "rgb(230,11,9)"
        context.stroke();
        x1+=15;
        x2+=15;
        y1+=15;
        y2+=15;
    }
}
function drawBash1(x1,y1,x2,y2){
    for(var i = 0;i<50;i++){
        context.beginPath();
        context.moveTo(x1,y1);
        context.lineTo(x2,y2);

        context.lineWidth =1;
        context.strokeStyle = "rgb(230,11,9)"
        context.stroke();
        x1-=15;
        x2-=15;
        y1+=15;
        y2+=15;
    }
}

作品为原创,请勿用于商业用途,仅供学习,参考


效果图:


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值