浏览文章

文章信息

用canvas实现写毛笔字功能,根据停留时间改变笔画粗细 39902

先上效果图

HTML代码
<!DOCTYPE html
    PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=yes">
    <title></title>

    <script src="./jquery-2.1.3.min.js" type="text/javascript"></script>

    <!-- <link rel="stylesheet" type="text/css" href="./style.css"> -->
 <style>
     /* #canvas{
         background: url(./1.png) no-repeat center center;
         background-size: 100% 100%;

     } */

/* CSS Document */

#canvas
{
    display:block;
    margin:0 auto;
    border:1px solid #aaa;
    
    
}
#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 ;
    cursor:pointer;
    background:#fff;
    font-weight:bold;
    font-family: Microsoft Yahei, Arial;
}

.op_btn
{
    background-color:#def;
}

.clearfix{
    clear:both;
}

.color_btn{
    floatleft;
    margin10px 10px 0 0;
    border:5px solid white;
    width:40px;
    height:40px;
    border-radius5px 5px;
    cursor:pointer;
}
.color_btn:hover{
    border5px solid violet;
}
.color_btn_selected{
    border5px solid blueviolet;
}
#black_btn{
    background-colorblack;
}
#blue_btn{
    background-colorblue;
}
#green_btn{
    background-colorgreen;
}
#red_btn{
    background-colorred;
}
#orange_btn{
    background-colororange;
}
#yellow_btn{
    background-coloryellow;
}
 </style>
</head>

<body>

    <canvas id="canvas" width="800" height="800">你的浏览器不支持canvas</canvas>

    <div id="controller" style="width: 800px;">
        <div id="black_btn" class="color_btn "></div>
        <div id="blue_btn" class="color_btn color_btn_selected"></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="./handwrite.js"></script>
    <div style="text-align:center;margin:50px 0;">
    </div>

</body>

</html>
handwrite.js
// JavaScript Documentvar 

//为了手机端的自适应;
      var canvasWidth=Math.min(800,$(window).width()-20);
      var ResultLineWidth=1;
      var canvasHeight=canvasWidth;
      //判断是都按下鼠标
      var isMouseDown=false;
      //记录上一次鼠标所在位置
      var lasloc={x:0,y:0};
      var lasTimeStamp=0;
      var laslinewidth=-1;
      var strokeColor="blue";
      
      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();
        }
      )
    
//使用jQuery对颜色按钮进行操作
$(".color_btn").click(
   function(e)
    {
        $(".color_btn").removeClass("color_btn_selected");
        $(this).addClass("color_btn_selected");
        strokeColor=$(this).css("background-color");
    
     }

)     


    function beginStock(point)
    {
         isMouseDown=true;
         
         //console.log("mousedown");
         lasloc=windowToCanvas(point.x,point.y);
         lasTimeStamp=new Date().getTime();
    }
  
      function endStock(point)
    {
        isMouseDown=false;
    }
     
     function moveStock(point)
     {
         
         var curloc=windowToCanvas(point.x,point.y);      
              var curTimeStamp=new Date().getTime();
              
              var s=calDistangce(curloc,lasloc);
              var t=curTimeStamp-lasTimeStamp;
              
              var lineWidth=CalClientWidth(t,s);
               
              
              //具体的绘制,鼠标按下之后
               context.beginPath();
               context.moveTo(lasloc.x,lasloc.y);
               context.lineTo(curloc.x,curloc.y);
               context.strokeStyle=strokeColor;
               context.lineWidth=lineWidth;
               //设置线条的帽子,是线条平滑
               context.lineCap="round";
               context.lineJoin="round";
               context.stroke();
              
              
               lasloc=curloc;
               lasTimeStamp=curTimeStamp;
               laslinewidth=ResultLineWidth;
     } 
     
     
     
     
     
     
     //鼠标按下
     canvas.onmousedown=function(e)
     {
         //阻止默认事件响应
         e.preventDefault();
         beginStock({x:e.clientX,y:e.clientY});
         //当前的canvas画布上的坐标点  alert(loc.x+","+loc.y);
     };
     
     //鼠标松开
      canvas.onmouseup=function(e)
     {
         e.preventDefault();
         endStock();
         
         //console.log("mouseup");
     };
    //鼠标移出指定对象时发生 
     canvas.onmouseout=function(e)
     {
         e.preventDefault();
         endStock();
         //console.log("mouseout");
     };
     
     //鼠标移动过程中
     canvas.onmousemove=function(e)
     {
         e.preventDefault();
         if(isMouseDown)
         {
             //console.log("mousemove");
              moveStock({x:e.clientX,y:e.clientY}); 
         }
     };
//移动端(触碰相关的事件)
canvas.addEventListener('touchstart',function(e){
     e.preventDefault();
     //触碰事件,也可能是多点触碰,就是第一个
     touch=e.touches[0];
     beginStock({x:touch.pageX,y:touch.pageY});
    
    
});
canvas.addEventListener('touchmove',function(e){
     e.preventDefault();
    
     if(isMouseDown)
         {
             //console.log("mousemove");
            touch=e.touches[0];
            moveStock({x:touch.pageX,y:touch.pageY});
    
         }
}); 
canvas.addEventListener('touchend',function(e){
     e.preventDefault();
     endStock();
    
}); 
//移动端(触碰相关的事件)结束 



function Drawgrid(){ 
      context.save(); 
      
       context.strokeStyle = "rgb(230,11,9)"

    context.beginPath()
    context.moveTo3 , 3 )
    context.lineTo( canvasWidth - 3 , 3 )
    context.lineTo( canvasWidth - 3 , canvasHeight - 3 )
    context.lineTo3 , 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(); 
    }
      
    //屏幕坐标点转化为canvas画布坐标    ,定位canvas画布上的坐标 
function windowToCanvas(x,y)
{
    //包含canvas距离画布的上和左边距
    var bbox=canvas.getBoundingClientRect();
    return {x:Math.round(x-bbox.left),y:Math.round(y-bbox.top)}

}
 
 
//通过两点计算出两点之间距离
function calDistangce(loc1,loc2)
{
    return Math.sqrt((loc1.x-loc2.x)*(loc1.x-loc2.x)+(loc1.y-loc2.y)*(loc1.y-loc2.y));
}  
 
//笔画速度越快,笔越细,反之越粗!
var maxlinewidth=30;
var minlinewidth=1
var maxlinespeed=10;
var minlinespeed=0.1
function CalClientWidth(t,s)
{
    var v=s/t;
    var ResultLineWidth;
    //处理速度很慢和很快的情况
    if(v<=minlinespeed)
    
        ResultLineWidth=maxlinewidth;
    else if(v>=maxlinespeed)
             
                 ResultLineWidth=minlinewidth;
     else
             
                 ResultLineWidth=maxlinewidth-(v-minlinespeed)/(maxlinespeed-minlinespeed)*(maxlinewidth-minlinewidth);
    if(laslinewidth==-1)
               return ResultLineWidth;          
    return laslinewidth*2/3+ResultLineWidth*1/3;
    
}


原创