FabricJS: The Bounding box of a path not get update when I change path coordinates

百般思念 提交于 2020-01-24 00:49:26

问题


We have a problem working with paths in fabric, we need to change all the time the coordinates of a quadratic line (path) when the user drags the first point or the last point, the paths gets updated as usual, but the problem is that the bounding box of the path don't get update on every change of the object.path (see the image)

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

(see this fiddle http://jsfiddle.net/davidtorroija/uyLx3r41/1/)

There is a function to update the bounding box? or is this a bug in fabricjs?

Thanks!


回答1:


This is just hint in the good direction. The line is re initialized every redrawn ( you can better do at mouse up ). In this way the bounding box stays fit to the shape.

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>


来源:https://stackoverflow.com/questions/35436344/fabricjs-the-bounding-box-of-a-path-not-get-update-when-i-change-path-coordinat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!