diff --git a/editor/path.js b/editor/path.js new file mode 100644 index 00000000..fd8c5f28 --- /dev/null +++ b/editor/path.js @@ -0,0 +1,488 @@ +/** + * Package: svgedit.path + * + * Licensed under the Apache License, Version 2 + * + * Copyright(c) 2011 Alexis Deveria + * Copyright(c) 2011 Jeff Schiller + */ + +// Dependencies: +// 1) jQuery +// 2) browser.js +// 3) math.js +// 4) svgutils.js + +var svgedit = svgedit || {}; + +(function() { + +if (!svgedit.path) { + svgedit.path = {}; +} + +var svgns = "http://www.w3.org/2000/svg"; + +var uiStrings = { + "pathNodeTooltip": "Drag node to move it. Double-click node to change segment type", + "pathCtrlPtTooltip": "Drag control point to adjust curve properties" +}; + +var segData = { + 2: ['x','y'], + 4: ['x','y'], + 6: ['x','y','x1','y1','x2','y2'], + 8: ['x','y','x1','y1'], + 10: ['x','y','r1','r2','angle','largeArcFlag','sweepFlag'], + 12: ['x'], + 14: ['y'], + 16: ['x','y','x2','y2'], + 18: ['x','y'] +}; + +var pathFuncs = []; + +svgedit.path.path = null; + +var editorContext_ = null; + +svgedit.path.init = function(editorContext) { + editorContext_ = editorContext; + + pathFuncs = [0,'ClosePath']; + var pathFuncsStrs = ['Moveto', 'Lineto', 'CurvetoCubic', 'CurvetoQuadratic', 'Arc', + 'LinetoHorizontal', 'LinetoVertical','CurvetoCubicSmooth','CurvetoQuadraticSmooth']; + $.each(pathFuncsStrs, function(i,s) { + pathFuncs.push(s+'Abs'); + pathFuncs.push(s+'Rel'); + }); +}; + +svgedit.path.insertItemBefore = function(elem, newseg, index) { + // Support insertItemBefore on paths for FF2 + var list = elem.pathSegList; + + if(svgedit.browser.supportsPathInsertItemBefore()) { + list.insertItemBefore(newseg, index); + return; + } + var len = list.numberOfItems; + var arr = []; + for(var i=0; i + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index 7714636f..5073c672 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -20,6 +20,7 @@ // 8) history.js // 9) select.js // 10) draw.js +// 11) path.js if(!window.console) { window.console = {}; @@ -235,64 +236,6 @@ var cur_shape = all_properties.shape; // default size of 1 until it needs to grow bigger var selectedElements = new Array(1); - -// Function: getElem -// Get a DOM element by ID within the SVG root element. -// -// Parameters: -// id - String with the element's new ID -var getElem = null; -if (svgedit.browser.supportsSelectors()) { - getElem = function(id) { - // querySelector lookup - return svgroot.querySelector('#'+id); - }; -} else if (svgedit.browser.supportsXpath()) { - getElem = function(id) { - // xpath lookup - return svgdoc.evaluate('svg:svg[@id="svgroot"]//svg:*[@id="'+id+'"]', - container, function() { return "http://www.w3.org/2000/svg"; }, - 9, null).singleNodeValue; - }; -} else { - getElem = function(id) { - // jQuery lookup: twice as slow as xpath in FF - return $(svgroot).find('[id=' + id + ']')[0]; - }; -} -canvas.getElem = getElem; - -// Function: assignAttributes -// Assigns multiple attributes to an element. -// -// Parameters: -// node - DOM element to apply new attribute values to -// attrs - Object with attribute keys/values -// suspendLength - Optional integer of milliseconds to suspend redraw -// unitCheck - Boolean to indicate the need to use svgedit.units.setUnitAttr -var assignAttributes = canvas.assignAttributes = function(node, attrs, suspendLength, unitCheck) { - if(!suspendLength) suspendLength = 0; - // Opera has a problem with suspendRedraw() apparently - var handle = null; - if (!svgedit.browser.isOpera()) svgroot.suspendRedraw(suspendLength); - - for (var i in attrs) { - var ns = (i.substr(0,4) === "xml:" ? xmlns : - i.substr(0,6) === "xlink:" ? xlinkns : null); - - if(ns) { - node.setAttributeNS(ns, i, attrs[i]); - } else if(!unitCheck) { - node.setAttribute(i, attrs[i]); - } else { - svgedit.units.setUnitAttr(node, i, attrs[i]); - } - - } - - if (!svgedit.browser.isOpera()) svgroot.unsuspendRedraw(handle); -}; - // Function: cleanupElement // Remove unneeded (default) attributes, makes resulting SVG smaller // @@ -393,6 +336,10 @@ var convertToNum = canvas.convertToNum = svgedit.units.convertToNum; // import from svgutils.js svgedit.utilities.init({ + getDOMDocument: function() { return svgdoc; }, + getDOMContainer: function() { return container; }, + getSVGRoot: function() { return svgroot; }, + // TODO: replace this mostly with a way to get the current drawing. getSelectedElements: function() { return selectedElements; }, getSVGContent: function() { return svgcontent; } }); @@ -402,6 +349,8 @@ var setHref = canvas.setHref = svgedit.utilities.setHref; var getPathBBox = svgedit.utilities.getPathBBox; var getBBox = canvas.getBBox = svgedit.utilities.getBBox; var getRotationAngle = canvas.getRotationAngle = svgedit.utilities.getRotationAngle; +var getElem = canvas.getElem = svgedit.utilities.getElem; +var assignAttributes = canvas.assignAttributes = svgedit.utilities.assignAttributes; // import from sanitize.js var nsMap = svgedit.sanitize.getNSMap(); @@ -476,6 +425,11 @@ svgedit.select.init(curConfig, { // this object manages selectors for us var selectorManager = this.selectorManager = svgedit.select.getSelectorManager(); +// Import from path.js +svgedit.path.init({ + currentZoom: function() { return current_zoom; } +}); + // Function: snapToGrid // round value to for snapping // NOTE: This function did not move to svgutils.js since it depends on curConfig. @@ -492,8 +446,6 @@ var snapToGrid = svgedit.utilities.snapToGrid; // Interface strings, usually for title elements var uiStrings = { - "pathNodeTooltip": "Drag node to move it. Double-click node to change segment type", - "pathCtrlPtTooltip": "Drag control point to adjust curve properties", "exportNoBlur": "Blurred elements will appear as un-blurred", "exportNoforeignObject": "foreignObject elements will not appear", "exportNoDashArray": "Strokes will appear filled", @@ -3317,10 +3269,12 @@ var getMouseTarget = this.getMouseTarget = function(evt) { // Remove non-scaling stroke if(svgedit.browser.supportsNonScalingStroke()) { var elem = selectedElements[0]; - elem.removeAttribute('style'); - svgedit.utilities.walkTree(elem, function(elem) { + if (elem) { elem.removeAttribute('style'); - }); + svgedit.utilities.walkTree(elem, function(elem) { + elem.removeAttribute('style'); + }); + } } } @@ -4014,6 +3968,7 @@ var textActions = canvas.textActions = function() { } }(); +// TODO: Migrate all of this code into path.js // Group: Path edit functions // Functions relating to editing path elements var pathActions = canvas.pathActions = function() { @@ -4021,429 +3976,16 @@ var pathActions = canvas.pathActions = function() { var subpath = false; var pathData = {}; var current_path; - var path; var newPoint, firstCtrl; - var segData = { - 2: ['x','y'], - 4: ['x','y'], - 6: ['x','y','x1','y1','x2','y2'], - 8: ['x','y','x1','y1'], - 10: ['x','y','r1','r2','angle','largeArcFlag','sweepFlag'], - 12: ['x'], - 14: ['y'], - 16: ['x','y','x2','y2'], - 18: ['x','y'] - }; - function retPath() { - return path; - } - function resetD(p) { p.setAttribute("d", pathActions.convertPath(p)); } - - function insertItemBefore(elem, newseg, index) { - // Support insertItemBefore on paths for FF2 - var list = elem.pathSegList; - - if(svgedit.browser.supportsPathInsertItemBefore()) { - list.insertItemBefore(newseg, index); - return; - } - var len = list.numberOfItems; - var arr = []; - for(var i=0; i