Fabric.js:如何通过鼠标绘制多边形 [英] Fabric.js: How to draw a polygon by mouse

查看:192
本文介绍了Fabric.js:如何通过鼠标绘制多边形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在Fabric.js中通过鼠标交互绘制一个fabric.Polygon. 我做了一个小jsfiddle来显示我的实际状态: http://jsfiddle.net/Kienz/ujefxh7w/

I want draw a fabric.Polygon with mouse interaction in Fabric.js. I made a small jsfiddle to show my actual state: http://jsfiddle.net/Kienz/ujefxh7w/

按ESC键后,将取消交互式绘图模式",并最终确定多边形.但是现在多边形的位置是错误的(控件是正确的).

After pressing the ESC key, the "interactive draw mode" is canceled and the polygon is finalized. But now the position of the polygon is wrong (controls are right).

有人有主意吗?

推荐答案

有两个解决方案,它们非常简单:

There are two solutions to this problem, which are very very simple:

只需从画布上删除多边形,然后在每个添加的点上使用新的fabric.Polygon(...)重新创建它即可!

Just remove the polygon from the canvas and recreate it (using new fabric.Polygon(...)) on every added point!

专业人士缺点:是的,由于画布将被重新渲染两次,因此性能会稍差一些,但是您将省去每次重新计算坐标的麻烦.

Pros & Cons: Yes, you will get a slightly worse performance, because the canvas will be rerendered twice, but you will save yourself the trouble of recalculating the coordinates every time.

您可以在下面的代码段中或此分叉的小提琴中查看该解决方案.

You can check this solution out in the snippet below or in this forked fiddle.

/**
 * fabric.js template for bug reports
 *
 * Please update the name of the jsfiddle (see Fiddle Options).
 * This templates uses latest dev verison of fabric.js (https://rawgithub.com/kangax/fabric.js/master/dist/all.js).
 */

// initialize fabric canvas and assign to global windows object for debug
var canvas = window._canvas = new fabric.Canvas('c');

// Do some initializing stuff
fabric.Object.prototype.set({
  transparentCorners: false,
  cornerColor: 'rgba(102,153,255,0.5)',
  cornerSize: 12,
  padding: 7
});

// ADD YOUR CODE HERE
var mode = "add",
  currentShape;

canvas.observe("mouse:move", function(event) {
  var pos = canvas.getPointer(event.e);
  if (mode === "edit" && currentShape) {
    var points = currentShape.get("points");
    points[points.length - 1].x = pos.x;
    points[points.length - 1].y = pos.y;
    currentShape.set({
      points: points
    });
    canvas.renderAll();
  }
});

canvas.observe("mouse:down", function(event) {
  var pos = canvas.getPointer(event.e);

  if (mode === "add") {
    var polygon = new fabric.Polygon([{
      x: pos.x,
      y: pos.y
    }, {
      x: pos.x + 0.5,
      y: pos.y + 0.5
    }], {
      fill: 'blue',
      opacity: 0.5,
      selectable: false
    });
    currentShape = polygon;
    canvas.add(currentShape);
    mode = "edit";
  } else if (mode === "edit" && currentShape && currentShape.type === "polygon") {
    var points = currentShape.get("points");
    points.push({
      x: pos.x,
      y: pos.y
    });
    canvas.remove(currentShape);
    currentShape = new fabric.Polygon(points, {
      fill: 'blue',
      opacity: 0.5,
      selectable: false
    });
    canvas.add(currentShape);
  }
});

fabric.util.addListener(window, 'keyup', function(e) {
  if (e.keyCode === 27) {
    if (mode === 'edit' || mode === 'add') {
      mode = 'normal';
      var points = currentShape.get('points');
      canvas.remove(currentShape);
      currentShape = new fabric.Polygon(points, {
        fill: 'blue',
        opacity: 0.5,
        selectable: true
      });
      canvas.add(currentShape);
    } else {
      mode = 'add';
    }
    currentShape = null;
  }
})

