Установите ограничение на перетаскивание объекта в Fabric.js

Я новичок в структуре js, чтобы установить предел сопротивления enter image description here

Я также попробую с https://github.com/kangax/fabric.js/wiki/Working-with-events

не может получить решение.

пожалуйста, проверьте прикрепленное изображение, объект может переместить любую программу, но она должна отображаться только в красной области. Мне это нужно. помогите мне... спасибо заранее!

Ответ 1

Что сработало для меня, так это создать прослушиватель событий для события object:moving. Когда происходит переход, вы обновляете переменные goodtop и goodleft и как только вы находитесь за пределами границ, чтобы переместить объект в последние хорошие точки.

var goodtop, goodleft, boundingObject;

canvas.on("object:moving", function(){
    var obj = this.relatedTarget;
    var bounds = boundingObject;
    obj.setCoords();
    if(!obj.isContainedWithinObject(bounds)){
        obj.setTop(goodtop);
        obj.setLeft(goodleft);
        canvas.refresh();    
    } else {
        goodtop = obj.top;
        goodleft = obj.left;
    }  
});

Ответ 2

В то время как ответ Orangepill верен, он вызывает "заикание", когда ваш объект попадает на границы объекта. Если у вас прямоугольная ограничивающая рамка (а не сложный ограничивающий объект), альтернативой является то, что объект можно перетаскивать по границам и "скользить" вдоль ограничивающего прямоугольника. Вы делаете это, закрывая значения координат и позволяя другому размеру двигаться как обычно. Пример фрагмента будет выглядеть так:

var canvas = new fabric.Canvas("bounded");

var boundingBox = new fabric.Rect({
  fill: "none",
  width: 600,
  height: 400,
  hasBorders: false,
  hasControls: false,
  lockMovementX: true,
  lockMovementY: true,
  evented: false,
  stroke: "red"
});

var movingBox = new fabric.Rect({
  width: 100,
  height: 100,
  hasBorders: false,
  hasControls: false
});

canvas.on("object:moving", function() {
  var top = movingBox.top;
  var bottom = top + movingBox.height;
  var left = movingBox.left;
  var right = left + movingBox.width;

  var topBound = boundingBox.top;
  var bottomBound = topBound + boundingBox.height;
  var leftBound = boundingBox.left;
  var rightBound = leftBound + boundingBox.width;

  // capping logic here
  movingBox.setLeft(Math.min(Math.max(left, leftBound), rightBound - movingBox.width));
  movingBox.setTop(Math.min(Math.max(top, topBound), bottomBound - movingBox.height));
});

canvas.add(boundingBox);
canvas.add(movingBox);

Посмотрите этот пример в JSFiddle здесь

Ответ 3

Ответ Felix Fung был отправной точкой, но есть много вещей, которые следует учитывать. Вот версия, которая учитывает некоторые из них.

Он обрабатывает холст, имеющий преобразование видового экрана (т.е. увеличенное/развернутое) и объекты, которые имеют центральное начало, а не left/top-origined. Он также ограничивает объекты более широкими/выше, чем область просмотра, сверху/слева, а не нижней/правой.

canvas.on("object:moving", function(e) {
  var obj = e.target;
  var canvas = obj.canvas;
  var top = obj.top;
  var left = obj.left;
  var zoom = canvas.getZoom();
  var pan_x = canvas.viewportTransform[4];
  var pan_y = canvas.viewportTransform[5];

  // width & height we are constraining to must be calculated by applying the inverse of the current viewportTransform
  var c_width = canvas.width / zoom;
  var c_height = canvas.height / zoom;


  var w = obj.width * obj.scaleX
  var left_adjust, right_adjust
  if(obj.originX == "center") {
    left_adjust = right_adjust = w / 2;
  } else {
    left_adjust = 0;
    right_adjust = w;
  }

  var h = obj.height * obj.scaleY;
  var top_adjust, bottom_adjust;
  if(obj.originY == "center") {
    top_adjust = bottom_adjust = h / 2;
  } else {
    top_adjust = 0;
    bottom_adjust = h;
  }

  // if you need margins set them here
  var top_margin = 0;
  var bottom_margin = 0;
  var left_margin = 0;
  var right_margin = 0;


  var top_bound = top_margin + top_adjust - pan_y;
  var bottom_bound = c_height - bottom_adjust - bottom_margin - pan_y;
  var left_bound = left_margin + left_adjust - pan_x;
  var right_bound = c_width - right_adjust - right_margin - pan_x;

  if( w > c_width ) {
    obj.setLeft(left_bound);
  } else {
    obj.setLeft(Math.min(Math.max(left, left_bound), right_bound));          
  }

  if( h > c_height ) {
    obj.setTop(top_bound);
  } else {
    obj.setTop(Math.min(Math.max(top, top_bound), bottom_bound));          
  }
});

Ответ 4

СМОТРЕТЬ РАБОЧИЙ ПРИМЕР Это так же просто, как вода, попробуйте это

просто используйте этот js

<script type="text/javascript">
   //use global variable for canvas object


  var canvas;
  var ctx;
 function onLoad() {
  //get fabric canvas with id mycanvas


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


   canvas.on("mouse : down",function{

   //get canvas 2d context
   ctx = canvas.getContext("2d");

   ctx.beginPath();
   ctx.rect(115,60,221,390);//specify bounded rectangle
   ctx.closePath();
   ctx.clip();
   ctx.save();
  });
    //now restore the context on mouse up

    canvas.on("mouse : up",function(){
         ctx.restore();//restore the context
    });
}



 </script>

Надеюсь, это поможет вам. Njoy кодирования:)  теперь u может иметь одинаковую область отсечения для каждого объекта, поддерживаемого Fabric.js для преобразования и перемещения. попробуйте:).