fabricjs.com火柴人:移动线条并影响相关圈子

时间:2015-06-01 18:35:43

标签: coordinates move fabricjs lines

使用http://fabricjs.com/ stickman 示例, 移动线时,我一直试图移动相关的圆圈。示例中的代码结构不合理,重量级和有错误:),因为我无法对称地移动相关的圆圈。

如果在 //移动另一个圈部分,则使用下一行

  

obj.set({         'left':( s.calcLinePoints()。x1 + _l),         'top':( -s.calcLinePoints()。y1 + _t)       });

  • 差异在于y1 的收集信息的符号,我们在视觉上移动一些水平线结果OK ,但在我看来这种类型的“调整”不正确...

[示例代码]

$(function() {
  //create the fabriccanvas object & disable the canvas selection
  var canvas = new fabric.Canvas('c', {
    selection: false
  });
  //move the objects origin of transformation to the center
  fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

  function makeCircle(left, top, line1, line2, usedLine, usedEnd) {
    //used line - used line for the center
    //usedEnd - fromt the used line

    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 2,
      radius: 6,
      fill: '#fff',
      stroke: '#666'
    });

    c.hasControls = c.hasBorders = false;

    c.line1 = line1;
    c.line2 = line2;

    //add information which line end is used for center
    var _usedLineName;

    if (usedLine == 1) {
      _usedLineName = line1.name;
    } else {
      _usedLineName = line2.name;
    }

    c.usedLineName = _usedLineName;
    c.usedEndPoint = usedEnd;

    return c;
  }

  function makeLine(coords, name) {
    var l = new fabric.Line(coords, {
      stroke: 'red',
      strokeWidth: 4,
      selectable: true, //false
      name: name
    });

    l.hasControls = l.hasBorders = false;

    return l;
  }

  //initial shape information
  var line = makeLine([250, 125, 350, 125], "l1"),
    line2 = makeLine([350, 125, 350, 225], "l2"),
    line3 = makeLine([350, 225, 250, 225], "l3"),
    line4 = makeLine([250, 225, 250, 125], "l4");

  canvas.add(line, line2, line3, line4);

  canvas.add(
    makeCircle(line.get('x1'), line.get('y1'), line4, line, 1, 2),
    makeCircle(line.get('x2'), line.get('y2'), line, line2, 1, 2),
    makeCircle(line2.get('x2'), line2.get('y2'), line2, line3, 1, 2),
    makeCircle(line3.get('x2'), line3.get('y2'), line3, line4, 1, 2));



  canvas.on('object:moving', function(e) {
    //find the moving object type
    var objType = e.target.get('type');
    var p = e.target;

    if (objType == 'circle') {
      p.line1 && p.line1.set({
        'x2': p.left,
        'y2': p.top
      });
      p.line2 && p.line2.set({
        'x1': p.left,
        'y1': p.top
      });
      //set coordinates for the lines - should be done if element is moved programmely
      p.line2.setCoords();
      p.line1.setCoords();

      canvas.renderAll();
    } else if (objType == 'line') {

      //loop all circles and if some is with coordinates as some of the ends - to change them
      for (var i = 0; i < canvas.getObjects('circle').length; i++) {

        var currentObj = canvas.getObjects('circle')[i];

        if (currentObj.get("usedLineName") == e.target.get('name')) {

          //usedEndPoint=2
          for (var ss = 0; ss < canvas.getObjects('line').length; ss++) {
            var s = canvas.getObjects('line')[ss];
            //console.log(s.calcLinePoints())
            //console.log(s.calcLinePoints().y2)
            var _l = s.left;
            var _t = s.top;
            if (s.get("name") == currentObj.get("usedLineName")) {
              currentObj.set({
                'left': (s.calcLinePoints().x2 + _l),
                'top': (s.calcLinePoints().y2 + _t)
              });
              console.log(s.calcLinePoints().y2 + _t)
              currentObj.setCoords();

              currentObj.line1 && currentObj.line1.set({
                'x2': currentObj.left,
                'y2': currentObj.top
              });
              currentObj.line2 && currentObj.line2.set({
                'x1': currentObj.left,
                'y1': currentObj.top
              });

              currentObj.line2.setCoords();
              currentObj.line1.setCoords();


              //move the other circle
              canvas.forEachObject(function(obj) {
                var _objType = obj.get('type');
                if (_objType == "circle" && obj.line2.name == s.get("name")) {

                  obj.set({
                    'left': (s.calcLinePoints().x1 + _l),
                    'top': (s.calcLinePoints().y1 + _t)
                  });
                  console.log(s.calcLinePoints().y1 + _t)
                  obj.setCoords();

                  obj.line1 && obj.line1.set({
                    'x2': obj.left,
                    'y2': obj.top
                  });
                  obj.line2 && obj.line2.set({
                    'x1': obj.left,
                    'y1': obj.top
                  });

                  obj.line2.setCoords();
                  obj.line1.setCoords();
                  //canvas.renderAll();
                }
              });
              canvas.renderAll();
              //end move oter
            }
          }

        }
      }

    }
  });

});
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>

