【问题标题】:Fabric.js - Creating polyline shape via mouse drag does not center the shape to its bounding boxFabric.js - 通过鼠标拖动创建折线形状不会将形状置于其边界框的中心
【发布时间】:2018-09-14 02:05:41
【问题描述】:

我正在使用(折线)工具创建一个三角形,试图制作一个矩形三角形。一切都很好,但创建的三角形不在它的边界框内,这会导致问题。 我已经实现了创建一个多边形并且多边形在它的边界框内居中,但是应用相同的技术似乎不适用于折线三角形的情况。

Image showing the unwanted effect

这个jsFiddle 正在显示不受欢迎的行为。

也许我必须更改“originX”和“originY”,但我尝试了几个 不同的组合,但没有成功:

const triangle = new fabric.Polyline(calcPoints(originX, originY, originX, originY), {
objectCaching: false,
left: originX,
top: originY,
originX: 'left',
originY: 'top',
fill: '#0000FF',
includeDefaultValues: false});

我还在鼠标上使用 newShape.setPositionByOrigin 方法:

newShape.setPositionByOrigin(position, 'top', 'left'); 

对于多边形情况,我还为形状应用了 pathOffset,但在这里它会导致事件更大的偏移。

有什么办法可以将形状固定在边界框中?

问候!

【问题讨论】:

    标签: fabricjs


    【解决方案1】:

    如果你需要一个直角三角形,你可以覆盖fabric.Rect

    演示

    var canvas = new fabric.Canvas("my-canvas", {
      backgroundColor: '#fff',
      width: 400,
      height: 400
    });
    fabric.RectangleTriangle = fabric.util.createClass(fabric.Rect, {
      type: 'rectangleTriangle',
      _render: function(ctx) {
        var w = this.width,
          h = this.height,
          x = -this.width / 2,
          y = -this.height / 2;
        ctx.beginPath();
        ctx.moveTo(x, y);
        ctx.lineTo(x, y + h);
        ctx.lineTo(x + w, y + h);
        ctx.lineTo(x, y);
        ctx.closePath();
        this._renderPaintInOrder(ctx);
      }
    });
    fabric.RectangleTriangle.fromObject = function(object, callback) {
      return fabric.Object._fromObject('RectangleTriangle', object, callback);
    };
    var rect, isDown, origX, origY;
    
    function onMouseDown(o) {
      isDown = true;
      var pointer = canvas.getPointer(o.e);
      origX = pointer.x;
      origY = pointer.y;
      var pointer = canvas.getPointer(o.e);
      rect = new fabric.RectangleTriangle({
        left: origX,
        top: origY,
        width: pointer.x - origX,
        height: pointer.y - origY,
        fill: 'blue',
        selectable:false
      });
      canvas.add(rect);
    };
    
    function onMouseMove(o) {
      if (!isDown) return;
      var pointer = canvas.getPointer(o.e);
    
      if (origX > pointer.x) {
        rect.set({
          left: Math.abs(pointer.x)
        });
      }
      if (origY > pointer.y) {
        rect.set({
          top: Math.abs(pointer.y)
        });
      }
    
      rect.set({
        width: Math.abs(origX - pointer.x)
      });
      rect.set({
        height: Math.abs(origY - pointer.y)
      });
      canvas.renderAll();
    };
    
    function onMouseUp(o) {
      isDown = false;
      rect.setCoords();
    };
    
    function select() {
      canvas.off('mouse:up', onMouseUp);
      canvas.off('mouse:move', onMouseMove);
      canvas.off('mouse:down', onMouseDown);
      canvas.selection = true;
      objectSelectable(true);
    }
    
    function draw() {
      canvas.on('mouse:up', onMouseUp);
      canvas.on('mouse:move', onMouseMove);
      canvas.on('mouse:down', onMouseDown);
      canvas.selection = false;
      objectSelectable(false);
    }
    
    function objectSelectable(value) {
      canvas.forEachObject(function(obj) {
        obj.selectable = value;
      })
    }
    draw();
    canvas{
      border:2px solid;
    }
    <script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
    <button onclick="select()">select</button>
    <button onclick="draw()">draw</button>
    <div id="wrapper">
    	<canvas id="my-canvas"></canvas>
    </div>

    【讨论】:

    • 谢谢你,Durga,我也想过这是否可能(覆盖矩形),但我从未尝试过。这可能是一个解决方案,我会尝试的。问候!
    • @Virto111 添加了来自here的鼠标事件创建
    猜你喜欢
    • 2017-05-31
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 2018-06-26
    • 2023-03-22
    • 1970-01-01
    相关资源
    最近更新 更多