diff --git a/editor/history.js b/editor/history.js deleted file mode 100644 index e69de29b..00000000 diff --git a/editor/svg-editor.html b/editor/svg-editor.html index fb16ba90..25a39ad4 100644 --- a/editor/svg-editor.html +++ b/editor/svg-editor.html @@ -19,6 +19,7 @@ + @@ -33,6 +34,7 @@ + diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js index a6fdc461..c7157695 100644 --- a/editor/svgcanvas.js +++ b/editor/svgcanvas.js @@ -9,6 +9,12 @@ * */ +// Dependencies: +// 1) jQuery +// 2) browsersupport.js +// 3) svgtransformlist.js +// 4) svgutils.js + if(!window.console) { window.console = {}; window.console.log = function(str) {}; @@ -1433,192 +1439,9 @@ var SelectorManager; }; }()); - -// ************************************************************************************** -// SVGTransformList implementation for Webkit -// These methods do not currently raise any exceptions. -// These methods also do not check that transforms are being inserted or handle if -// a transform is already in the list, etc. This is basically implementing as much -// of SVGTransformList that we need to get the job done. -// -// interface SVGEditTransformList { -// attribute unsigned long numberOfItems; -// void clear ( ) -// SVGTransform initialize ( in SVGTransform newItem ) -// SVGTransform getItem ( in unsigned long index ) -// SVGTransform insertItemBefore ( in SVGTransform newItem, in unsigned long index ) -// SVGTransform replaceItem ( in SVGTransform newItem, in unsigned long index ) -// SVGTransform removeItem ( in unsigned long index ) -// SVGTransform appendItem ( in SVGTransform newItem ) -// NOT IMPLEMENTED: SVGTransform createSVGTransformFromMatrix ( in SVGMatrix matrix ); -// NOT IMPLEMENTED: SVGTransform consolidate ( ); -// } -// ************************************************************************************** +// "Import" from svgtransformlist.js +var SVGEditTransformList = svgedit.SVGTransformList; var svgTransformLists = {}; -var SVGEditTransformList = function(elem) { - - function transformToString(xform) { - var m = xform.matrix, - text = ""; - switch(xform.type) { - case 1: // MATRIX - text = "matrix(" + [m.a,m.b,m.c,m.d,m.e,m.f].join(",") + ")"; - break; - case 2: // TRANSLATE - text = "translate(" + m.e + "," + m.f + ")"; - break; - case 3: // SCALE - if (m.a == m.d) text = "scale(" + m.a + ")"; - else text = "scale(" + m.a + "," + m.d + ")"; - break; - case 4: // ROTATE - var cx = 0, cy = 0; - // this prevents divide by zero - if (xform.angle != 0) { - var K = 1 - m.a; - cy = ( K * m.f + m.b*m.e ) / ( K*K + m.b*m.b ); - cx = ( m.e - m.b * cy ) / K; - } - text = "rotate(" + xform.angle + " " + cx + "," + cy + ")"; - break; - } - return text; - }; - - this._elem = elem || null; - this._xforms = []; - // TODO: how do we capture the undo-ability in the changed transform list? - this._update = function() { - var tstr = ""; - var concatMatrix = svgroot.createSVGMatrix(); - for (var i = 0; i < this.numberOfItems; ++i) { - var xform = this._list.getItem(i); - tstr += transformToString(xform) + " "; - } - this._elem.setAttribute("transform", tstr); - }; - this._list = this; - this._init = function() { - // Transform attribute parser - var str = this._elem.getAttribute("transform"); - if(!str) return; - - // TODO: Add skew support in future - var re = /\s*((scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/; - var arr = []; - var m = true; - while(m) { - m = str.match(re); - str = str.replace(re,''); - if(m && m[1]) { - var x = m[1]; - var bits = x.split(/\s*\(/); - var name = bits[0]; - var val_bits = bits[1].match(/\s*(.*?)\s*\)/); - val_bits[1] = val_bits[1].replace(/(\d)-/g, "$1 -"); - var val_arr = val_bits[1].split(/[, ]+/); - var letters = 'abcdef'.split(''); - var mtx = svgroot.createSVGMatrix(); - $.each(val_arr, function(i, item) { - val_arr[i] = parseFloat(item); - if(name == 'matrix') { - mtx[letters[i]] = val_arr[i]; - } - }); - var xform = svgroot.createSVGTransform(); - var fname = 'set' + name.charAt(0).toUpperCase() + name.slice(1); - var values = name=='matrix'?[mtx]:val_arr; - - if(name == 'scale' && values.length == 1) { - values.push(values[0]); - } else if(name == 'translate' && values.length == 1) { - values.push(0); - } - xform[fname].apply(xform, values); - this._list.appendItem(xform); - } - } - } - - this.numberOfItems = 0; - this.clear = function() { - this.numberOfItems = 0; - this._xforms = []; - }; - - this.initialize = function(newItem) { - this.numberOfItems = 1; - this._xforms = [newItem]; - }; - - this.getItem = function(index) { - if (index < this.numberOfItems && index >= 0) { - return this._xforms[index]; - } - return null; - }; - - this.insertItemBefore = function(newItem, index) { - var retValue = null; - if (index >= 0) { - if (index < this.numberOfItems) { - var newxforms = new Array(this.numberOfItems + 1); - // TODO: use array copying and slicing - for ( var i = 0; i < index; ++i) { - newxforms[i] = this._xforms[i]; - } - newxforms[i] = newItem; - for ( var j = i+1; i < this.numberOfItems; ++j, ++i) { - newxforms[j] = this._xforms[i]; - } - this.numberOfItems++; - this._xforms = newxforms; - retValue = newItem; - this._list._update(); - } - else { - retValue = this._list.appendItem(newItem); - } - } - return retValue; - }; - - this.replaceItem = function(newItem, index) { - var retValue = null; - if (index < this.numberOfItems && index >= 0) { - this._xforms[index] = newItem; - retValue = newItem; - this._list._update(); - } - return retValue; - }; - - this.removeItem = function(index) { - var retValue = null; - if (index < this.numberOfItems && index >= 0) { - var retValue = this._xforms[index]; - var newxforms = new Array(this.numberOfItems - 1); - for (var i = 0; i < index; ++i) { - newxforms[i] = this._xforms[i]; - } - for (var j = i; j < this.numberOfItems-1; ++j, ++i) { - newxforms[j] = this._xforms[i+1]; - } - this.numberOfItems--; - this._xforms = newxforms; - this._list._update(); - } - return retValue; - }; - - this.appendItem = function(newItem) { - this._xforms.push(newItem); - this.numberOfItems++; - this._list._update(); - return newItem; - }; -}; -// ************************************************************************************** // Group: Helper functions diff --git a/editor/svgtransformlist.js b/editor/svgtransformlist.js new file mode 100644 index 00000000..1930fbbf --- /dev/null +++ b/editor/svgtransformlist.js @@ -0,0 +1,200 @@ +/** + * SVGTransformList + * + * Licensed under the Apache License, Version 2 + * + * Copyright(c) 2010 Alexis Deveria + * Copyright(c) 2010 Jeff Schiller + */ + +(function() { + +if (!window.svgedit) { + window.svgedit = {}; +} + +// Helper function. +function transformToString(xform) { + var m = xform.matrix, + text = ""; + switch(xform.type) { + case 1: // MATRIX + text = "matrix(" + [m.a,m.b,m.c,m.d,m.e,m.f].join(",") + ")"; + break; + case 2: // TRANSLATE + text = "translate(" + m.e + "," + m.f + ")"; + break; + case 3: // SCALE + if (m.a == m.d) text = "scale(" + m.a + ")"; + else text = "scale(" + m.a + "," + m.d + ")"; + break; + case 4: // ROTATE + var cx = 0, cy = 0; + // this prevents divide by zero + if (xform.angle != 0) { + var K = 1 - m.a; + cy = ( K * m.f + m.b*m.e ) / ( K*K + m.b*m.b ); + cx = ( m.e - m.b * cy ) / K; + } + text = "rotate(" + xform.angle + " " + cx + "," + cy + ")"; + break; + } + return text; +}; + +// ************************************************************************************** +// SVGTransformList implementation for Webkit +// These methods do not currently raise any exceptions. +// These methods also do not check that transforms are being inserted or handle if +// a transform is already in the list, etc. This is basically implementing as much +// of SVGTransformList that we need to get the job done. +// +// interface SVGEditTransformList { +// attribute unsigned long numberOfItems; +// void clear ( ) +// SVGTransform initialize ( in SVGTransform newItem ) +// SVGTransform getItem ( in unsigned long index ) +// SVGTransform insertItemBefore ( in SVGTransform newItem, in unsigned long index ) +// SVGTransform replaceItem ( in SVGTransform newItem, in unsigned long index ) +// SVGTransform removeItem ( in unsigned long index ) +// SVGTransform appendItem ( in SVGTransform newItem ) +// NOT IMPLEMENTED: SVGTransform createSVGTransformFromMatrix ( in SVGMatrix matrix ); +// NOT IMPLEMENTED: SVGTransform consolidate ( ); +// } +// ************************************************************************************** +svgedit.SVGTransformList = function(elem) { + this._elem = elem || null; + this._xforms = []; + // TODO: how do we capture the undo-ability in the changed transform list? + this._update = function() { + var tstr = ""; + var concatMatrix = svgroot.createSVGMatrix(); + for (var i = 0; i < this.numberOfItems; ++i) { + var xform = this._list.getItem(i); + tstr += transformToString(xform) + " "; + } + this._elem.setAttribute("transform", tstr); + }; + this._list = this; + this._init = function() { + // Transform attribute parser + var str = this._elem.getAttribute("transform"); + if(!str) return; + + // TODO: Add skew support in future + var re = /\s*((scale|matrix|rotate|translate)\s*\(.*?\))\s*,?\s*/; + var arr = []; + var m = true; + while(m) { + m = str.match(re); + str = str.replace(re,''); + if(m && m[1]) { + var x = m[1]; + var bits = x.split(/\s*\(/); + var name = bits[0]; + var val_bits = bits[1].match(/\s*(.*?)\s*\)/); + val_bits[1] = val_bits[1].replace(/(\d)-/g, "$1 -"); + var val_arr = val_bits[1].split(/[, ]+/); + var letters = 'abcdef'.split(''); + var mtx = svgroot.createSVGMatrix(); + $.each(val_arr, function(i, item) { + val_arr[i] = parseFloat(item); + if(name == 'matrix') { + mtx[letters[i]] = val_arr[i]; + } + }); + var xform = svgroot.createSVGTransform(); + var fname = 'set' + name.charAt(0).toUpperCase() + name.slice(1); + var values = name=='matrix'?[mtx]:val_arr; + + if(name == 'scale' && values.length == 1) { + values.push(values[0]); + } else if(name == 'translate' && values.length == 1) { + values.push(0); + } + xform[fname].apply(xform, values); + this._list.appendItem(xform); + } + } + } + + this.numberOfItems = 0; + this.clear = function() { + this.numberOfItems = 0; + this._xforms = []; + }; + + this.initialize = function(newItem) { + this.numberOfItems = 1; + this._xforms = [newItem]; + }; + + this.getItem = function(index) { + if (index < this.numberOfItems && index >= 0) { + return this._xforms[index]; + } + return null; + }; + + this.insertItemBefore = function(newItem, index) { + var retValue = null; + if (index >= 0) { + if (index < this.numberOfItems) { + var newxforms = new Array(this.numberOfItems + 1); + // TODO: use array copying and slicing + for ( var i = 0; i < index; ++i) { + newxforms[i] = this._xforms[i]; + } + newxforms[i] = newItem; + for ( var j = i+1; i < this.numberOfItems; ++j, ++i) { + newxforms[j] = this._xforms[i]; + } + this.numberOfItems++; + this._xforms = newxforms; + retValue = newItem; + this._list._update(); + } + else { + retValue = this._list.appendItem(newItem); + } + } + return retValue; + }; + + this.replaceItem = function(newItem, index) { + var retValue = null; + if (index < this.numberOfItems && index >= 0) { + this._xforms[index] = newItem; + retValue = newItem; + this._list._update(); + } + return retValue; + }; + + this.removeItem = function(index) { + var retValue = null; + if (index < this.numberOfItems && index >= 0) { + var retValue = this._xforms[index]; + var newxforms = new Array(this.numberOfItems - 1); + for (var i = 0; i < index; ++i) { + newxforms[i] = this._xforms[i]; + } + for (var j = i; j < this.numberOfItems-1; ++j, ++i) { + newxforms[j] = this._xforms[i+1]; + } + this.numberOfItems--; + this._xforms = newxforms; + this._list._update(); + } + return retValue; + }; + + this.appendItem = function(newItem) { + this._xforms.push(newItem); + this.numberOfItems++; + this._list._update(); + return newItem; + }; +}; + +})(); \ No newline at end of file diff --git a/editor/svgutils.js b/editor/svgutils.js index 1d4fe534..4d58aac2 100644 --- a/editor/svgutils.js +++ b/editor/svgutils.js @@ -16,8 +16,9 @@ if (!window.svgedit) { window.svgedit = {}; } -svgedit.Utilities = { -}; +if (!svgedit.Utilities) { + svgedit.Utilities = {}; +} // String used to encode base64. svgedit.Utilities._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";