Чтобы получить координаты xy отброшенного элемента в svg: изображение в d3 - PullRequest
1 голос
/ 15 февраля 2020

Здесь я работаю с примером, в котором мне нужно получить значения X и Y отброшенного элемента (используя Jquery drag & drop) из элемента svg: image. Пожалуйста, проверьте мой codepen . В коде ручки вы можете видеть значок rss, который является перетаскиваемым элементом, а основное большое изображение используется в качестве элемента перетаскивания. Основное большое изображение добавляется с помощью d3 svg: image. При перетаскивании значка rss на основное большое изображение, к точке отбрасывания следует добавить значок rss. Итак, в функции удаления (JQuery) я добавил код d3, чтобы добавить значок rss к основному большому изображению.

Я использовал 4 метода для получения значения X & Y точки, на которой выпал значок rss. В коде пера вы можете видеть, что:

Первый метод для извлечения xy-позиции:

 var currentPos = ui.helper.position();
 var parentOffset = $(this).parent().offset();
 var x1 = event.pageX - parentOffset.left;
 var y1 = event.pageY - parentOffset.top;

Второй метод для извлечения xy-позиции:

var dropPositionX = event.pageX - $(this).offset().left;
var dropPositionY = event.pageY - $(this).offset().top;
// Get mouse offset relative to dragged item:
var dragItemOffsetX = event.offsetX;
var dragItemOffsetY = event.offsetY;
// Get position of dragged item relative to drop target:
var x2 = dropPositionX-dragItemOffsetX;
var y2 = dropPositionY-dragItemOffsetY;

Третий метод для извлечь xy positon:

 var x3 = ui.offset.left - $(this).offset().left;
 var y3 = ui.offset.top - $(this).offset().top;

Четвертый способ извлечь xy positon:

    var elem = document.getElementById("floor")
    var rect = elem.getBoundingClientRect();
            var scrollTop = document.documentElement.scrollTop?
                            document.documentElement.scrollTop:document.body.scrollTop;
            var scrollLeft = document.documentElement.scrollLeft?                   
                            document.documentElement.scrollLeft:document.body.scrollLeft;
            var elementLeft = rect.left+scrollLeft;  
            var elementTop = rect.top+scrollTop;

            var x4 = event.pageX-elementLeft;
            var y4 = event.pageY-elementTop;

Присоединение пропущенного значка к основному большому изображению:

svg.append("svg:image")
      .attr('xlink:href', 'http://icons.webpatashala.com/icons/Blueberry-Basic-Icons/Png/rss-icon.PNG')
      .attr('x', x1)  //x2, x3, x4, x5
      .attr('y', y1);  //x2, x3, x4, x5

Но с использованием всех Методы, значок rss не добавляются в точную точку, в которой он отбрасывается. Как получить точное значение X & Y?

1 Ответ

2 голосов
/ 17 февраля 2020

Думаю, я понял, что ты ищешь. Есть несколько вещей, которые следует учитывать при решении этой проблемы:

Масштабирование ViewBox

Это основной вопрос, который необходимо учитывать. Поскольку вы используете свойство viewBox в своем элементе svg и не используете width / height, то независимо от размера окна браузера будет изменяться масштаб видимого холста svg. Это важно учитывать при отбрасывании клонированного изображения, поскольку вы не можете использовать абсолютные top / left координаты. Это может выглядеть нормально на 0, 0, но когда вы начнете отходить от него, вы заметите, что изображение не пропадает там, где вы думаете, что оно должно быть.

Способ обойти это - использовать d3.scaleLinear() (документы здесь ). Это поможет перевести сбрасываемые координаты в координаты вашего SVG. То, как я это сформулировал, заключается в том, что для шкалы X значение domain относится к свойству SVG left к свойствам left + width, а range устанавливается к значениям viewbox x-min и width вашего SVG. , Аналогичный подход используется для шкалы Y (см. Код).

Где SVG находится на вашей странице

Это следующая вещь, которую следует рассмотреть. Это соответствует предыдущему пункту о окне просмотра. Например, если у SVG есть несколько полей, вам необходимо учитывать это при настройке шкалы d3.scaleLinear(). Для этого нужно использовать getBoundingClientRectangle() следующим образом:

const clientRect = document.getElementById('floor').getBoundingClientRect();

Если размер окна изменен

Если размер окна изменен, вам необходимо выполнить сброс шкалы.

Где вы берете изображение из перетаскиваемого элемента

Это может добавить некоторую работу, если вы хотите выяснить, как получить смещение x, y где вы взяли изображение, когда вы впервые захватили его с помощью мыши. Вместо этого я использую свойство cursorAt в конфигурации метода draggable() и задаю для него значение { left: 0, top: 0 }, поэтому при перетаскивании изображения пользователь увидит курсор в левом верхнем углу изображения. Это избавляет вас от необходимости выяснять смещение места, где они захватили изображение.

Вот код, который я использовал в конце (ручка здесь ) (также мне пришлось используйте другой значок, потому что тот, который вы использовали, не загружался для меня).

let scaleX = getScaleX();
let scaleY = getScaleY();

function getScaleX() {
  const clientRect = document.getElementById('floor').getBoundingClientRect();
  return d3.scaleLinear()
    .domain([clientRect.left, clientRect.left + clientRect.width])
    .range([0, 1500])
}

function getScaleY() {
  const clientRect = document.getElementById('floor').getBoundingClientRect();
  return d3.scaleLinear()
    .domain([clientRect.top, clientRect.top + clientRect.height])
    .range([0, 800])
}

window.onresize = function() {
  scaleX = getScaleX();
  scaleY = getScaleY();
};

var svg = d3.select('#floor');

svg.append("svg:image")
  .attr('xlink:href', 'https://wallpapershome.com/images/pages/pic_h/241.jpg')
  .style('width', "100%");

$(function() {
  $("#draggable" ).draggable({
      helper: "clone",
    cursor: 'move',
    containment: "document",
    cursorAt: { top: 0, left: 0 }
  });

  $( "#droppable" ).droppable({
    drop: function( event, ui ) {
      $( this ).addClass( "ui-state-highlight" );

      svg.append("svg:image")
        .attr('xlink:href', 'https://i2.wp.com/icons.iconarchive.com/icons/cornmanthe3rd/plex/512/Communication-RSS-icon.png')
        .attr('x', scaleX(event.pageX))
        .attr('y', scaleY(event.pageY))
        .attr('width', '50px');
    }
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...