2015-02-10 1 views
5

Если бумага слишком большая для div, на которой она показана, я хотел бы сделать бумагу перетаскиваемой.Как сделать бумагу перетаскиваемой

Я пробовал документы пустыми: событиями указателей поворота и указателей, но не мог просто следить за mousemovement. Я также попытался сделать элемент бумаги перетаскиваемой через jquery, но ничего похожего на трюк ...

Есть ли способ сделать это?

ответ

4

Я предлагаю следующее:

  1. зарегистрировать обработчик для бумаги blank:pointerdown event, что будет инициировать тащит бумагу (хранить флаг, который вы будете использовать в вашем mousemove обработчиком признать, что бумага в «панорамирование " государство).
  2. Поместите большую бумагу в контейнер <div> с CSS overflow: auto. Это <div> будет вашим маленьким окном к большой бумаге.
  3. зарегистрировать обработчик для тела документа mousemove событие (потому что вы, скорее всего, хотите, чтобы бумага перетаскивалась, даже если курсор мыши покидает область бумаги?). В этом обработчике вы будете устанавливать свойства scrollLeft и scrollTop вашего контейнера <div>, делая бумагу «панорамирование». Для настройки свойств scrollLeft и scrollTop вы будете использовать свойства объекта и clientY объекта события вместе с теми же свойствами, которые были сохранены ранее в вашем обработчике blank:pointerdown. (другими словами, вам нужны эти, чтобы найти смещение панорамирования с последних mousemove/blank:pointerdown).
  4. зарегистрировать обработчик для MouseUp документа тела и в этом обработчике очистить бумагу тащит флаг, который вы установили на шаге 1.
+0

Это работает замечательно! Большое спасибо! – Maria

+1

Это чистый гений. Я не мог понять, как это сделать. Спасибо. JointJS просто блестяще. – Karl

11

Я знаю, что это немного старая нить, но я застрял с этим для и натолкнулся на аккуратное решение, используя библиотеку SVG Pan и Zoom. Git hub link here

EDIT - Я создал plunker шагов ниже (плюс некоторые дополнительные) здесь: SVG panning with Jointjs

Первый шаг после создания документа является инициализирует SVG Pan и Zoom:

panAndZoom = svgPanZoom(targetElement.childNodes[0], 
     { 
      viewportSelector: targetElement.childNodes[0].childNodes[0], 
      fit: false, 
      zoomScaleSensitivity: 0.4, 
      panEnabled: false 
     }); 

Где targetElement - это div, в который попала бумага для совместной работы. Jointjs создаст в нем элемент SVG (следовательно, childNodes [0]), и внутри этого элемента первым элементом является тег viewport (следовательно, childNodes [0] .childNodes [0] в viewportselector). На этом этапе кастрюля отключена, потому что в моем случае он будет работать с элементами перетаскивания на бумаге. Вместо того, что я делаю, это сохранить ссылку на объект panAndZoom, а затем включите панорамирование и выключаться по пустым: pointerdown и пустым: pointerup событий:

paper.on('blank:pointerdown', function (evt, x, y) { 
     panAndZoom.enablePan(); 
    }); 
paper.on('cell:pointerup blank:pointerup', function(cellView, event) { 
      panAndZoom.disablePan(); 

});

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

+0

Привет, Лука, спасибо за ссылку. Я изо всех сил, чтобы заставить его работать, хотя, вероятно, из-за целевого элемента;) , если у меня есть бумага = новый joint.dia.Paper ({эш: $ («# MyId»), Должен ли я использовать . вар panAndZoom = svgPanZoom ($ ('# MyId') ChildNodes [0] Если да, то я получаю ошибку "TypeError: не удается прочитать свойство '0' неопределенных"? – jmls

+0

jsfiddle того, как вы» вы сделали это было бы очень полезно;) – jmls

+0

Эй, в данный момент, я должен уметь сортировать вас с помощью jsfiddle в понедельник вечером. В то же время, когда вы настраиваете svgpanzoom, вам нужно указать его элементу svg. если #myid дает вам идентификатор элемента svg, тогда вам не нужны детдоны pa к.т.. Если #myid дает вам div выше svg, тогда вам нужна часть детдомов. Id предлагает использовать окно chrome devtools, чтобы просмотреть html, чтобы узнать, как вы получаете элемент svg. –

11

Это может быть достигнуто с помощью комбинации событий JointJS и документировать события.Дисплей графика заключен в div:

<div id='diagram'></div> 

Затем добавить обработчик событий для JointJS, сначала pointerdown события, где мы храним начальную позицию перетаскивания:

paper.on('blank:pointerdown', 
    function(event, x, y) { 
     dragStartPosition = { x: x, y: y}; 
    } 
); 

Тогда к концу перетаскивание (pointerup), когда мы удалим переменные мы сохраняем позицию в (он также действует как флаг, есть ли активное сопротивление в процессе):

paper.on('cell:pointerup blank:pointerup', function(cellView, x, y) { 
    delete dragStartPosition; 
}); 

Поскольку JointJS не выставляет событие «перемещение указателя на бумагу», нам необходимо использовать событие документа mousemove. Например, с JQuery:

$("#diagram") 
    .mousemove(function(event) { 
     if (dragStartPosition) 
      paper.translate(
       event.offsetX - dragStartPosition.x, 
       event.offsetY - dragStartPosition.y); 
    }); 

Мы получаем сопротивление начальных координат и текущее положение указателя и обновить позицию бумаги с помощью paper.translate() вызова.

ВНИМАНИЕ: если масштабировать бумагу (используя paper.scale()), вы должны также масштабировать начальную позицию перетаскивания:

var scale = V(paper.viewport).scale(); 
dragStartPosition = { x: x * scale.sx, y: y * scale.sy}; 

Вызовы paper.translate() будет обновлять в нужное положение.

+0

Это работало очень хорошо (вместе с масштабированием), никаких дополнительных libs не требуется. Большое спасибо. – pootzko

+0

В объединении v1.1 paper.setOrigin (x, y) устарел в пользу paper.translate (x, y). http://resources.jointjs.com/docs/jointjs/v1.1/joint.html –

+0

Отличный материал, спасибо. Было бы намного быстрее, если бы вы разместили весь код в одном блоке, потому что мне трудно было его правильно собрать. :) – Sam