Как ограничить поведение перетаскивания d3.js на карте Меркатора

Я реализовал карту в svg-элементе с функцией меркатора d3.js. На карте представлен только конкретный город - все, что находится за пределами карты города, не имеет отношения к моему проекту.

Теперь я хочу реализовать на этой карте некоторые функции, такие как zoom() и drag().

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

Для обычных svg-элементов это работает:

var drag = d3.behavior.drag()
                 .on("drag", dragmove);

function dragmove(d) {
    var x = Math.max(0, Math.min('width-of-svg-element', d3.event.x));
    var y = Math.max(0, Math.min('height-of-svg-element', d3.event.y));
    d3.select(this)
    .attr("transform", "translate(" + x + "," + y + ")");
    }

Но это не работает для моей карты Меркатора.

пожалуйста, помогите мне :(

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

Вот небольшой пример: https://jsfiddle.net/c55w7u9e/

Мое намерение состоит в том, чтобы у пользователя не было возможности перетащить красный круг (в этом примере, но в моем проекте карта) за пределы элемента svg...


person GenXGer    schedule 15.04.2016    source источник
comment
У вас есть пример, который вы показываете? Предпочтительно на JSFiddle?   -  person thatOneGuy    schedule 15.04.2016
comment
jsfiddle.net/c55w7u9e   -  person GenXGer    schedule 15.04.2016


Ответы (1)


Обновленная скрипта: https://jsfiddle.net/thatoneguy/c55w7u9e/4/

Вы не учитывали свой радиус. Он работал, но вы этого не видите. Обновить перетаскивание на это:

function dragmove(d) {
    var x = Math.max(0, Math.min(width - radius, d3.event.x));
    var y = Math.max(0, Math.min(height - radius, d3.event.y));
    d3.select(this)
    .attr("transform", "translate(" + x + "," + y + ")");
    }

Справка по этому вопросу: Объяснение функции dragmove Майка Бостока d3.js

И этот пример: http://bl.ocks.org/mbostock/1557377 //think он офлайн...

Я бы использовал эту функцию для ограничения, она работает лучше:

function dragmove(d) {
  d3.select(this)
      .attr("cx", d.x = Math.max(radius, Math.min(width - radius, d3.event.x)))
      .attr("cy", d.y = Math.max(radius, Math.min(height - radius, d3.event.y)));
        }

Обновлена ​​скрипта из примеров: https://jsfiddle.net/thatoneguy/c55w7u9e/5/

person thatOneGuy    schedule 15.04.2016