canvas {
  border: 1px solid #999;
}
img {
  display: none;
}

<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

每次都重新计算多边形尺寸,就像在Polygon类的构造函数中一样.代码摘录:

Recalculate the polygon dimensions every time, like it is done in the constructor of Polygon class. Excerpt from the code:

currentShape.set({
    points: points
});
currentShape._calcDimensions();
currentShape.set({
    left: currentShape.minX,
    top: currentShape.minY,
    pathOffset: {
        x: currentShape.minX + currentShape.width / 2,
        y: currentShape.minY + currentShape.height / 2
    }
});
currentShape.setCoords();
canvas.renderAll();

专业人士缺点:更好的性能(在负载较重的画布上可能很明显),但是您将拥有更多代码,因为必须将其添加到两个处理程序中.

Pros & Cons: Better performance (probably noticeable on heavily loaded canvases), but you will have more code as you have to add it to both handlers.

您可以在下面的代码段中或此分叉的小提琴中进行检查.

You can check this out in the snippet below or in this forked fiddle.

/**
 * fabric.js template for bug reports
 *
 * Please update the name of the jsfiddle (see Fiddle Options).
 * This templates uses latest dev verison of fabric.js (https://rawgithub.com/kangax/fabric.js/master/dist/all.js).
 */

// initialize fabric canvas and assign to global windows object for debug
var canvas = window._canvas = new fabric.Canvas('c');

// Do some initializing stuff
fabric.Object.prototype.set({
  transparentCorners: false,
  cornerColor: 'rgba(102,153,255,0.5)',
  cornerSize: 12,
  padding: 7
});

// ADD YOUR CODE HERE
var mode = "add",
  currentShape;

canvas.observe("mouse:move", function(event) {
  var pos = canvas.getPointer(event.e);
  if (mode === "edit" && currentShape) {
    var points = currentShape.get("points");
    points[points.length - 1].x = pos.x;
    points[points.length - 1].y = pos.y;
    currentShape.set({
      points: points
    });
    canvas.renderAll();
  }
});

canvas.observe("mouse:down", function(event) {
  var pos = canvas.getPointer(event.e);

  if (mode === "add") {
    var polygon = new fabric.Polygon([{
      x: pos.x,
      y: pos.y
    }, {
      x: pos.x + 0.5,
      y: pos.y + 0.5
    }], {
      fill: 'blue',
      opacity: 0.5,
      selectable: false
    });
    currentShape = polygon;
    canvas.add(currentShape);
    mode = "edit";
  } else if (mode === "edit" && currentShape && currentShape.type === "polygon") {
    var points = currentShape.get("points");
    points.push({
      x: pos.x,
      y: pos.y
    });
    currentShape.set({
      points: points
    });
    currentShape._calcDimensions();
    currentShape.set({
      left: currentShape.minX,
      top: currentShape.minY,
      pathOffset: {
        x: currentShape.minX + currentShape.width / 2,
        y: currentShape.minY + currentShape.height / 2
      }
    });
    currentShape.setCoords();
    canvas.renderAll();
  }
});

fabric.util.addListener(window, 'keyup', function(e) {
  if (e.keyCode === 27) {
    if (mode === 'edit' || mode === 'add') {
      mode = 'normal';
      currentShape.set({
        selectable: true
      });
      currentShape._calcDimensions();
      currentShape.set({
        left: currentShape.minX,
        top: currentShape.minY,
        pathOffset: {
          x: currentShape.minX + currentShape.width / 2,
          y: currentShape.minY + currentShape.height / 2
        }
      });
      currentShape.setCoords();
      canvas.renderAll();
    } else {
      mode = 'add';
    }
    currentShape = null;
  }
})

canvas {
  border: 1px solid #999;
}
img {
  display: none;
}

<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

这篇关于Fabric.js:如何通过鼠标绘制多边形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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