复合形状类?

时间:2017-09-05 18:12:15

标签: javascript fabricjs rulers

有没有人曾尝试为Fabric.js创建一个自定义形状类,它是形状的组合?我想创建一个类似尺子的东西,左右两端是垂直线,并连接到中间,| --- | 。 我还想在这个统治者的中心跟随一个文本框。两端还应具有重新定位的能力。 我没有上课就完成了这个,但它不会保存或加载,因为我从多个形状制作了我的版本。 任何人都有任何想法,如果可以创建这样的自定义形状?

以下是我从前一段时间发现的另一个例子中提取的一些代码示例。创建3条线来组成我的标尺。如果我导出画布数据,我将获得数据重新创建为3行,所以如果我清除画布并重新加载这些数据,我将得到我的3行,但它们将是独立的3行。我想我需要弄清楚如何保存他们的关系,这样他们可以在重新加载时保留他们的标尺行为。我认为最好的方法是创建一个带有“标尺”类型的自定义形状。

window.onload = function() {
  var canvas;
  var started = false;
  var mode = 0;
  var lastX = 0;
  var lastY = 0;

  canvas = new fabric.Canvas('c');
  canvas.isDrawingMode = false;
  canvas.isTouchSupported = true;
  canvas.selection = false;

  canvas.on("mouse:down", function(option) {

    if (mode === 1) {
      var mouse = canvas.getPointer(option.e);
      lastX = mouse.x;
      lastY = mouse.y;
      started = true;

      var ln = new fabric.Line([lastX, lastY, lastX, lastY], {
        fill: 'red',
        stroke: 'red',
        strokeWidth: 4,
        originX: 'center',
        originY: 'center',
        lockScalingX: true,
        lockScalingY: true,
        lockRotation: true,
        hasBorders: false,
        hasControls: false,
        perPixelTargetFind: true
      });

      var rAnchor = new fabric.Line([lastX - 20, lastY, lastX + 20, lastY], {
        fill: 'red',
        stroke: 'red',
        strokeWidth: 4,
        originX: 'center',
        originY: 'center',
        lockScalingX: true,
        lockScalingY: true,
        lockRotation: true,
        hasBorders: false,
        hasControls: false,
        perPixelTargetFind: true
      });

      var tip = new fabric.Line([lastX - 20, lastY, lastX + 20, lastY], {
        fill: 'red',
        stroke: 'red',
        strokeWidth: 4,
        originX: 'center',
        originY: 'center',
        lockScalingX: true,
        lockScalingY: true,
        lockRotation: true,
        hasBorders: false,
        hasControls: false,
        perPixelTargetFind: true
      });

      tip.line = ln;
      rAnchor.line = ln;
      ln.tip = tip;
      ln.rAnchor = rAnchor;

      canvas.add(ln);
      canvas.add(rAnchor);
      canvas.add(tip);

      canvas.setActiveObject(ln);
      canvas.renderAll();
    }
  });

  canvas.on("mouse:move", function(e) {
    if (!started) {
      return false;
    }
    var mouse = canvas.getPointer(e.e);

    var line = canvas.getActiveObject();
    line.set('x2', mouse.x).set('y2', mouse.y);

    var tip = line.get('tip');
    tip.set('left', mouse.x).set('top', mouse.y);

    var rAnchor = line.get('rAnchor');


    // Get the angle for pointing the tip at the mouse location.
    var rad = Math.atan2((line.y1 - line.y2), (line.x1 - line.x2));
    var ang = rad * (180 / Math.PI);
    tip.set('angle', (ang - 90));
    rAnchor.set('angle', (ang - 90));

    line.setCoords();
    tip.setCoords();
    rAnchor.setCoords();
    canvas.renderAll();
  });

  canvas.on("mouse:up", function() {
    if (started) {
      started = false;
    }

    canvas.discardActiveObject();
    canvas.renderAll();
  });

  // Event Handler for Drawn Object move
  canvas.on('object:moving', function(e) {
    var p = e.target;

    // move line
    if (p.tip) {
      var oldCenterX = (p.x1 + p.x2) / 2;
      var oldCenterY = (p.y1 + p.y2) / 2;

      var deltaX = p.left - oldCenterX;
      var deltaY = p.top - oldCenterY;


      p.tip.set({
        'left': p.x2 + deltaX,
        'top': p.y2 + deltaY
      }).setCoords();

      p.rAnchor.set({
        'left': p.x1 + deltaX,
        'top': p.y1 + deltaY
      });

      p.set({
        'x1': p.x1 + deltaX,
        'y1': p.y1 + deltaY
      });
      p.set({
        'x2': p.x2 + deltaX,
        'y2': p.y2 + deltaY
      });

      p.set({
        'left': (p.x1 + p.x2) / 2,
        'top': (p.y1 + p.y2) / 2
      });
    }

    // move tip
    if (p.line) {
      var tip = p.line.tip;
      var rAnchor = p.line.rAnchor;

      p.line.set({
        'x2': tip.left,
        'y2': tip.top,
        'x1': rAnchor.left,
        'y1': rAnchor.top
      });

      // Get the angle for pointing the tip at the mouse location.
      var rad = Math.atan2((p.line.y1 - p.line.y2), (p.line.x1 - p.line.x2));
      var ang = rad * (180 / Math.PI);
      tip.set('angle', (ang - 90));
      rAnchor.set('angle', (ang - 90));
      tip.setCoords();
      rAnchor.setCoords();
      p.line.setCoords();
    }
    canvas.renderAll();
  });

  // Button Event Handlers
  document.getElementById("btnEdit").addEventListener("click", function(e) {
    mode = 0;
  });

  document.getElementById("btnArrow").addEventListener("click", function(e) {
    mode = 1;
  });
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.17/fabric.min.js"></script>
<canvas style="border: 2px solid; " height="500" width="600" id="c"></canvas>
<button id="btnEdit">Edit</button>
<button id="btnArrow">Ruler</button>

0 个答案:

没有答案