Canvas: Rectangles-привязка к сетке / привязка к объектам

мне удалось манипулировать тканью.js для добавления оснастки и масштабирования в функциональность сетки по:

var grid = 100;
//Snap to Grid
canvas.on('object:moving', function (options) {
    options.target.set({
        left: Math.round(options.target.left / grid) * grid,
        top: Math.round(options.target.top / grid) * grid
    });
});
canvas.on('object:scaling', function (options) {
    options.target.set({
        left: Math.round(options.target.left / grid) * grid,
        top: Math.round(options.target.top / grid) * grid
    });
});

теперь я хочу добавить привязку к функциональности объектов. Моя идея состояла в том, чтобы проверить пересечение двух объектов, а затем как-то зафиксировать движение. Я знаю, что это не лучшая попытка, но, по крайней мере, она привязывается к нему, но больше не позволяет перемещать объект. И: сейчас это не реализовано хорошо. Смотри:http://jsfiddle.net/gcollect/y9kyq/

Я три вопроса:

  1. "привязка" не работает хорошо, потому что атрибут объекта слева каким-то образом зависит от указателя. Репликация путем перетаскивания объекта и просмотра вывода элементов управления. Например, при перемещении красного прямоугольника в положение слева: 62 прямоугольник не пересекается с синим прямоугольником и все еще может удаляться. Как я могу перезагрузить фактическое левое значение прямоугольника. Из-за моей привязки к линиям сетки, он слева:100, а не слева:62.
  2. любой идея, как я могу добавить привязку к функциональности объекта? И запретить пересечение?
  3. как я могу проверить это для N объектов, а не только для двух?

Спасибо за ваши комментарии.

PS: Пример jsfiddle не показывает масштаб для функциональности сетки, потому что ему нужна ткань.JS манипуляции в строке: 11100

var distroundedforgrid = Math.round(dist/100)*100;      
      transform.newScaleX = Math.round((transform.original.scaleX * distroundedforgrid / lastDist)*10)/10;
      transform.newScaleY = Math.round((transform.original.scaleY * distroundedforgrid / lastDist)*10)/10;

      target.set('scaleX', transform.newScaleX);
      target.set('scaleY', transform.newScaleY);
    }

3 ответов


для тех, кто еще заинтересован в решении: Я решил это здесь:https://stackoverflow.com/a/22649022/3207478 См. jsfiddle:http://jsfiddle.net/gcollect/FD53A/

работает с .oCoords.tl .tr .bl. and .br solved it.


для масштабирования на основе сетки см. этой JSfiddle

function snapScaling(options) {
    var target = options.target;
    var type = canvas.getActiveObject().get('type');
    var corner = target.__corner;
    var w = target.getWidth();
    var h = target.getHeight();
    var snap = {   // Closest snapping points
      top: Math.round(target.top / grid) * grid,
      left: Math.round(target.left / grid) * grid,
      bottom: Math.round((target.top + h) / grid) * grid,
      right: Math.round((target.left + w) / grid) * grid,
    };
    snap.height = snap.top - snap.bottom;
    if(snap.height < 0) {
      snap.height *= - 1;
    }
    snap.width = snap.left - snap.right;
    if(snap.width < 0) {
      snap.width *= - 1;
    }
    switch (corner) {
      case 'mt':
      case 'mb':
          target.top = snap.top;
          target.height = snap.height;
          target.scaleY = 1;
        break;
      case 'ml':
      case 'mr':
        target.left = snap.left;
        target.width = snap.width;
        target.scaleX = 1;
        break;
      case 'tl':
      case 'bl':
      case 'tr':
      case 'br':
        target.top = snap.top;
        target.left = snap.left;

        target.height = snap.height;
        target.width = snap.width;

        target.scaleY = 1;
        target.scaleX = 1;
    }

    if(type == 'ellipse') {
      target.rx = (target.width / 2);
      target.ry = (target.height / 2);
    }
  }

Я понял, что это решает привязку к объектам на оси x и будет работать над решением для оси y. см. JSfiddle здесь.

Я сделал это, установив новое "левое"-значение для активного объекта, когда я обнаруживаю пересечение.

        if (options.target.isContainedWithinObject(obj)||options.target.intersectsWithObject(obj)||obj.isContainedWithinObject(options.target)) {

            var distx = ((obj.left + obj.width)/2) - ((options.target.left + options.target.width)/2);
            var disty = ((obj.top + obj.height)/2) - ((options.target.top + options.target.height)/2);                  

            if (distx > 0){
                options.target.left = obj.left - options.target.width;
            } else {
                options.target.left = obj.left + obj.width;
            }

        }