fabricjs.com stickman:移动线条并影响相关的圈子 [英] fabricjs.com stickman: move the lines and affect the related circles

查看:113
本文介绍了fabricjs.com stickman:移动线条并影响相关的圈子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 http://fabricjs.com/的 stickman 示例, 我一直在尝试实现在移动直线时移动相关的圆圈.该示例中的代码结构不合理,繁琐.出现错误:),因为我不能对称地移动相关的圆圈.

using the stickman example of http://fabricjs.com/, I have been trying to achieve moving the related circles when a line is moved. The code in the example is not well structured, heavy & with errors :), as I can not to move the the related circles symmetrically.

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

If in the //move the other circle part is used next line

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

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

  • 区别在于收集到的y1信息的符号,我们在视觉上移动了一些水平线,结果确定,但是在我看来,这种调整"类型不是正确的...
    • the difference is in the sign of collected information for y1 and we move some horizontal line visually the result OK, but in my opinion this type of "adjustment" is not the correct one...
    • [示例代码]

      $(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/

      Here it is the code on jsfiddle, too: https://jsfiddle.net/muybien/mzsa3z9L/

      我以前要感谢您,即使只是阅读问题.

      I want previously to thank you, even only for reading the question.

      推荐答案

      感谢 MiltoxBeyond的建议,此问题已解决. 这是一个可以正常工作的示例:

      Thanks of MiltoxBeyond's suggestion, the problem is fixed. Here it is a working and little cleaned example:

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

      canvas {
        border: 1px solid #808080;
      }

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

      这篇关于fabricjs.com stickman:移动线条并影响相关的圈子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