这里也是jsfiddle上的代码: https://jsfiddle.net/muybien/mzsa3z9L/

我以前要感谢你,甚至只是为了阅读这个问题。

1 个答案:

答案 0 :(得分:0)

感谢 MiltoxBeyond的建议,问题得到解决。 这是一个工作且很少清理的例子:

&#13;
&#13;
//to save the old cursor position: used on line mooving
var _curX, _curY;
$(function() {
  //create the fabriccanvas object & disable the canvas selection
  var canvas = new fabric.Canvas('c', {
    selection: false
  });
  //move the objects origin of transformation to the center
  fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

  function makeCircle(left, top, line1, line2) {

    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 2,
      radius: 6,
      fill: '#fff',
      stroke: '#666'
    });

    c.hasControls = c.hasBorders = false;

    c.line1 = line1;
    c.line2 = line2;

    return c;
  }

  function makeLine(coords, name) {
    var l = new fabric.Line(coords, {
      stroke: 'red',
      strokeWidth: 4,
      selectable: true, //false
      name: name
    });

    l.hasControls = l.hasBorders = false;

    return l;
  }

  //initial shape information
  var line = makeLine([250, 125, 350, 125], "l1"),
    line2 = makeLine([350, 125, 350, 225], "l2"),
    line3 = makeLine([350, 225, 250, 225], "l3"),
    line4 = makeLine([250, 225, 250, 125], "l4");

  canvas.add(line, line2, line3, line4);

  canvas.add(
    makeCircle(line.get('x1'), line.get('y1'), line4, line), makeCircle(line.get('x2'), line.get('y2'), line, line2), makeCircle(line2.get('x2'), line2.get('y2'), line2, line3), makeCircle(line3.get('x2'), line3.get('y2'), line3, line4)
  );

  canvas.on('object:selected', function(e) {
    //find the selected object type
    var objType = e.target.get('type');
    if (objType == 'line') {
      _curX = e.e.clientX;
      _curY = e.e.clientY;
      //console.log(_curX);
      //console.log(_curY);
    }
  });

  canvas.on('object:moving', function(e) {
    //find the moving object type
    var p = e.target;
    var objType = p.get('type');

    if (objType == 'circle') {
      p.line1 && p.line1.set({
        'x2': p.left,
        'y2': p.top
      });
      p.line2 && p.line2.set({
        'x1': p.left,
        'y1': p.top
      });
      //set coordinates for the lines - should be done if element is moved programmely
      p.line2.setCoords();
      p.line1.setCoords();

      canvas.renderAll();
    } else if (objType == 'line') {
      var _curXm = (_curX - e.e.clientX);
      var _curYm = (_curY - e.e.clientY);
      //console.log("moved: " + _curXm);
      //console.log("moved: " + _curYm);

      //loop all circles and if some contains the line - move it
      for (var i = 0; i < canvas.getObjects('circle').length; i++) {
        var currentObj = canvas.getObjects('circle')[i];

        if (currentObj.line1.get("name") == p.get('name') || currentObj.line2.get("name") == p.get('name')) {

          currentObj.set({
            'left': (currentObj.left - _curXm),
            'top': (currentObj.top - _curYm)
          });

          currentObj.setCoords();

          currentObj.line1 && currentObj.line1.set({
            'x2': currentObj.left,
            'y2': currentObj.top
          });
          currentObj.line2 && currentObj.line2.set({
            'x1': currentObj.left,
            'y1': currentObj.top
          });

          currentObj.line2.setCoords();
          currentObj.line1.setCoords();
        }
      }
      _curX = e.e.clientX;
      _curY = e.e.clientY;
    }
  });

});
&#13;
canvas {
  border: 1px solid #808080;
}
&#13;
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<canvas id="c" width="500" height="500"></canvas>
&#13;
&#13;
&#13;