简体   繁体   English

Fabric.js - 免费绘制一个矩形

[英]Fabric.js - Free draw a rectangle

I have the following which doesn't work correctly:我有以下无法正常工作的情况:

var canvas = new fabric.Canvas('canvas');


canvas.observe('mouse:down', function(e) { mousedown(e); });
canvas.observe('mouse:move', function(e) { mousemove(e); });
canvas.observe('mouse:up', function(e) { mouseup(e); });


var started = false;


var x = 0;
var y = 0;


/* Mousedown */
function mousedown(e) {

    var mouse = canvas.getPointer(e.memo.e);

    started = true;

    x = mouse.x;
    y = mouse.y;    

    var square = new fabric.Rect({ 

        width: 1, 
        height: 1, 
        left: mouse.x, 
        top: mouse.y, 
        fill: '#000'

    });


    canvas.add(square); 
    canvas.renderAll();
    canvas.setActiveObject(square); 

}


/* Mousemove */
function mousemove(e) {

    if(!started) {

        return false;

    }

    var mouse = canvas.getPointer(e.memo.e);

    var x = Math.min(mouse.x,  x),
    y = Math.min(mouse.y,  y),
    w = Math.abs(mouse.x - x),
    h = Math.abs(mouse.y - y);

    if (!w || !h) {

        return false;

    }

    var square = canvas.getActiveObject(); 

    square.set('top', y).set('left', x).set('width', w).set('height', h);

    canvas.renderAll(); 

}


/* Mouseup */
function mouseup(e) {

    if(started) {

        started = false;    

    }   

 }

The above logic is from a simple rectangle drawing system I used without fabric.js so I know it works, just not with fabric.js.上面的逻辑来自一个简单的矩形绘图系统,我在没有 fabric.js 的情况下使用,所以我知道它可以工作,只是不能用于 fabric.js。

It seems the maths is off or I'm setting the incorrect params with the width/height/x/y values, as when you draw the rectangle does not follow the cursor correctly.似乎数学关闭了,或者我正在使用宽度/高度/x/y 值设置不正确的参数,因为当您绘制矩形时没有正确跟随光标。

Any help is much appreciated, thanks in advance :)非常感谢任何帮助,提前致谢:)

I have written an example for you.我已经为你写了一个例子。 Please follow the link below:请点击以下链接:

http://jsfiddle.net/a7mad24/aPLq5/ http://jsfiddle.net/a7mad24/aPLq5/

var canvas = new fabric.Canvas('canvas', { selection: false });

var rect, isDown, origX, origY;

canvas.on('mouse:down', function(o){
    isDown = true;
    var pointer = canvas.getPointer(o.e);
    origX = pointer.x;
    origY = pointer.y;
    var pointer = canvas.getPointer(o.e);
    rect = new fabric.Rect({
        left: origX,
        top: origY,
        originX: 'left',
        originY: 'top',
        width: pointer.x-origX,
        height: pointer.y-origY,
        angle: 0,
        fill: 'rgba(255,0,0,0.5)',
        transparentCorners: false
    });
    canvas.add(rect);
});

canvas.on('mouse:move', function(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();
});

canvas.on('mouse:up', function(o){
  isDown = false;
});

Looks like Fabric.js calculates everything from the origin.看起来 Fabric.js 从原点计算一切。 So, 'Top' and 'Left' are a bit misleading.所以,“上”和“左”有点误导。 Check the following link: Canvas Coordinates Have Offset .检查以下链接: 画布坐标有偏移 Also, I've changed a bit of your code:另外,我对您的代码进行了一些更改:

var canvas = new fabric.Canvas('canvas');
canvas.observe('mouse:down', function(e) { mousedown(e); });
canvas.observe('mouse:move', function(e) { mousemove(e); });
canvas.observe('mouse:up', function(e) { mouseup(e); });

var started = false;
var x = 0;
var y = 0;

/* Mousedown */
function mousedown(e) {
    var mouse = canvas.getPointer(e.memo.e);
    started = true;
    x = mouse.x;
    y = mouse.y;

    var square = new fabric.Rect({ 
        width: 0, 
        height: 0, 
        left: x, 
        top: y, 
        fill: '#000'
    });

    canvas.add(square); 
    canvas.renderAll();
    canvas.setActiveObject(square); 

}


/* Mousemove */
function mousemove(e) {
    if(!started) {
        return false;
    }

    var mouse = canvas.getPointer(e.memo.e);

    var w = Math.abs(mouse.x - x),
    h = Math.abs(mouse.y - y);

    if (!w || !h) {
        return false;
    }

    var square = canvas.getActiveObject(); 
    square.set('width', w).set('height', h);
    canvas.renderAll(); 
}

/* Mouseup */
function mouseup(e) {
    if(started) {
        started = false;
    }

    var square = canvas.getActiveObject();

    canvas.add(square); 
    canvas.renderAll();
 } 

