| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 | (function () {  //变量声明  var mouseFrom = {},    mouseTo = {},    drawType = null,    canvasObjectIndex = 0,    textbox = null;  var drawWidth = 2; //笔触宽度  var color = "#E34F51"; //画笔颜色  var drawingObject = null; //当前绘制对象  var moveCount = 1; //绘制移动计数器  var doDrawing = false; // 绘制状态  //初始化画板  var canvas = new fabric.Canvas("c", {    isDrawingMode: true,    skipTargetFind: true,    selectable: false,    selection: false  });  window.canvas = canvas;  window.zoom = window.zoom ? window.zoom : 1;  canvas.freeDrawingBrush.color = color; //设置自由绘颜色  canvas.freeDrawingBrush.width = drawWidth;  //绑定画板事件  canvas.on("mouse:down", function (options) {    var xy = transformMouse(options.e.offsetX, options.e.offsetY);    mouseFrom.x = xy.x;    mouseFrom.y = xy.y;    doDrawing = true;  });  canvas.on("mouse:up", function (options) {    var xy = transformMouse(options.e.offsetX, options.e.offsetY);    mouseTo.x = xy.x;    mouseTo.y = xy.y;    // drawing();    drawingObject = null;    moveCount = 1;    doDrawing = false;  });  canvas.on("mouse:move", function (options) {    if (moveCount % 2 && !doDrawing) {      //减少绘制频率      return;    }    moveCount++;    var xy = transformMouse(options.e.offsetX, options.e.offsetY);    mouseTo.x = xy.x;    mouseTo.y = xy.y;    drawing();  });  canvas.on("selection:created", function (e) {    if (e.target._objects) {      //多选删除      var etCount = e.target._objects.length;      for (var etindex = 0; etindex < etCount; etindex++) {        canvas.remove(e.target._objects[etindex]);      }    } else {      //单选删除      canvas.remove(e.target);    }    canvas.discardActiveObject(); //清楚选中框  });  //坐标转换  function transformMouse(mouseX, mouseY) {    return { x: mouseX / window.zoom, y: mouseY / window.zoom };  }  //绑定工具事件  jQuery("#toolsul")    .find("li")    .on("click", function () {      //设置样式      jQuery("#toolsul")        .find("li>i")        .each(function () {          jQuery(this).attr("class", jQuery(this).attr("data-default"));        });      jQuery(this)        .addClass("active")        .siblings()        .removeClass("active");      jQuery(this)        .find("i")        .attr(          "class",          jQuery(this)            .find("i")            .attr("class")            .replace("black", "select")        );      drawType = jQuery(this).attr("data-type");      canvas.isDrawingMode = false;      if (textbox) {        //退出文本编辑状态        textbox.exitEditing();        textbox = null;      }      if (drawType == "pen") {        canvas.isDrawingMode = true;      } else if (drawType == "remove") {        canvas.selection = true;        canvas.skipTargetFind = false;        canvas.selectable = true;      } else {        canvas.skipTargetFind = true; //画板元素不能被选中        canvas.selection = false; //画板不显示选中      }    });  //绘画方法  function drawing() {    if (drawingObject) {      canvas.remove(drawingObject);    }    var canvasObject = null;    switch (drawType) {      case "arrow": //箭头        canvasObject = new fabric.Path(drawArrow(mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y, 30, 30), {          stroke: color,          fill: "rgba(255,255,255,0)",          strokeWidth: drawWidth        });        break;      case "line": //直线        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {          stroke: color,          strokeWidth: drawWidth        });        break;      case "dottedline": //虚线        canvasObject = new fabric.Line([mouseFrom.x, mouseFrom.y, mouseTo.x, mouseTo.y], {          strokeDashArray: [3, 1],          stroke: color,          strokeWidth: drawWidth        });        break;      case "circle": //正圆        var left = mouseFrom.x,          top = mouseFrom.y;        var radius = Math.sqrt((mouseTo.x - left) * (mouseTo.x - left) + (mouseTo.y - top) * (mouseTo.y - top)) / 2;        canvasObject = new fabric.Circle({          left: left,          top: top,          stroke: color,          fill: "rgba(255, 255, 255, 0)",          radius: radius,          strokeWidth: drawWidth        });        break;      case "ellipse": //椭圆        var left = mouseFrom.x,          top = mouseFrom.y;        var radius = Math.sqrt((mouseTo.x - left) * (mouseTo.x - left) + (mouseTo.y - top) * (mouseTo.y - top)) / 2;        canvasObject = new fabric.Ellipse({          left: left,          top: top,          stroke: color,          fill: "rgba(255, 255, 255, 0)",          originX: "center",          originY: "center",          rx: Math.abs(left - mouseTo.x),          ry: Math.abs(top - mouseTo.y),          strokeWidth: drawWidth        });        break;      case "square": //TODO:正方形(后期完善)        break;      case "rectangle": //长方形        var path =          "M " +          mouseFrom.x +          " " +          mouseFrom.y +          " L " +          mouseTo.x +          " " +          mouseFrom.y +          " L " +          mouseTo.x +          " " +          mouseTo.y +          " L " +          mouseFrom.x +          " " +          mouseTo.y +          " L " +          mouseFrom.x +          " " +          mouseFrom.y +          " z";        canvasObject = new fabric.Path(path, {          left: left,          top: top,          stroke: color,          strokeWidth: drawWidth,          fill: "rgba(255, 255, 255, 0)"        });        //也可以使用fabric.Rect        break;      case "rightangle": //直角三角形        var path = "M " + mouseFrom.x + " " + mouseFrom.y + " L " + mouseFrom.x + " " + mouseTo.y + " L " + mouseTo.x + " " + mouseTo.y + " z";        canvasObject = new fabric.Path(path, {          left: left,          top: top,          stroke: color,          strokeWidth: drawWidth,          fill: "rgba(255, 255, 255, 0)"        });        break;      case "equilateral": //等边三角形        var height = mouseTo.y - mouseFrom.y;        canvasObject = new fabric.Triangle({          top: mouseFrom.y,          left: mouseFrom.x,          width: Math.sqrt(Math.pow(height, 2) + Math.pow(height / 2.0, 2)),          height: height,          stroke: color,          strokeWidth: drawWidth,          fill: "rgba(255,255,255,0)"        });        break;      case "isosceles":        break;      case "text":        textbox = new fabric.Textbox("", {          left: mouseFrom.x - 60,          top: mouseFrom.y - 20,          width: 150,          fontSize: 18,          borderColor: "#2c2c2c",          fill: color,          hasControls: false        });        canvas.add(textbox);        textbox.enterEditing();        textbox.hiddenTextarea.focus();        break;      case "remove":        break;      default:        break;    }    if (canvasObject) {      // canvasObject.index = getCanvasObjectIndex();      canvas.add(canvasObject); //.setActiveObject(canvasObject)      drawingObject = canvasObject;    }  }  //绘制箭头方法  function drawArrow(fromX, fromY, toX, toY, theta, headlen) {    theta = typeof theta != "undefined" ? theta : 30;    headlen = typeof theta != "undefined" ? headlen : 10;    // 计算各角度和对应的P2,P3坐标    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI,      angle1 = (angle + theta) * Math.PI / 180,      angle2 = (angle - theta) * Math.PI / 180,      topX = headlen * Math.cos(angle1),      topY = headlen * Math.sin(angle1),      botX = headlen * Math.cos(angle2),      botY = headlen * Math.sin(angle2);    var arrowX = fromX - topX,      arrowY = fromY - topY;    var path = " M " + fromX + " " + fromY;    path += " L " + toX + " " + toY;    arrowX = toX + topX;    arrowY = toY + topY;    path += " M " + arrowX + " " + arrowY;    path += " L " + toX + " " + toY;    arrowX = toX + botX;    arrowY = toY + botY;    path += " L " + arrowX + " " + arrowY;    return path;  }  //获取画板对象的下标  function getCanvasObjectIndex() {    return canvasObjectIndex++;  }})();
 |