canvas批阅-添加对错以及箭头文字图形等,可撤销可保存

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<title>Document</title>  
<style type="text/css">
    body{font:16px/1 "Microsoft Yahei","微软雅黑",'Arial Negreta', 'Arial';}
    canvas{border:1px solid #000000; cursor: crosshair;}
    .hide{display: none;}
    #txt{position: absolute; top: 1%; left: 1%; width: 575px; height: 30px; border:1px solid #e42343;}
    #word{position: absolute;width: 220px; height: 80px; padding: 0 2px; background:none; color:#e42343; border: 1px dashed #b9b9b9; font-size: 15px; font-family: "微软雅黑", "arial"; }
    #word::-webkit-input-placeholder{color:#e42343; font-family: "微软雅黑", "arial";}
    #word::-moz-placeholder{color:#e42343;font-family: "微软雅黑", "arial";}
    #word::placeholder{color:#e42343; font-family: "微软雅黑", "arial";}
</style>
</head>  
<body>
  <button type="button" class="btn btn-warning" onclick="true1();" >正确</button>
  <button type="button" class="btn btn-warning" onclick="error1();" >错误</button>
  <button onclick="pen();">画笔</button>
  <button onclick="arrow();">箭头</button>
  <button onclick="rect();">矩形</button>
  <!--<button onclick="text();">text</button>-->
  <button onclick="word1();">文字</button>
  <button onclick="put();">上一步</button>
  <button onclick="restuya();">清除批注</button>
  <button onclick="back();">回退</button>
  <button onclick="saveTu();">保存</button>
<hr>

<div style="position: relative;">
  <canvas id="canvas" width="700"  height="500" >
    您的浏览器不支持绘图,请升级或更换浏览器!
  </canvas>
  <input type="text" value="" class="hide" id="txt" placeholder="请输入文字">
  <textarea class="hide" id="word" cols="30" rows="10"  placeholder="请输入文字" autofocus></textarea>
  <input id="inputV" type="hidden"  value="1">
</div>
<hr>
  <div id="res"></div>

<script type="text/javascript">  
    var canvas = document.getElementById('canvas');   
    var ctx = canvas.getContext('2d'); 
    var myCanvas_rect = canvas.getBoundingClientRect();
    var Txt = document.getElementById('txt');
    var word = document.getElementById('word');
    var widths = myCanvas_rect.width;
    var heights = myCanvas_rect.height;
    var lineW = 3;
    var lineWPen = 2;
    var colorF="#e42343";
    var colorT="#50f596";
    var imgData;
    var preDrawAry = new Array();

    //引入图片背景路径
    var imgs = new Image();  
    imgs.src = "images/stu.png";
    imgs.onload = drawImg;

    //图片加载完成再执行
    function drawImg(){  
        ctx.drawImage(imgs,0,0,widths,heights);  
    };

    // 对号
    function true1(){
            Txt.style.display="none";
            word.style.display="none";
            ctx.closePath();
            canvas.onmousedown=function (ev) {
            imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
            preDrawAry.push(imgData);
            ctx.beginPath();
            ctx.strokeStyle = colorT;
            ctx.lineWidth = lineW;
            ctx.lineJoin="round";
            };
            canvas.onmouseup=function (ev) {
                //鼠标按下的位置
                var oldX = ev.offsetX;
                var oldY = ev.offsetY;
                console.log(oldX,oldY);
                ctx.moveTo(oldX,oldY);
                ctx.lineTo(ev.offsetX+20,ev.offsetY+20);
                ctx.lineTo(ev.offsetX+60,ev.offsetY-10);
                ctx.stroke();
            }
    };

    // 叉号
    function error1(){
           Txt.style.display="none";
            word.style.display="none";
           ctx.closePath();
           canvas.onmousedown=function (ev) {
            imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
            preDrawAry.push(imgData);
            ctx.beginPath();
            ctx.strokeStyle = colorF;
            ctx.lineWidth = lineW;
            ctx.lineJoin="round";
           };
            //鼠标按下的位置
            canvas.onmouseup=function (ev) {
                var oldX = ev.offsetX;
                var oldY = ev.offsetY;
                ctx.moveTo(oldX,oldY);
                ctx.lineTo(ev.offsetX+30,ev.offsetY+30);
                ctx.moveTo(ev.offsetX+30,ev.offsetY);
                ctx.lineTo(ev.offsetX,ev.offsetY+30);
                ctx.stroke();
            };
            ctx.closePath();
    };

    // 画笔
    function pen(){
          Txt.style.display="none";
          word.style.display="none";
          var last;
          // 鼠标按下  
          canvas.onmousedown = function(){  
              // 在鼠标按下后触发鼠标移动事件  
              canvas.onmousemove = move;  
              imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
              preDrawAry.push(imgData);
          }  
        
          // 鼠标抬起取消鼠标移动的事件  
          canvas.onmouseup = function(){  
              canvas.onmousemove = null;    
              last = null;  
          }  
        
          // 鼠标移出画布时 移动事件取消  
          canvas.onmouseout = function(){  
              canvas.onmousemove = null;  
              last = null;  
          }  
           // 鼠标移动函数  
            function move(e){  
                // console.log(e.offsetX);  
                if(last != null){  
                    ctx.beginPath();  
                    ctx.lineWidth = lineWPen;
                    ctx.strokeStyle = colorF;
                    ctx.moveTo(last[0],last[1]);  
                    ctx.lineTo(e.offsetX,e.offsetY);  
                    ctx.stroke();  
                }         
                // 第一次触发这个函数,只做一件事,把当前 鼠标的 x , y 的位置记录下来  
                // 做下一次 线段的 起始点。  
                last = [e.offsetX,e.offsetY];  
          
            }  
    };

    // 箭头
    function arrow(){
           Txt.style.display="none";
           word.style.display="none";
           var beginPoint = {},
           stopPoint = {},
           polygonVertex = [],
           CONST = {
               edgeLen:100,
               angle: 50
           };
            var Plot = {
               angle: "",
               //短距离画箭头的时候会出现箭头头部过大,修改:
               dynArrowSize: function() {
                   var x = stopPoint.x - beginPoint.x,
                       y = stopPoint.y - beginPoint.y,
                       length = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
                       if (length < 250) {
                           CONST.edgeLen = CONST.edgeLen/2;
                           CONST.angle = CONST.angle/2;
                       }
                       else if(length<500){
                           CONST.edgeLen=CONST.edgeLen*length/500;
                           CONST.angle=CONST.angle*length/500;
                       }
//                    console.log(length);
               },
               //getRadian 返回以起点与X轴之间的夹角角度值
               getRadian: function(beginPoint, stopPoint) {
                   Plot.angle = Math.atan2(stopPoint.y - beginPoint.y, stopPoint.x - beginPoint.x) / Math.PI * 180;
                   console.log(Plot.angle);
                   paraDef(50,25);
                   Plot.dynArrowSize();
               },
               ///获得箭头底边两个点
               arrowCoord: function(beginPoint, stopPoint) {
                   polygonVertex[0] = beginPoint.x;
                   polygonVertex[1] = beginPoint.y;
                   polygonVertex[6] = stopPoint.x;
                   polygonVertex[7] = stopPoint.y;
                   Plot.getRadian(beginPoint, stopPoint);
                   polygonVertex[8] = stopPoint.x - CONST.edgeLen * Math.cos(Math.PI / 180 * (Plot.angle + CONST.angle));
                   polygonVertex[9] = stopPoint.y - CONST.edgeLen * Math.sin(Math.PI / 180 * (Plot.angle + CONST.angle));
                   polygonVertex[4] = stopPoint.x - CONST.edgeLen * Math.cos(Math.PI / 180 * (Plot.angle - CONST.angle));
                   polygonVertex[5] = stopPoint.y - CONST.edgeLen * Math.sin(Math.PI / 180 * (Plot.angle - CONST.angle));
               },
               //获取另两个底边侧面点
               sideCoord: function() {
                   var midpoint = {};
                   // midpoint.x = polygonVertex[6] - (CONST.edgeLen * Math.cos(Plot.angle * Math.PI / 180));
                   // midpoint.y = polygonVertex[7] - (CONST.edgeLen * Math.sin(Plot.angle * Math.PI / 180));
                   midpoint.x=(polygonVertex[4]+polygonVertex[8])/2;
                   midpoint.y=(polygonVertex[5]+polygonVertex[9])/2;
                   polygonVertex[2] = (polygonVertex[4] + midpoint.x) / 2;
                   polygonVertex[3] = (polygonVertex[5] + midpoint.y) / 2;
                   polygonVertex[10] = (polygonVertex[8] + midpoint.x) / 2;
                   polygonVertex[11] = (polygonVertex[9] + midpoint.y) / 2;
               },

               //画箭头
               drawArrow: function() {
                   ctx.beginPath();
                   ctx.moveTo(polygonVertex[0], polygonVertex[1]);
                   ctx.lineTo(polygonVertex[2], polygonVertex[3]);
                   ctx.lineTo(polygonVertex[4], polygonVertex[5]);
                   ctx.lineTo(polygonVertex[6], polygonVertex[7]);
                   ctx.lineTo(polygonVertex[8], polygonVertex[9]);
                   ctx.lineTo(polygonVertex[10], polygonVertex[11]);
                   // ctx.lineTo(polygonVertex[0], polygonVertex[1]);
                   ctx.closePath();
                   ctx.fillStyle=colorF;
                   ctx.fill();
               }
           };
              //记录起点beginPoint
               canvas.onmousedown=function (e) {
                     imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
                     preDrawAry.push(imgData);
                       beginPoint.x = e.offsetX;
                       beginPoint.y = e.offsetY;
                      console.log(beginPoint.x+"+"+beginPoint.y);
                 };

               //记录终点stopPoint,绘图
              canvas.onmouseup = function(e){  
                   stopPoint.x = e.offsetX;
                   stopPoint.y = e.offsetY;
                   // alert(stopPoint.x+"+"+stopPoint.y);
                   Plot.arrowCoord(beginPoint, stopPoint);
                   Plot.sideCoord();
                   Plot.drawArrow();
               };

               //自定义参数
               function paraDef(edgeLen, angle) {
                   CONST.edgeLen = edgeLen;
                   CONST.angle = angle;
               }

    };

    // 矩形
//    function rect() {
//        Txt.style.display="none";
//        word.style.display="none";
//        var x1,y1,x2,y2,wid,hig;
//        ctx.closePath();
//        canvas.onmousedown=function (ev) {
//            imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
//            preDrawAry.push(imgData);
//            x1 = ev.offsetX;
//            y1 = ev.offsetY;
//            ctx.beginPath();
//            ctx.moveTo(x1,y1);
//            ctx.lineWidth = 2;
//            ctx.strokeStyle = colorF;
//            ctx.lineJoin="round";
//
//        };
//        canvas.onmouseup=function (v) {
//            x2 = v.offsetX;
//            y2 = v.offsetY;
//            wid = x2 - x1;
//            hig = y2 - y1;
//            ctx.lineTo(x2,y1);
//            ctx.lineTo(x2,y2);
//            ctx.lineTo(x1,y2);
//            ctx.lineTo(x1,y1);
//            ctx.stroke();
//        }
//    }

    //矩形
    function rect(){
        Txt.style.display="none";
        word.style.display="none";
        var startPoint = {};
        var isDraw = false;
        function getLocation(e) {
            var bbox = document.getElementById("canvas").getBoundingClientRect();
            return {
                x: e.clientX - bbox.left * (canvas.width/bbox.width),
                y: e.clientY - bbox.top * (canvas.height/bbox.height)
            };
        }
        //绘制矩形方法
        function drawRect(startPoint, endPoint){
            ctx.save();
            ctx.beginPath();
            ctx.strokeRect(startPoint.x, startPoint.y,
                endPoint.x-startPoint.x, endPoint.y-startPoint.y);
            ctx.strokeStyle = colorF;
            ctx.lineWidth = lineWPen;
            ctx.stroke();
            ctx.closePath();
        }
        function saveImageData() {
            imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
            preDrawAry.push(imgData);
        }
        function restoreImageData() {
            ctx.putImageData(imgData, 0, 0);
        }
        canvas.onmousedown = function(e) {
            startPoint = getLocation(e);
            isDraw = true;
            saveImageData();
        };
        canvas.onmousemove = function(e) {
            if(isDraw) {
                restoreImageData();
                drawRect(startPoint, getLocation(e));
            }
        };
        canvas.onmouseup = function(e) {
            isDraw = false;
            ctx.closePath();
        };
    }
    // 文字先写字
    function text(){
        Txt.style.display="block";
        word.style.display="none";
        ctx.font="16px Microsoft Yahei";
        canvas.onmousedown=function (ev) {
            imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
            preDrawAry.push(imgData);
            var v = Txt.value;
//            console.log(v);
            if (v != '') {
                var oldX = ev.offsetX;
                var oldY = ev.offsetY;
                console.log(oldX,oldY);
                ctx.moveTo(oldX,oldY);
                canvas.onmouseup=function (ev) {
                    ctx.fillStyle=colorF;
                    ctx.fillText(v,oldX,oldY);
                    canvasTextAutoLine(v,canvas,oldX,oldY,20);
                    // Txt.value = "";
                    Txt.style.display="none";
                }
            }
        }
    }

    // 文字
    function word1(){
        var canvas = document.getElementById('canvas');
        Txt.style.display="none";
        ctx.font="16px Microsoft Yahei";
        canvas.onmousedown=function () {
            ctx.closePath();
        }
        canvas.onmouseup=function (ev) {
           var inputV= document.getElementById('inputV').value;
           if(inputV == 1){
               document.getElementById('word').focus();
//               console.log(ev.offsetX,ev.offsetY);
               var oldX = ev.offsetX;
               var oldY = ev.offsetY;
               word.style.display="block";
               word.style.left=oldX+'px';
               word.style.top =oldY+'px';
               word.onblur=function () {
                   var v = word.value;
                   if(v != '' && v != ' '){
                       imgData=ctx.getImageData(0,0,canvas.width,canvas.height);
                       preDrawAry.push(imgData);
                       ctx.moveTo(oldX,oldY);
                       ctx.fillStyle=colorF;
                       ctx.fillText(v,oldX,oldY+10);
                       canvasTextAutoLine(v,canvas,oldX,oldY+10,20);
                       inputV ="2";
                       word.value = "";
                   }

               }
           }
       }
   }

    // 文字过长超出换行toDataURL()
    function canvasTextAutoLine(str,canvas,initX,initY,lineHeight){
        var ctx = canvas.getContext("2d");
        var lineWidth = 0;
        var canvasWidth = canvas.width;
        var lastSubStrIndex= 0;
        for(var i=0;i<str.length;i++){
            lineWidth+=ctx.measureText(str[i]).width;
            if(lineWidth>canvasWidth-initX){
                ctx.fillText(str.substring(lastSubStrIndex,i),initX,initY);
                initY+=lineHeight;
                lineWidth=0;
                lastSubStrIndex=i;
            }
            if(i==str.length-1){
                ctx.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);
            }
        }
    }

    // 删除批注
    function restuya(){
        word.style.display="none";
        Txt.style.display="none";
        ctx.clearRect(0,0,canvas.width,canvas.height);  
        window.location.reload();
    };

    // 回退多次
    function back(){
        word.style.display="none";
        Txt.style.display="none";
        if(preDrawAry.length>0) {
            console.log(preDrawAry)
            var popData = preDrawAry.pop();
            ctx.putImageData(popData, 0, 0);
        }
    }

    // 回退一次
    function put(){
         ctx.putImageData(imgData,0,0);
    };

    //保存
    function saveTu(){
        var image = new Image();
        var image = canvas.toDataURL('image/png');    
        console.log(Image);
        document.getElementById('res').innerHTML = '<img src="'+image+'">';  
    }

</script>  
</body>  
</html>  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值