解决Group下fabricjs.Path自定义宽高问题

484 阅读2分钟

问题由来

在绘制设备的形状的时候,大部分选择的是矩形元素,但是有时候需要有一个开口方向,表明他的位置情况。这时候需要使用自定义的绘制类型,这时候fabric.path可以解决这个问题。

image.png

fabric.Path

Fabric中的Path表示可以填充,描边和修改的形状的轮廓。path由一系列命令组成,基本上模仿了从一个点到另一个点的笔。借助“move”,“line”,“curve”或“arc”等命令,path可以形成令人难以置信的复杂形状。在Paths(路径组合)团队的帮助下,可能性更大。

Fabric中的路径与SVG 元素非常相似。它们使用相同的命令,可以从<path>元素创建,并将其序列化。稍后我们将更加仔细地观察序列化和SVG解析,但现在值得一提的是,您很可能很少手动创建Path实例:

var canvas = new fabric.Canvas('c');
var path = new fabric.Path('M 0 0 L 200 100 L 170 200 z');
path.set({ left: 120, top: 120 });
canvas.add(path);

image.png

更新fabric.path 宽高

从构造函数发现,Path的宽高其实是取决于路径绘制的字符串,并不是有属性 width和height控制。直接用代码修改 path.set('width',200) 并不能控制他的宽高。这时我们来研究了fabric.Group的相关方法。增删改差 + 查询

  • group.item(0) // 获得子对象
  • group.getObjects() // 获得全部子对象数组
  • group.size() // 组合中所有对象的数量
  • group.contains() // 检查某个对象是否在组合
  • group.add() // 新增
  • group.addWithUpdate() // 新增并更新
  • group.remove() // 删除
  • group.removeWithUpdate() // 删除并更新

借助Group的相关机制,我们可以删除后,重新绘制Group的子元素,从而到达更新内部组件宽高的效果。

      const orginWidth = value / (selectFabricObject.scaleX || 1) - 3;
      const orginHeight = selectFabricObject.getScaledHeight() - 3;
      const pathObject = selectFabricObject.item(0);
      const x = pathObject.left || 0;
      const y = pathObject.top || 0;
      const angle = pathObject.angle || 0;
      selectFabricObject.remove(...selectFabricObject.getObjects());
      const path = new fabric.Path(
        `M ${-x} ${-y} L ${-x + orginWidth} ${-y} L ${-x + orginWidth} ${-y + orginHeight} L ${-x} ${
          -y + orginHeight
        }`,
        {
          angle: angle,
          borderColor: '000',
          stroke: '#000',
          fill: '#A7FFCF',
          left: selectFabricObject.get('left'),
          top: selectFabricObject.get('top'),
          originX: 'left',
          originY: 'top',
          strokeWidth: 3,
        },
      );
      const name = new fabric.Textbox('打包台', {
        fontSize: 11,
        lockRotation: true,
        width: orginWidth,
        fontWeight: '200',
        stroke: '#2b354a',
        strokeWidth: 1,
        left: (selectFabricObject.get('left') || 0) + orginWidth / 2,
        top: (selectFabricObject.get('top') || 0) + orginHeight / 2,
        originX: 'center',
        originY: 'center',
        textAlign: 'center',
        splitByGrapheme: true,
      });
      selectFabricObject.addWithUpdate(path);
      selectFabricObject.addWithUpdate(name);

image.png

这里我们控制控制了Group{lockScalingX: true ,lockScalingY: true,} 禁止他手动拖动修改scaleX scaleY 的值。只能通过右侧操作宽高,需要知道这两个的区别,请访问之前的文章 fabricjs获取真实宽高