Страницы

Поиск по вопросам

вторник, 23 апреля 2019 г.

jquery drag and drop связи

Что хочу получить:
Картинка для визуализации. Задача состоит в том что бы связывать блоки (динамически протянуть стрелку от одного блок к другому) и в конце получить структуру для дальнейшей работы. Например:
a link to b
b link to c
Так же у одного блок может быть несколько связей. Прошу подсказать направление, как сделать связи.
перетаскивания сделал так:
jQuery UI Draggable - Default functionality

Drag me


Drag me



Ответ

Рабочий вариант, но код не в лучшем виде. Ссылка на plunker.
"use strict"; var can = $("#can").get(0), ctx = can.getContext('2d'); var boxes = []; function get_box(x, y) { for (var box of boxes) { if (x >= box.x && x < box.x + box.w && y >= box.y && y < box.y + box.h) { return box; } } return null; } function getxy(e) { return {x:e.clientX, y:e.clientY}; } class Box { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.drag = null; this.name = String.fromCharCode("A".charCodeAt() + boxes.length); boxes.push(this); } on_mouse_down(e) { this.drag = { oldx: this.x, oldy: this.y, // old position of box msx: e.clientX, msy: e.clientY // mouse start x, y }; } on_mouse_move(e) { if (!this.drag) return; var dx = e.clientX - this.drag.msx, dy = e.clientY - this.drag.msy; this.x = this.drag.oldx + dx; this.y = this.drag.oldy + dy; draw_boxes(); } on_mouse_up(e) { this.drag = null; } draw() { ctx.save(); ctx.fillRect(this.x, this.y, this.w, this.h); ctx.font = "30px Georgia"; ctx.fillStyle = "white"; ctx.fillText(this.name, this.x + 10, this.y + 30); ctx.restore(); } center() { return {x: this.x + Math.floor(this.w/2), y: this.y + Math.floor(this.h/2) }; } } var link = null, links = []; function on_mouse_event(method_name) { return function (e) { for (var box of boxes) box[method_name](e); } } $("#can").mousedown(function (e) { var p = getxy(e), b = get_box(p.x, p.y); if (e.shiftKey) { new Box(p.x, p.y, 50, 50); draw_all(); return; } if (!b) return; if (e.ctrlKey) { link = {b}; return; } get_box(p.x, p.y).on_mouse_down(e); }); $("#can").mousemove((e) => { if (link) { link.t = getxy(e); } else { for (var box of boxes) box.on_mouse_move(e); } draw_all(); }); $("#can").mouseup((e) => { var x = e.clientX, y = e.clientY, b = get_box(x, y); if (link) { if (link.b == b || !b) { link = null; return; } links.push({from:link.b, to:b}); } else { for (var box of boxes) box.on_mouse_up(e); } link = null; }); $("#getlinks").click((e) => { var msg = ""; for (var l of links) { msg += `Box "${l.from.name}" свзяан с Box "${l.to.name}"
`; } $("#res").html(msg); }); new Box(10, 10, 50, 50); new Box(150, 150, 50, 50); function draw_boxes() { for (var box of boxes) { box.draw(); } } function draw_links() { for (var l of links) { var bc1 = l.from.center(), bc2 = l.to.center(); ctx.beginPath(); ctx.moveTo(bc1.x, bc1.y); ctx.lineTo(bc2.x, bc2.y); ctx.stroke(); } } function draw_link() { var bc = link.b.center(); ctx.beginPath(); ctx.moveTo(bc.x, bc.y); ctx.lineTo(link.t.x, link.t.y); ctx.stroke(); } function draw_all() { ctx.clearRect(0, 0, can.width, can.height); draw_links(); draw_boxes(); if (link) draw_link(); } draw_all(); html, body { margin: 0; padding: 0; }

This text is displayed if your browser does not support HTML5 Canvas.

MouseMove -- перемещение коробок.
Shift + Click -- добавить коробку.
Ctrl (на коробке) + MouseMove -- провести линию.


Комментариев нет:

Отправить комментарий