Во-первых, для простоты здесь является скрипку о том, как нарисовать базовую линию с помощью мыши и KineticJS: http://jsfiddle.net/projeqht/fF3hh/
Допустим, у вас уже есть два круга на сцене, и вам нужно, чтобы нарисовать линию для их соединения.
Мы можем использовать e.targetNode
для выбора узлов на каждом событии (MouseDown, MouseUp), например:
layer.on("mousedown", function (e) {
var nodeDown = e.targetNode;
}
layer.on("mouseup", function (e) {
var nodeUp = e.targetNode;
}
Нам нужно проверить, если родитель nodeDown
является Kinetic.Group или что-то другое ,
- Если целевой узел
nodeDown
имеет Kinetic.Group для родителей, мы можем использовать эту группу, чтобы сохранить новую строку, а второй целевой узел nodeUp
.
- Если целевой узел
nodeUp
не имеет Kinetic.Group для родителя, нам нужно увидеть, есть ли у nodeUp
группа для родителя. Если nodeUp
имеет Kinetic.Group для родителя, мы можем использовать эту группу для хранения новой строки и первого целевого узла nodeDown
.
- Если ни один из
nodeDown
или nodeUp
не имеет группы для родителя, тогда нам нужно будет создать для них новую группу и добавить все три формы (2 круга и строку) в эту новую группу.
Используйте этот учебник, чтобы узнать, как перемещать фигуры из 1 группы в другую: http://www.html5canvastutorials.com/kineticjs/html5-canvas-move-shape-to-another-container-with-kineticjs/
Кроме того, если вы перемещаете фигуру из одной группы в другую, вы можете remove()
или destroy()
дополнительные группы, если он больше не нужен.
При рисовании линии вам придется отключить перетаскивание фигур, чтобы вы могли перетаскивать и рисовать мышью. Вы можете сделать это, делая что-то похожее на это:
function stopDrag() {
for (var i=0; i<layer.children.length; i++) {
layer.children[i].setDraggable(false);
}
}
function startDrag() {
for (var i=0; i<layer.children.length; i++) {
layer.children[i].setDraggable(true);
}
}
Это заставит все ребенок слоя перетаскиваемого и undraggable, но вы можете захотеть ограничить, что, будучи более конкретным, чем выберите layer.children
. Приятным трюком, который мне нравилось использовать здесь, было имя всех групп, которые были перетаскиваемы как «draggable_shapes», а затем используйте var draggableArray = stage.get('.draggable_shapes')
, чтобы выбрать все группы, которые разрешены для перетаскивания, затем вы можете пропустить этот массив и setDraggable()
.
Еще один момент, который следует отметить, заключается в том, что координаты X и Y линии будут немного сложными для расчета, в зависимости от того, имеет ли она группу в качестве родителя или слоя. Если линия сгруппирована, координаты линии будут относиться к позиции , иначе координаты линии будут относительно Этап (верхний левый угол).
Это позволит вам начать соединение линии с двумя разными кругами. Вам решать логику координат, если вы хотите, чтобы линии соединялись только на внешнем краю кругов.
Возможно, вы захотите добавить прозрачный прямоугольник (атрибут opacity: 0
) за каждым кругом, чтобы на мульдауне с прямоугольником вы вызывали drawLine()
, чтобы начать рисовать линию. Или, если пользователь нажимает на круг, он перетаскивает группу. По крайней мере, это имеет аналогичную функциональность для приложения ясных графиков.
Пользовательский Хит Функция (http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-custom-hit-function-tutorial/), вероятно, будет более чистым способом сделать это, но я не на 100% на использовании пользовательских функций Хит, кто-то еще может знать лучше.
Сообщите мне, если вам нужна дополнительная помощь. Удачи!
Большое спасибо за этот ответ. Я попробую завтра, потому что сейчас у меня в голове большой узел. Я отметил ответ как принятый, потому что на первый взгляд все это кажется очень подробным и логичным для меня, так что еще раз, спасибо! :) – Dominik
+1 для пользовательских функций хита. Это идеальный вариант использования для них –
, поэтому он работает :) только для информации. Только проблема: используя touch-интерфейс, я получаю NaN только для x и y-координат. Любые идеи о том, как изменить код для реализации сенсорных координат? Я попробовал getTouchPosition() и снова getX и так далее, но это не сработало. – Dominik