взаимодействовать. js SVG прямоугольный привязка к div с полями - PullRequest
4 голосов
/ 17 марта 2020

В этом jsFiddle у меня есть SVG interact.js прямоугольник, который при изменении размера привязывается к сетке.

Это работает нормально, пока я не начну изменять поля с нуля на число , Прямоугольник находится внутри элемента div #mysvg, и если я изменяю поля элемента div, прямоугольник привязывается неправильно (есть сдвиг).

Попробуйте изменить поля CSS с:

#mysvg { 
   margin-top: 0px; 
   margin-left: 0px; 
}

Кому:

#mysvg { 
   margin-top: 12px; 
   margin-left: 12px; 
}

Затем перезапустите jsFiddle, и вы увидите проблему.

Аналогичная проблема возникает, когда поле тела увеличивается с нуля.

Как решить эту проблему? Есть ли способ изменить размер interact.js относительно div, игнорируя его поле или где div расположен на странице (например, div может находиться внутри другого div)?

1 Ответ

3 голосов
/ 20 марта 2020

В interact.snappers.grid есть свойство offset, которое можно использовать для смещения привязки сетки:

modifiers: [
  interact.modifiers.snap({
    targets: [
      interact.snappers.grid({
        x: 20,
        y: 20,

        // Here set the offset x, y
        // to the margins top and left of the SVG
        offset: { x: 12, y: 12 }

      }),
    ]
  })
]

Вы можете проверить его работоспособность с #mysvg margin-top и margin-left, установленными на 12px в этом jsFiddle , или запустите приведенный ниже фрагмент кода:

var svg = document.getElementById('mysvg');

// draw vertical lines
var gridSize = 20;
for (var i=0;i < 100;i++){
  var line = document.createElementNS("http://www.w3.org/2000/svg", "line");    
  svg.appendChild(line);
  line.setAttribute("x1", (i + 1) * gridSize)
  line.setAttribute("y1", 0)
  line.setAttribute("x2", (i + 1) * gridSize)
  line.setAttribute("y2", 500)
  line.setAttribute("stroke-width", 1)
  line.setAttribute("stroke", 'gray');
}
        
// draw vertical lines
for (var i=0;i < 100;i++){
  var line = document.createElementNS("http://www.w3.org/2000/svg", "line");    
  svg.appendChild(line);
  line.setAttribute("x1", 0)
  line.setAttribute("y1", (i + 1) * gridSize)
  line.setAttribute("x2", 2000)
  line.setAttribute("y2", (i + 1) * gridSize)
  line.setAttribute("stroke-width", 1)
  line.setAttribute("stroke", 'gray');
}

var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
svg.appendChild(rect);
rect.setAttribute('x', 90);
rect.setAttribute('y', 90);
rect.setAttribute('width', 100);
rect.setAttribute('height', 100);
rect.setAttribute('class', 'resize-me');
rect.setAttribute('stroke-width', 2);
rect.setAttribute('stroke', 'black');
rect.setAttribute('fill', 'orange');

interact('.resize-me')
  .resizable({
    edges: { left: true, right: true, bottom: true, top: true },
    margin: 3,
    modifiers: [
      interact.modifiers.snap({
        targets: [
          interact.snappers.grid({
            x: 20,
            y: 20,

            // Here set the offset x, y
            // to the margins top and left of the SVG
            offset: { x: 12, y: 12 }

          }),
        ]
      })
    ]
  })
  .on('resizemove', function(event) {
    var target = event.target;
    var x = (parseFloat(target.getAttribute('endx')) || 0)
    var y = (parseFloat(target.getAttribute('endy')) || 0)

    target.setAttribute('width', event.rect.width);
    target.setAttribute('height', event.rect.height);

    x += event.deltaRect.left
    y += event.deltaRect.top
    target.setAttribute('transform', 'translate(' + x + ', ' + y + ')')

    target.setAttribute('endx', x)
    target.setAttribute('endy', y)
  });
svg {
  width: 100%;
  height: 240px;
  
  -ms-touch-action: none;
  touch-action: none;
  box-sizing: border-box;
}

body { margin: 0px }

#mysvg { 
   margin-top: 12px; 
   margin-left: 12px; 
}
<script src="https://cdn.jsdelivr.net/npm/interactjs@latest/dist/interact.min.js"></script>

<svg id="mysvg"></svg>
...