SVG и JavaScript: перемещение элементов с помощью мыши только перемещает элементы вниз и вправо - PullRequest
0 голосов
/ 24 декабря 2018

Этот код должен позволять пользователям перемещать элементы SVG, но по какой-то причине элементы перемещаются только вправо и вниз, независимо от движения мыши.

Другие вопросы как этот похожи, но не помогают.

Разве вы не можете смешивать getBoundingClientRect с манипулированием атрибутами x и y элемента?

Поскольку атрибуты могут содержать процентные значения, мы используемgetBoundingClientRect как основная истина для позиции элемента.

Codepen: https://codepen.io/anon/pen/ZVKvgp

var selectedElem = $("#imageBox1");
var isMoving = false;
var mouseLastX = null;
var mouseLastY = null;

$(document).bind('mousedown', function(e) {
   isMoving = true;
});

$(document).bind('mouseup', function(e) {
    isMoving = false;
    mouseLastX = null;
    mouseLastY = null;
});

$(document).bind('mousemove', function(event) {
     // Ignore if not moving
     if (!isMoving) {
        return;
     }

     // Exit if attempting to move, but no element is selected.
     if (!selectedElem) {
        console.log("Error moving element: no selected element.");
     }

     // If here, move selected element.
     // Get current mouse position.
     var mouseCurX = event.pageX;
     var mouseCurY = event.pageY;

     // Set last position? Must check null explicitly in case values are 0.
     if (mouseLastX == null || mouseLastY == null) {
        mouseLastX = mouseCurX;
        mouseLastY = mouseCurY;
     }

     // Get current values for selected element.
     var elemClientRect = selectedElem[0].getBoundingClientRect();
     var elemX = elemClientRect.x;
     var elemY = elemClientRect.y;

     // Set deltas.
     var deltaX = mouseCurX - mouseLastX;
     var deltaY = mouseCurY - mouseLastY;

     // Set new element position.
     var newX = elemX + deltaX;
     var newY = elemY + deltaY;

     // Store mouse position.
     mouseLastX = mouseCurX;
     mouseLastY = mouseCurY;

     // Update element.
     selectedElem.attr("x", newX);
     selectedElem.attr("y", newY);
});

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

Существует несколько проблем

  1. getBoundingClientRect даст вам x и y относительно страницы, однако атрибуты x и y относятся кродительский контейнер
  2. Начальные атрибуты x и y imageBox1 оба 25%, поэтому вы не можете просто добавить к этому пиксели, вам нужно использовать формат calc(25% + << delta >>px)

Вот как заставить изображение двигаться так, как вы хотите:

var selectedElem = $("#imageBox1");
var isMoving = false;
var mouseLastX = null;
var mouseLastY = null;

$(document).bind('mousedown', function(e) {
   isMoving = true;
});

$(document).bind('mouseup', function(e) {
    isMoving = false;
    mouseLastX = null;
    mouseLastY = null;
});

$(document).bind('mousemove', function(event) {
     // Ignore if not moving
     if (!isMoving) {
        return;
     }

     // Exit if attempting to move, but no element is selected.
     if (!selectedElem) {
        console.log("Error moving element: no selected element.");
     }

     // If here, move selected element.
     // Get current mouse position.
     var mouseCurX = event.pageX;
     var mouseCurY = event.pageY;
  
     // Set last position? Must check null explicitly in case values are 0.
     if (mouseLastX && mouseLastY) {

       // Get current values for selected element.
       var currX = selectedElem.attr("x");
       var currY = selectedElem.attr("y");
       var elemXpct = parseInt(currX.match(/\d+(?=%)/));
       var elemYpct = parseInt(currY.match(/\d+(?=%)/));
       var elemXpxls = parseInt(currX.match(/\d+(?=px)/) || 0) * (/-/.test(currX) ? -1 : 1);
       var elemYpxls = parseInt(currY.match(/\d+(?=px)/) || 0) * (/-/.test(currY) ? -1 : 1);

       // Set deltas.
       var deltaX = mouseCurX - mouseLastX;
       var deltaY = mouseCurY - mouseLastY;
       
       // Set new element position.
       var newX = elemXpxls + deltaX;
       var newY = elemYpxls + deltaY;
       
       var newXsign = newX < 0 ? '-' : '+';
       var newYsign = newY < 0 ? '-' : '+';
       
       // Update element.
       selectedElem.attr("x", `calc(${elemXpct}% ${newXsign} ${Math.abs(newX)}px)`);
       selectedElem.attr("y", `calc(${elemXpct}% ${newYsign} ${Math.abs(newY)}px)`);
     }
  
     // Store mouse position.
     mouseLastX = mouseCurX;
     mouseLastY = mouseCurY;

});
.imageBox {
  cursor: move;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg id="rootBox" width="375" height="812" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  
    <rect x="0%" y="0%" width="100%" height="100%" fill="beige" />
  
    <svg id="imageBox1" class="imageBox" x="25%" y="25%" width="50%" height="50%">
       <image class="image" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" xlink:href="https://www.dropbox.com/s/bzm1y7tjrhl872s/Screenshot.png?raw=1" />
       <image class="frame" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" xlink:href="https://www.dropbox.com/s/6njspwfz2hgfd03/iPhone_X_Black.png?raw=1" />
    </svg>
    
</svg>
0 голосов
/ 24 декабря 2018

Если цель состоит в том, чтобы сделать SVG подвижным, вы можете использовать перетаскивание из jquery.

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>

<script> $(function () { $("#draggable").draggable(); }); </script>

и ваш html

<svg id="draggable" width="375" height="812" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <rect x="0%" y="0%" width="100%" height="100%" fill="beige" /> <svg id="imageBox1" class="imageBox" x="25%" y="25%" width="50%" height="50%"> <image class="image" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" xlink:href="https://www.dropbox.com/s/bzm1y7tjrhl872s/Screenshot.png?raw=1" /> <image class="frame" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" xlink:href="https://www.dropbox.com/s/6njspwfz2hgfd03/iPhone_X_Black.png?raw=1" /> </svg> </svg>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...