diff --git a/editor/ext-connector.js b/editor/ext-connector.js new file mode 100644 index 00000000..dff8f08e --- /dev/null +++ b/editor/ext-connector.js @@ -0,0 +1,243 @@ +$(function() { + svgCanvas.addExtension("Connector", function(vars) { + + var svgcontent = vars.content; + var getNextId = vars.getNextId; + var addElem = vars.addSvgElementFromJson; + var selManager = vars.selectorManager; + var started = false, + start_x, + start_y, + cur_line, + start_elem, + end_elem, + connections = [], + conn_class = "se_connect", + connect_str = "-SE_CONNECT-", + selElems; + + // Init code +// (function() { +// +// +// }()); + + + return { + name: "Connector", + svgicons: "images/conn.svg", + buttons: [{ + id: "mode_connect", + type: "mode", + icon: "images/cut.png", + events: { + 'click': function() { + svgCanvas.setMode("connector"); + } + } + }], + mouseDown: function(opts) { + var e = opts.event; + + start_x = opts.start_x, + start_y = opts.start_y; + var mode = svgCanvas.getMode(); + + if(mode == "connector") { + + if(started) return; + + if(e.target.parentNode.parentNode == svgcontent) { + // Connectable element + start_elem = e.target; + + // Get center of source element + var bb = svgCanvas.getStrokedBBox([start_elem]); + var x = bb.x + bb.width/2; + var y = bb.y + bb.height/2; + + started = true; + cur_line = addElem({ + "element": "line", + "attr": { + "x1": x, + "y1": y, + "x2": start_x, + "y2": start_y, + "id": getNextId(), + "stroke": '#000', + "stroke-width": 1, + "fill": "none", + "opacity": .5, + "style": "pointer-events:none" + } + }); + } + return { + started: true + }; + } else if(mode == "select") { + + // Check if selected elements have connections + var elems = opts.selectedElements; + var i = elems.length; + var connectors = $(svgcontent).find("." + conn_class); + if(!connectors.length) return; + + connections = []; + + while(i--) { + var elem = elems[i]; + if(!elem) continue; + if(elem.getAttribute('class') == conn_class) continue; + var elem_id = elem.id; + connectors.each(function() { + var con_id = this.id; + if(con_id.indexOf(elem_id) != -1) { + var is_start = true; + if(con_id.indexOf(connect_str + elem_id) != -1) { + // Found connector (selected is end elem) + is_start = false; + } + + var bb = svgCanvas.getStrokedBBox([elem]); + var x = bb.x + bb.width/2; + var y = bb.y + bb.height/2; + + connections.push({ + elem: elem, + connector: this, + is_start: is_start, + start_x: x, + start_y: y + }); + } + }); + } + } + }, + mouseMove: function(opts) { + var zoom = svgCanvas.getZoom(); + var e = opts.event; + var x = opts.mouse_x/zoom; + var y = opts.mouse_y/zoom; + + var diff_x = x - start_x, + diff_y = y - start_y; + + var mode = svgCanvas.getMode(); + + if(mode == "connector" && started) { + cur_line.setAttributeNS(null, "x2", x); + cur_line.setAttributeNS(null, "y2", y); + } else if(mode == "select") { + var slen = selElems.length; + + while(slen--) { + var elem = selElems[slen]; + // Look for selected connector elements + if(elem && elem.getAttribute('class') == conn_class) { + // Remove the "translate" transform given to move + svgCanvas.getTransformList(elem).clear(); + } + } + + if(connections.length) { + // Update line with element + var i = connections.length; + + while(i--) { + var conn = connections[i]; + var line = conn.connector; + var elem = conn.elem; + var n = conn.is_start ? 1 : 2; + line.setAttributeNS(null, "x"+n, conn.start_x + diff_x); + line.setAttributeNS(null, "y"+n, conn.start_y + diff_y); + } + } + } + }, + mouseUp: function(opts) { + var zoom = svgCanvas.getZoom(); + var e = opts.event, + x = opts.mouse_x/zoom, + y = opts.mouse_y/zoom; + + if(svgCanvas.getMode() == "connector") { + if(e.target.parentNode.parentNode != svgcontent) { + // Not a valid target element, so remove line + $(cur_line).remove(); + started = false; + return { + keep: false, + element: null, + started: started + } + } else if(e.target == start_elem) { + // Start line through click + started = true; + return { + keep: true, + element: null, + started: started + } + } else { + // Valid end element + end_elem = e.target; + var line_id = start_elem.id + connect_str + end_elem.id; + var alt_line_id = end_elem.id + connect_str + start_elem.id; + + // Don't create connector if one already exists + if($('#'+line_id + ', #' + alt_line_id).length) { + $(cur_line).remove(); + return { + keep: false, + element: null, + started: false + } + } + + var bb = svgCanvas.getStrokedBBox([end_elem]); + var x = bb.x + bb.width/2; + var y = bb.y + bb.height/2; + cur_line.setAttributeNS(null, "x2", x); + cur_line.setAttributeNS(null, "y2", y); + cur_line.id = line_id; + console.log('cur_line',cur_line.id); + cur_line.setAttribute("class", conn_class); + svgCanvas.addToSelection([cur_line]); + svgCanvas.moveToBottomSelectedElement(); + + started = false; + return { + keep: true, + element: cur_line, + started: started + } + } + } + }, + selectedChanged: function(opts) { + + // Use this to update the current selected elements + selElems = opts.elems; + + var i = selElems.length; + +// var to_hide = $('#tool_clone, #tool_topath, div.toolset:has(#angle), #line_panel'); + + while(i--) { + var elem = selElems[i]; + if(elem && elem.getAttribute('class') == conn_class) { + selManager.requestSelector(elem).showGrips(false); + + if(opts.selectedElement && !opts.multiselected) { + // TODO: Set up context tools and hide most regular line tools + + } + } + } + } + }; + }); +}); \ No newline at end of file diff --git a/editor/images/conn.svg b/editor/images/conn.svg new file mode 100644 index 00000000..8d0f3af7 --- /dev/null +++ b/editor/images/conn.svg @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/editor/svg-editor.html b/editor/svg-editor.html index 6bb2570b..32c5cadc 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -18,6 +18,7 @@ +