From e192beee227622e75b31340cc8348d36570291c1 Mon Sep 17 00:00:00 2001 From: Patrick Simianer Date: Mon, 31 Aug 2015 18:46:46 +0200 Subject: adding, removal of objects and alignment links --- edit.html | 4 +- r.js | 510 ++++++++++++++++++++++++++++++++++++++++++-------------------- 2 files changed, 351 insertions(+), 163 deletions(-) diff --git a/edit.html b/edit.html index b96bf3a..0f2bb0a 100644 --- a/edit.html +++ b/edit.html @@ -15,9 +15,7 @@

TODO

diff --git a/r.js b/r.js index 5fe83f5..2cc5f63 100644 --- a/r.js +++ b/r.js @@ -1,194 +1,384 @@ -Raphael.fn.connection = function (obj1, obj2, line, bg) { +/* + * global vars and data + * + */ +var shapes_by_id = {}, + r, + curDrag = null, + shapes = [], + target_shapes = [], + texts = [], + connections = {}, + margin = 30, + padding = margin/3, + xbegin = 80, + ybegin = 5, + box_height = 50, + line_margin = 150, + ysource = ybegin, + ytarget = ysource+line_margin; + font_size = 20, + id = 0, + connect_mode = false, + connect_mode_shape = null, + rm_shape = null, + text_att = { 'fill': '#000', 'stroke': 'none', 'text-anchor': 'start', 'font-size': font_size, 'font-family': 'Times New Roman' }, + shape_att = { fill: "#eee", stroke: "#000", "fill-opacity": 0, "stroke-width": 1 } + source = ["das", "ist ein", "kleines", "haus", "gewesen", "."], // data + target = ["this", "has been", "a", "small", "house", "."], // ^ + align = [0, 1, 3, 4, 1, 5]; // ^ + +/* + * connection + * + */ +Raphael.fn.connection = function (obj1, obj2, line, bg) +{ if (obj1.line && obj1.from && obj1.to) { line = obj1; obj1 = line.from; obj2 = line.to; } + if (!obj1.getBBox() || !obj2.getBBox()) + return; var bb1 = obj1.getBBox(), - bb2 = obj2.getBBox(); - var x1 = bb1.x+bb1.width/2, + bb2 = obj2.getBBox(), + x1 = bb1.x+bb1.width/2, y1 = bb1.y+bb1.height, x2 = bb2.x+bb2.width/2, - y2 = bb2.y; - var path = ["M", x1, y1, "L", x2, y2]; + y2 = bb2.y, + path = ["M", x1, y1, "L", x2, y2]; if (line && line.line) { line.bg && line.bg.attr({path: path}); line.line.attr({path: path}); } else { - var color = typeof line == "string" ? line : "#000"; return { bg: bg && bg.split && this.path(path).attr({stroke: bg.split("|")[0], fill: "none", "stroke-width": bg.split("|")[1] || 3}), - line: this.path(path).attr({stroke: color, fill: "none"}), + line: this.path(path).attr({stroke: "#000", fill: "none"}), from: obj1, to: obj2 }; } }; - -add_obj = function() +var conn_str = function (obj1, obj2) { - r.rect(350,105,100,40); + return obj1["id_"]+"-"+obj2["id_"]; } - -var shapes_by_id = {}, - curDrag = null, - shapes = [], - texts = [], - r; -window.onload = function () { - r = Raphael("holder", 640, 200); // FIXME: variable sz - var dragger = function () { - curDrag = this; - if (this.type == "text") - curDrag = this.pair; - // remember original coords - this.ox = this.attr("x"); - this.oy = this.attr("y"); - this.pair.ox = this.pair.attr("x"); - this.pair.oy = this.pair.attr("y"); - if (this.type != "text") - this.animate({ "fill-opacity": .2 }, 500); - if (this.pair.type != "text") - this.pair.animate({ "fill-opacity": .2 }, 500); - }, - move = function (dx, dy) { - var att = { x: this.ox + dx, y: this.oy }; - this.attr(att); - att = { x: this.pair.ox + dx, y: this.pair.oy }; - this.pair.attr(att); - for (i = connections.length; i--;) { - r.connection(connections[i]); - } - r.safari(); - }, - collide = function collide(obj) { - if (obj.type != 'rect') - return; - if (curDrag["grid_"] > obj["grid_"]) { - if (curDrag.getBBox().width < obj.getBBox().width && - curDrag.getBBox().x > (obj.getBBox().x+obj.getBBox().width/3)) { - return; - } - att = { x: obj.attr("x")+curDrag.getBBox().width+(margin-2*padding) }; - obj.attr(att); - att = { x: obj.pair.attr("x")+curDrag.getBBox().width+(margin-2*padding) }; - obj.pair.attr(att); - } else { - if (curDrag.getBBox().width < obj.getBBox().width && - curDrag.getBBox().x < (obj.getBBox().x+obj.getBBox().width/3)) { - return; - } - att = { x: obj.attr("x")-(curDrag.getBBox().width+(margin-2*padding)) }; - obj.attr(att); - att = { x: obj.pair.attr("x")-(curDrag.getBBox().width+(margin-2*padding)) }; - obj.pair.attr(att); +var make_conn = function(obj1, obj2) +{ + connections[conn_str(obj1,obj2)] = r.connection(obj1, obj2); +}, +rm_conn = function(id1, id2) +{ + var b = false; + for (var i=0; i obj["grid_"]) { + if (curDrag.getBBox().width < obj.getBBox().width && + curDrag.getBBox().x > (obj.getBBox().x+obj.getBBox().width/3)) { + return; + } + att = { x: obj.attr("x")+curDrag.getBBox().width+(margin-2*padding) }; + obj.attr(att); + att = { x: obj.pair.attr("x")+curDrag.getBBox().width+(margin-2*padding) }; + obj.pair.attr(att); + } else { + if (curDrag.getBBox().width < obj.getBBox().width && + curDrag.getBBox().x < (obj.getBBox().x+obj.getBBox().width/3)) { + return; + } + att = { x: obj.attr("x")-(curDrag.getBBox().width+(margin-2*padding)) }; + obj.attr(att); + att = { x: obj.pair.attr("x")-(curDrag.getBBox().width+(margin-2*padding)) }; + obj.pair.attr(att); + } + // switch grid pos + var tmpx = curDrag["grid_"]; + curDrag["grid_"] = obj["grid_"]; + obj["grid_"] = tmpx; +}, +up = function () { + if (this["delete_me_"]) { + var del = shapes_by_id[this["id_"]]; + for (key in connections) { + if (key.split("-")[1] == curDrag["id_"]) { + rm_conn(key.split("-")[0], key.split("-")[1]); } - for (i = connections.length; i--;) { - r.connection(connections[i]); + } + var i=source.length; + for (; i field + var input = text.inlineTextEditing.startEditing(); + + input.addEventListener("blur", function(e){ + // Stop inline editing after blur on the text field + text.inlineTextEditing.stopEditing(); + this.toFront(); + }, true); +});*/ + +/* + * objs + * + */ +var make_obj = function(x, text, type) +{ + var y; + if (type == "source") { + y = ysource; + } else if (type == "target") { + y = ytarget; + } + // make text obj + texts.push(r.text(x, y+(box_height/2), text).attr(text_att)); + // make shape obj + var x_shape = texts[texts.length-1].getBBox().x-padding, + x_width = texts[texts.length-1].getBBox().width+(2*padding); + shapes.push(r.rect(x_shape, y, x_width, box_height).attr(shape_att)); + tx = texts[texts.length-1]; + sh = shapes[shapes.length-1]; + // fix z-index + tx.toBack(); + sh.toFront(); + // pair text/shape + tx.pair = shapes[shapes.length-1]; + sh.pair = texts[texts.length-1]; + // meta + sh["type_"] = type; + sh["id_"] = id; + shapes_by_id[id] = sh; + if (type == "target") { + sh.drag(move, dragger, up).onDragOver( function(obj) { collide(obj); }) + sh.attr({ cursor: "move" }); + tx.drag(move, dragger, up); + sh["grid_"] = id; + sh.click(function() { + if (connect_mode) { + if (connections[conn_str(connect_mode_shape,this)]) { + rm_conn(connect_mode_shape["id_"], this["id_"]); } else { - x_text = margin+texts[texts.length-1].getBBox().x2; - x_shape = shapes[shapes.length-1].getBBox().x2+padding; - } - texts.push(r.text(x_text, y+yd, a[i]).attr({'text-anchor': 'start', 'font-size': 14, 'font-family': 'Times New Roman'})); - shapes.push(r.rect(x_shape, y, texts[texts.length-1].getBBox().width+(2*padding), box_height)); - texts[texts.length-1].toBack(); - shapes[shapes.length-1].toFront(); - if (type_) { - texts[texts.length-1]["type_"] = type_; - shapes[shapes.length-1]["type_"] = type_; + make_conn(connect_mode_shape, this); } + connect_mode_shape.attr({"fill-opacity": 0}); + connect_mode = false; + connect_mode_shape = null; } - }; - // source - make_objs(source, ybegin, box_height/2); - make_objs(target, line_margin+ybegin, box_height/2, "target"); - // text editing - /*text = texts[4]; - r.inlineTextEditing(text); - shape = shapes[4]; - shape.dblclick(function(){ - text.toFront(); - // Retrieve created field - var input = text.inlineTextEditing.startEditing(); - - input.addEventListener("blur", function(e){ - // Stop inline editing after blur on the text field - text.inlineTextEditing.stopEditing(); - this.toFront(); - }, true); - });*/ - // make draggable - var k = 0; + }); + target_shapes.push(sh); + } else if (type == "source") { + sh.click(function() { + if (connect_mode) { + if (this != connect_mode_shape) + return; + this.attr({"fill-opacity": 0}); + connect_mode = false; + connect_mode_shape = null; + } else { + this.attr({"fill-opacity": .5}); + connect_mode = true; + connect_mode_shape = this; + } + }); + } + id++; +}, +add_obj = function() +{ + var max=0, max_idx=-1; for (var i=0; i < shapes.length; i++) { - shapes[i].attr({ fill: "#eee", stroke: "#000", "fill-opacity": 0, "stroke-width": 1 }); - texts[i].attr({fill: "#000", stroke: "none"}); - if (shapes[i]["type_"] == "target") { - shapes[i].drag(move, dragger, up).onDragOver( function(obj) { collide(obj); }) - shapes[i].attr({ cursor: "move" }); - texts[i].drag(move, dragger, up); - shapes[i]["id_"] = k; - shapes[i]["grid_"] = k; - shapes_by_id[k] = shapes[i]; - k++; + if (shapes[i]["grid_"] > max) { + max_idx = i; + max = shapes[i]["grid_"]; } - shapes[i].pair = texts[i]; - texts[i].pair = shapes[i]; } - // connections - var offset = source.length-1; - for (var i=0; i < align.length; i++) { - connections.push(r.connection(shapes[i], shapes[offset+align[i]+1], "#000")); + if (!shapes[max_idx]) { + make_obj(xbegin+padding, "NEW", "target", 0); + } else { + make_obj(shapes[max_idx].getBBox().x2+(margin-padding), + "NEW", + "target", + max+1); + } + r.setSize(r.width+target_shapes[target_shapes.length-1].getBBox().width+margin, r.height); + + snap_to_grid(true); +}, +make_objs = function (a, type) +{ + for (var i=0; i < a.length; i++) { + var x = 0; + if (i == 0) { + x = xbegin+padding; + } else { + x = margin+texts[texts.length-1].getBBox().x2; + } + make_obj(x, a[i], type); + } +}; + + +/////////////////////////////////////////////////////////////////////////////// + +window.onload = function () +{ + // canvas + r = Raphael("holder",0,0); + var c = 0, + d = 0, + a = null; + for (var i=0; i