Как установить требуемый clientRect x и y для фигуры? - PullRequest
0 голосов
/ 31 января 2019

Допустим, у меня есть 2 Rect с, один большой, один маленький, оба в одном Layer.Нет Group с и других Shape с.Маленький Rect - перетаскиваемый, изменяемый размер и вращающийся, большой - статический.

Я хочу убедиться, что вы не можете перетащить маленький за пределы большого, и я хочу любое вращение или масштабированиемаленький Rect, который нужно соблюдать.

Я использую getClientRect на обоих Rect s, чтобы определить границы перетаскивания.Теперь, когда я знаю нужные x и y для моего маленького ограничивающего прямоугольника Rect, как мне его установить?Я не могу сделать setAbsolutePosition({ x, y }), потому что маленький прямоугольник может вращаться, что означает, что getAbsolutePosition().x !== getClientRect().x.Я пытался использовать getAbsoluteTransform().point() для преобразования координат, но мне не повезло.

Заранее спасибо.

1 Ответ

0 голосов
/ 01 февраля 2019

Это может привести вас в путь.Поверните прямоугольник с помощью преобразователя, чтобы он попал в красный прямоугольник, или перетащите его, чтобы увидеть проверку границ с помощью эффекта прямоугольника клиента.Я использовал клиентский прямоугольник в преобразователе boundBoxFunc и rect.dragBoundFunc.

Примечание: существует проблема в том, что вычисления перекрытия так или иначе покидают прямоугольник так, что он перекрывает границу.Возможно, ошибка будет решена.

var stage = new Konva.Stage({
  container: 'canvas-container',
  width: 650,
  height: 300
});


var layer = new Konva.Layer();
stage.add(layer);

var rectOuter = new Konva.Rect({
   width: 240, height: 150, x: 80, y: 80, draggable: true, stroke: 'red'
  })
layer.add(rectOuter);

var rect = new Konva.Rect({
   width: 40, height: 50, x: 140, y: 140, draggable: true, fill: 'cyan',
  dragBoundFunc: function(newBoundBox) {
    var pos = rect.getClientRect();

    if (intersectRect(pos,  rectOuter.getClientRect())){
      return {
        x: oldBoundBox.x,
        y: oldBoundBox.y      
      }      
    }
    oldBoundBox.x = newBoundBox.x; // note old box for use if we deny the drag
    oldBoundBox.y = newBoundBox.y;
    return {
      x: newBoundBox.x,
      y: newBoundBox.y      
    }
  }  
  })
layer.add(rect);
var oldBoundBox = rect.getAbsolutePosition();

var rect2 = new Konva.Rect ({
  stroke: 'magenta', listening: false,  
})
layer.add(rect2);

var text = new Konva.Text({
  x: 5,
  y: 5,
});
layer.add(text);
updateText();


 
  // make the transformer for the image
  var transformer = new Konva.Transformer({
    node: rect,
    enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
      boundBoxFunc: function (oldBoundBox, newBoundBox) {
        var pos = rect.getClientRect();
        
        if (intersectRect(pos,  rectOuter.getClientRect())){
          return oldBoundBox;
        }
        
        return newBoundBox
      }    
  });
  layer.add(transformer);

    rect.on('dragmove', function () {
      updateText();
    })
    rect.on('transform', function () {
      updateText();
    });

   function updateText() {
     var pos = rect.getClientRect();
      var lines = [
        'x: ' + rect.x(),
        'y: ' + rect.y(),
        'rotation: ' + rect.rotation(),
        'width: ' + rect.width(),
        'height: ' + rect.height(),
        'scaleX: ' + rect.scaleX(),
        'scaleY: ' + rect.scaleY(),
        'client: ' + pos.x + ', ' + pos.y
      ];
     text.text(lines.join('\n'));
    
     // use rect2 to give a view on what is happening as we translate
     rect2.position({x: pos.x, y: pos.y});
     rect2.width(pos.width);
     rect2.height(pos.height);
     
      layer.batchDraw();
    }

layer.draw()
stage.draw()

// check if the rects overlap
function intersectRect(kr1, kr2) {
  var r1 = makeGeomRect(kr1, 0); // add left & right properties
  var r2 = makeGeomRect(kr2, 10);
  
  return !(r2.left <= r1.left && 
           r2.right > r1.right && 
           r2.top < r1.top &&
           r2.bottom > r1.bottom);
}
  

// make a handier rect - takes a rect with x, y, width, height and gives it left and right 
function makeGeomRect (r, padding){
  
  var out = {
    left: r.x + padding,
    right: r.x + r.width - padding,
    top: r.y + padding,
    bottom: r.y + r.height - padding    
  }
  return out;
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.min.js"></script>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-editor">
  <div id="canvas-container"></div>
</div>

Запустите фрагмент на весь экран, чтобы увидеть всю славу

...