FabricJS:当我更改路径坐标时,路径的边界框不会更新

问题描述 投票:0回答:2

我们在处理结构中的路径时遇到问题,当用户拖动第一个点或最后一个点时,我们需要始终更改二次线(路径)的坐标,路径会像往常一样更新,但问题是路径的边界框不会随着 object.path 的每次更改而更新(参见图片)

(function() {
  var canvas = this.__canvas = new fabric.Canvas('c');
  fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

  canvas.on({
    'object:selected': onObjectSelected,
    'object:moving': onObjectMoving,
    'before:selection:cleared': onBeforeSelectionCleared
  });

  (function drawQuadratic() {

    var line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', stroke: 'black' });

    line.path[0][1] = 100;
    line.path[0][2] = 100;

    line.path[1][1] = 200;
    line.path[1][2] = 200;

    line.path[1][3] = 300;
    line.path[1][4] = 100;

    line.selectable = true;
    line.hasControls = false;
    canvas.add(line);

    var p1 = makeCurvePoint(200, 200, null, line, null)
    p1.name = "p1";
    canvas.add(p1);

    var p0 = makeCurveCircle(100, 100, line, p1, null);
    p0.name = "p0";
    canvas.add(p0);

    var p2 = makeCurveCircle(300, 100, null, p1, line);
    p2.name = "p2";
    canvas.add(p2);

  })();

  function makeCurveCircle(left, top, line1, line2, line3) {
    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 5,
      radius: 12,
      fill: '#fff',
      stroke: '#666'
    });

    c.hasBorders = c.hasControls = false;

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

    return c;
  }

  function makeCurvePoint(left, top, line1, line2, line3) {
    var c = new fabric.Circle({
      left: left,
      top: top,
      strokeWidth: 8,
      radius: 14,
      fill: '#fff',
      stroke: '#666'
    });

    c.hasBorders = c.hasControls = false;

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

    return c;
  }

  function onObjectSelected(e) {
    var activeObject = e.target;

    if (activeObject.name == "p0" || activeObject.name == "p2") {
      activeObject.line2.animate('opacity', '1', {
        duration: 200,
        onChange: canvas.renderAll.bind(canvas),
      });
      activeObject.line2.selectable = true;
    }
  }

  function onBeforeSelectionCleared(e) {
    var activeObject = e.target;
    if (activeObject.name == "p0" || activeObject.name == "p2") {
      activeObject.line2.animate('opacity', '0', {
        duration: 200,
        onChange: canvas.renderAll.bind(canvas),
      });
      activeObject.line2.selectable = false;
    }
    else if (activeObject.name == "p1") {
      activeObject.animate('opacity', '0', {
        duration: 200,
        onChange: canvas.renderAll.bind(canvas),
      });
      activeObject.selectable = false;
    }
  }

  function onObjectMoving(e) {
    if (e.target.name == "p0" || e.target.name == "p2") {
      var p = e.target;

      if (p.line1) {
        p.line1.path[0][1] = p.left;
        p.line1.path[0][2] = p.top;
      }
      else if (p.line3) {
        p.line3.path[1][3] = p.left;
        p.line3.path[1][4] = p.top;
      }
    }
    else if (e.target.name == "p1") {
      var p = e.target;

      if (p.line2) {
        p.line2.path[1][1] = p.left;
        p.line2.path[1][2] = p.top;
      }
    }
    else if (e.target.name == "p0" || e.target.name == "p2") {
      var p = e.target;

      p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
      p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
      p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
      p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
    }
  }
})();
<script src="http://fabricjs.com/lib/fabric.js"></script>

<canvas id="c" width="600" height="600"></canvas>

(参见这个小提琴http://jsfiddle.net/davidtorroija/uyLx3r41/1/

有更新边界框的功能吗?或者这是fabricjs 中的一个错误?

谢谢!

javascript fabricjs
2个回答
2
投票

这只是一个好的方向的暗示。 每次重绘都会重新初始化该线(您可以更好地在鼠标向上执行)。 通过这种方式,边界框保持适合形状。

http://jsfiddle.net/uyLx3r41/2/

(function() {
  var line;
  var canvas = this.__canvas = new fabric.Canvas('c');
  fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';

  canvas.on({
'object:moving': onObjectMoving,
  });

  (function drawQuadratic() {

line = new fabric.Path('M 65 0 Q 100, 100, 200, 0', { fill: '', stroke: 'black' });

line.path[0][1] = 100;
line.path[0][2] = 100;

line.path[1][1] = 200;
line.path[1][2] = 200;

line.path[1][3] = 300;
line.path[1][4] = 100;

line.selectable = true;
line.hasControls = false;
canvas.add(line);

var p1 = makeCurvePoint(200, 200, null, line, null)
p1.name = "p1";
canvas.add(p1);

var p0 = makeCurveCircle(100, 100, line, p1, null);
p0.name = "p0";
canvas.add(p0);

var p2 = makeCurveCircle(300, 100, null, p1, line);
p2.name = "p2";
canvas.add(p2);

  })();

  function makeCurveCircle(left, top, line1, line2, line3) {
var c = new fabric.Circle({
  left: left,
  top: top,
  strokeWidth: 5,
  radius: 12,
  fill: '#fff',
  stroke: '#666'
});

c.hasBorders = c.hasControls = false;

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

return c;
  }

  function makeCurvePoint(left, top, line1, line2, line3) {
var c = new fabric.Circle({
  left: left,
  top: top,
  strokeWidth: 8,
  radius: 14,
  fill: '#fff',
  stroke: '#666'
});

c.hasBorders = c.hasControls = false;

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

return c;
  }


  function onObjectMoving(e) {
var p = e.target;
if (p.name == "p0" || p.name == "p2") {
  if (p.line1) {
    p.line1.path[0][1] = p.left;
    p.line1.path[0][2] = p.top;
  }
  else if (p.line3) {
    p.line3.path[1][3] = p.left;
    p.line3.path[1][4] = p.top;
  }
}
else if (p.name == "p1") {
  if (p.line2) {
    p.line2.path[1][1] = p.left;
    p.line2.path[1][2] = p.top;
  }
}
else if (p.name == "p0" || p.name == "p2") {
  p.line1 && p.line1.set({ 'x2': p.left, 'y2': p.top });
  p.line2 && p.line2.set({ 'x1': p.left, 'y1': p.top });
  p.line3 && p.line3.set({ 'x1': p.left, 'y1': p.top });
  p.line4 && p.line4.set({ 'x1': p.left, 'y1': p.top });
}
p && reinit();
  }
  
  function reinit() {
canvas.remove(line);
line = new fabric.Path(line.path, { fill: '', stroke: 'black' });
canvas.add(line);
  }
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.7/fabric.js"></script>

<canvas id="c" width="600" height="600"></canvas>


0
投票

Follwing 适用于 https://cdnjs.cloudflare.com/ajax/libs/fabric.js/6.0.0-rc.1/fabric.js

   const { left, top } = path1;
    path1._setPath(newPath);
    path1.set({ left, top });
    canvas.requestRenderAll();
© www.soinside.com 2019 - 2024. All rights reserved.