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


先上效果图

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



微蓝网际编程论坛- 版权声明 1、本主题所有言论和图片纯属会员个人意见,与微蓝网际编程论坛立场无关。
2、本站所有主题由该帖子作者发表,该帖子作者귀하다 하지 않微蓝网际编程论坛享有帖子相关版权。
3、微蓝网际编程论坛管理员和版主有权不事先通知发贴者而删除本文。
4、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者귀하다 하지 않微蓝网际编程论坛的同意。
5、帖子作者须承担一切因本文发表而直接或间接导致的民事或刑事法律责任。
6、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责。
7、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意。


上一篇:js阻止表单提交
下一篇:Vue前端UI组件集合
快速回复
什么都想要的人,什么都得不到,所以要学会抓住重点,放弃那些不认真对待你的人
最新回复 (2)
只看楼主
全部楼主
  • 管理员组 admin
    0 引用 2


    3月前
    3月前 回复
  • 一级用户组 귀하다 하지 않
    0 引用 3
    (≧▽≦)/ (•̀へ•╮) .(。•ˇ‸•。)
    3月前
    3月前 回复
    • 微蓝网际编程论坛
      4
          
返回
免责声明:本站部分内容来源于网络,若有侵权请及时通知(aiweline@qq.com),我们会及时处理。