The answer above seems to be deprecated.上面的答案似乎已被弃用。 I changed some things on the code below to fix that.我在下面的代码中更改了一些内容来解决这个问题。 And on the mousedown function I add the if to detect the active object to avoid creating a new rectangle when the user's move a selected object.在 mousedown 函数上,我添加了 if 来检测活动对象,以避免在用户移动选定对象时创建新矩形。

var canvas = new fabric.Canvas('canvas');

canvas.on('mouse:down', function(options) {
      if(canvas.getActiveObject()){
        return false;
      }

      started = true;
      x = options.e.clientX;
      y = options.e.clientY;

      var square = new fabric.Rect({ 
          width: 0, 
          height: 0, 
          left: x, 
          top: y, 
          fill: '#000'
      });

      canvas.add(square); 
      canvas.setActiveObject(square); 
  });

  canvas.on('mouse:move', function(options) {
    if(!started) {
        return false;
    }

    var w = Math.abs(options.e.clientX - x),
    h = Math.abs(options.e.clientY - y);

    if (!w || !h) {
        return false;
    }

    var square = canvas.getActiveObject(); 
    square.set('width', w).set('height', h);
  });

  canvas.on('mouse:up', function(options) {
    if(started) {
      started = false;
    }

    var square = canvas.getActiveObject();

    canvas.add(square); 
  });

Here is the detail blog with jsfiddle - https://blog.thirdrocktechkno.com/drawing-a-square-or-rectangle-over-html5-canvas-using-fabricjs-f48beeedb4d3这是带有 jsfiddle 的详细博客 - https://blog.thirdrocktechkno.com/drawing-a-square-or-rectangle-over-html5-canvas-using-fabricjs-f48beeedb4d3

 var Rectangle = (function () { function Rectangle(canvas) { var inst=this; this.canvas = canvas; this.className= 'Rectangle'; this.isDrawing = false; this.bindEvents(); } Rectangle.prototype.bindEvents = function() { var inst = this; inst.canvas.on('mouse:down', function(o) { inst.onMouseDown(o); }); inst.canvas.on('mouse:move', function(o) { inst.onMouseMove(o); }); inst.canvas.on('mouse:up', function(o) { inst.onMouseUp(o); }); inst.canvas.on('object:moving', function(o) { inst.disable(); }) } Rectangle.prototype.onMouseUp = function (o) { var inst = this; inst.disable(); }; Rectangle.prototype.onMouseMove = function (o) { var inst = this; if(!inst.isEnable()){ return; } var pointer = inst.canvas.getPointer(oe); var activeObj = inst.canvas.getActiveObject(); activeObj.stroke= 'red', activeObj.strokeWidth= 5; activeObj.fill = 'transparent'; if(origX > pointer.x){ activeObj.set({ left: Math.abs(pointer.x) }); } if(origY > pointer.y){ activeObj.set({ top: Math.abs(pointer.y) }); } activeObj.set({ width: Math.abs(origX - pointer.x) }); activeObj.set({ height: Math.abs(origY - pointer.y) }); activeObj.setCoords(); inst.canvas.renderAll(); }; Rectangle.prototype.onMouseDown = function (o) { var inst = this; inst.enable(); var pointer = inst.canvas.getPointer(oe); origX = pointer.x; origY = pointer.y; var rect = new fabric.Rect({ left: origX, top: origY, originX: 'left', originY: 'top', width: pointer.x-origX, height: pointer.y-origY, angle: 0, transparentCorners: false, hasBorders: false, hasControls: false }); inst.canvas.add(rect).setActiveObject(rect); }; Rectangle.prototype.isEnable = function(){ return this.isDrawing; } Rectangle.prototype.enable = function(){ this.isDrawing = true; } Rectangle.prototype.disable = function(){ this.isDrawing = false; } return Rectangle; }()); var canvas = new fabric.Canvas('canvas'); var rect = new Rectangle(canvas);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.17/fabric.min.js"></script> Please draw rectangle here <div id="canvasContainer"> <canvas id="canvas" width="400" height="400" style="border: solid 1px"></canvas> </div>

你可以使用这个简单的代码

canvas.add(new fabric.Rect({ left: 110, top: 110, fill: '#f0f', width: 50, height: 50 }));

Slight modification on the mouse up event to allow the object to be selectable and moveable.对鼠标向上事件稍作修改,以允许对象可选择和移动。

Note: adding the object to canvas again on the mouse:up even will add it twice to the canvase and it is the wrong thing to do.注意:在鼠标上再次将对象添加到画布:up 甚至会将其添加到画布两次,这是错误的做法。

 canvas.on('mouse:up', function(o){ isDown = false; var square = canvas.getActiveObject(); square.setCoords(); //allows object to be selectable and moveable });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM