FabricJS:当我更改路径坐标时,路径的边界框无法更新 [英] FabricJS: The Bounding box of a path not get update when I change path coordinates

查看:249
本文介绍了FabricJS:当我更改路径坐标时,路径的边界框无法更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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>

(请参阅此小提琴 http://jsfiddle.net/davidtorroija/uyLx3r41/1/)

有更新边框的功能吗?还是fabricjs中的错误?

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

谢谢!

推荐答案

这只是朝着正确方向的提示. 每次重新绘制时都会重新初始化该行(您最好将鼠标悬停在上面). 这样,边界框就可以适应形状.

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>

这篇关于FabricJS:当我更改路径坐标时,路径的边界框无法更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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