2013-07-02 7 views
1

Я пытаюсь интегрировать AngularJS с d3 для перетаскивания и изменения размера. Мне удалось создать объект rect, который можно перетаскивать в элементе SVG и изменять размер с помощью ручек изменения размера. Ручки изменения размера работают так, как должны, но изменение размера изменчиво, когда я пытаюсь изменить размер в северном или восточном направлении. Я создал следующий Plunk в качестве демонстрации проблемы: http://plnkr.co/tG19vpyyw0OHMetLOu2U. (Я упростил это, чтобы показать проблему, с которой я столкнулся, так что есть только одна ручка изменения размера.)AngularJS + d3js: проблемы с объектами изменения размера

Работы по перетаскиванию как следует, а также изменение размеров на западном и южном направлениях (также не показано в демо).

Понятно, что я попросил бы об этом сообщество и посмотрел, с кем раньше сталкивался. Спасибо вам всем.

ответ

2

Проблема в том, что вы сами изменяете элемент rect и прилагаемый элемент g. Очень небольшая задержка между установкой размера rect и позицией g просто потому, что это нужно сделать с помощью двух отдельных команд. Во время этой задержки позиция курсора относительно прямоугольника перетаскивания изменяется, запуская новое событие drag со значениями, которые соответствуют несогласованному промежуточному состоянию. Это фиксируется сразу же после (как только атрибуты обоих элементов были скорректированы), а также запускается новое событие drag, которое исправляет несогласованность, но это заметно как мерцание.

Самый простой способ исправить это - изменить размер и положение для rect и ничего для элемента g. Это означает также корректировку положения прямоугольника перетаскивания и делает код менее приятным, но избегает проблемы с синхронизацией/несогласованностью.

Так myrect становится

var myRect = d3.select(document.createElementNS("http://www.w3.org/2000/svg", "rect")) 
      .attr("data-ng-width", "{{square.w}}") 
      .attr("data-ng-height", "{{square.h}}") 
      .attr("stroke", "yellow") 
      .attr("stroke-width", 3) 
      .attr("fill-opacity", 0) 
      .attr("data-ng-x", "{{square.x}}") 
      .attr("data-ng-y", "{{square.y}}"); 

и resizer

var resizer = myGroup.append("rect") 
      .attr("width", 5) 
      .attr("height", 5) 
      .attr("stroke", "blue") 
      .attr("stroke-width", 1) 
      .attr("fill-opacity", 0) 
      .attr("cursor", "nw-resize") 
      .attr("x", "{{square.x-2.5}}") 
      .attr("y", "{{square.y-2.5}}") 
      .call(nresize); 

Я обновил свой код с этим решением here.

+0

Я вижу, что это работает - однако, я вижу, что при функции перетаскивания вы также меняете ширину и высоту прямоугольника? Я пытаюсь полностью понять последствия кода, который вы здесь написали (так как мне придется включать в группу другие элементы, которые должны будут перемещаться вместе с прямоугольником). Кроме того, вы сказали, что задержка вызывает проблему? Если бы я смог найти способ отложить выполнение, это бы устранить проблему? –

+0

Нет, основная проблема заключается в отключении между настройкой атрибутов двух связанных объектов, которые я считаю. Вы должны иметь возможность помещать 'myrect' внутри группы с другими элементами (но не' resizer') без проблем. –

+0

Как получается, что свойство 'transform' группы и координаты x/y квадрата установлены на угловое значение? Я уверен, что я пробовал это раньше и сталкивался с проблемами, когда функция перетаскивания не работала правильно (поскольку группа x/y и rect x/y добавлялись вместе). (Вот почему, первоначально, я исправил координаты прямоугольника до 0,0.) Полагаю, я понимаю, что это работает, но я пытаюсь выяснить, что вы сделали и что я не делал. –

Смежные вопросы