git-svn-id: http://svg-edit.googlecode.com/svn/trunk@2652 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Brett Zamir 2014-01-31 10:40:52 +00:00
parent f22e95f437
commit 525e8322a9
1 changed files with 107 additions and 88 deletions

View File

@ -1,5 +1,5 @@
/*globals $*/ /*globals $, svgedit, svgCanvas*/
/*jslint vars: true, eqeq: true */ /*jslint vars: true, eqeq: true, todo: true, bitwise: true, continue: true, forin: true */
/* /*
* svgcanvas.js * svgcanvas.js
* *
@ -26,6 +26,8 @@
// 12) coords.js // 12) coords.js
// 13) recalculate.js // 13) recalculate.js
(function () {'use strict';
if (!window.console) { if (!window.console) {
window.console = {}; window.console = {};
window.console.log = function(str) {}; window.console.log = function(str) {};
@ -37,14 +39,15 @@ if (window.opera) {
window.console.dir = function(str) {}; window.console.dir = function(str) {};
} }
}());
// Class: SvgCanvas // Class: SvgCanvas
// The main SvgCanvas class that manages all SVG-related functions // The main SvgCanvas class that manages all SVG-related functions
// //
// Parameters: // Parameters:
// container - The container HTML element that should hold the SVG root element // container - The container HTML element that should hold the SVG root element
// config - An object that contains configuration data // config - An object that contains configuration data
$.SvgCanvas = function(container, config) $.SvgCanvas = function(container, config) {
{
// Alias Namespace constants // Alias Namespace constants
var NS = svgedit.NS; var NS = svgedit.NS;
@ -423,7 +426,7 @@ var restoreRefElems = function(elem) {
// svgedit.utilities.setHref(svgthumb, '#svgcontent'); // svgedit.utilities.setHref(svgthumb, '#svgcontent');
// svgroot.appendChild(svgthumb); // svgroot.appendChild(svgthumb);
})(); }());
// Object to contain image data for raster images that were found encodable // Object to contain image data for raster images that were found encodable
var encodableImages = {}, var encodableImages = {},
@ -504,17 +507,18 @@ var runExtensions = this.runExtensions = function(action, vars, returnArray) {
// name - String with the ID of the extension // name - String with the ID of the extension
// ext_func - Function supplied by the extension with its data // ext_func - Function supplied by the extension with its data
this.addExtension = function(name, ext_func) { this.addExtension = function(name, ext_func) {
var ext;
if (!(name in extensions)) { if (!(name in extensions)) {
// Provide private vars/funcs here. Is there a better way to do this? // Provide private vars/funcs here. Is there a better way to do this?
if ($.isFunction(ext_func)) { if ($.isFunction(ext_func)) {
var ext = ext_func($.extend(canvas.getPrivateMethods(), { ext = ext_func($.extend(canvas.getPrivateMethods(), {
svgroot: svgroot, svgroot: svgroot,
svgcontent: svgcontent, svgcontent: svgcontent,
nonce: getCurrentDrawing().getNonce(), nonce: getCurrentDrawing().getNonce(),
selectorManager: selectorManager selectorManager: selectorManager
})); }));
} else { } else {
var ext = ext_func; ext = ext_func;
} }
extensions[name] = ext; extensions[name] = ext;
call("extension_added", ext); call("extension_added", ext);
@ -570,7 +574,7 @@ var getIntersectionList = this.getIntersectionList = function(rect) {
} }
var i = curBBoxes.length; var i = curBBoxes.length;
while (i--) { while (i--) {
if (!rubberBBox.width || !rubberBBox.width) {continue;} if (!rubberBBox.width) {continue;}
if (svgedit.math.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) { if (svgedit.math.rectsIntersect(rubberBBox, curBBoxes[i].bbox)) {
resultList.push(curBBoxes[i].elem); resultList.push(curBBoxes[i].elem);
} }
@ -1111,7 +1115,9 @@ var addToSelection = this.addToSelection = function(elemsToAdd, showGrips) {
}); });
// Make sure first elements are not null // Make sure first elements are not null
while (selectedElements[0] == null) selectedElements.shift(0); while (selectedElements[0] == null) {
selectedElements.shift(0);
}
}; };
// Function: selectOnly() // Function: selectOnly()
@ -1137,10 +1143,11 @@ var removeFromSelection = this.removeFromSelection = function(elemsToRemove) {
if (elemsToRemove.length == 0) { return; } if (elemsToRemove.length == 0) { return; }
// find every element and remove it from our array copy // find every element and remove it from our array copy
var newSelectedItems = new Array(selectedElements.length); var i,
j = 0, j = 0,
newSelectedItems = new Array(selectedElements.length),
len = selectedElements.length; len = selectedElements.length;
for (var i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
var elem = selectedElements[i]; var elem = selectedElements[i];
if (elem) { if (elem) {
// keep the item // keep the item
@ -1181,7 +1188,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
var mouse_target = evt.target; var mouse_target = evt.target;
// if it was a <use>, Opera and WebKit return the SVGElementInstance // if it was a <use>, Opera and WebKit return the SVGElementInstance
if (mouse_target.correspondingUseElement) mouse_target = mouse_target.correspondingUseElement; if (mouse_target.correspondingUseElement) {mouse_target = mouse_target.correspondingUseElement;}
// for foreign content, go up until we find the foreignObject // for foreign content, go up until we find the foreignObject
// WebKit browsers set the mouse target to the svgcanvas div // WebKit browsers set the mouse target to the svgcanvas div
@ -1190,7 +1197,7 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
{ {
while (mouse_target.nodeName != "foreignObject") { while (mouse_target.nodeName != "foreignObject") {
mouse_target = mouse_target.parentNode; mouse_target = mouse_target.parentNode;
if (!mouse_target) return svgroot; if (!mouse_target) {return svgroot;}
} }
} }
@ -1264,24 +1271,25 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
t2 = t * t, t2 = t * t,
t3 = t2 * t; t3 = t2 * t;
var m = Array var m = [
( [-1, 3, -3, 1],
Array(-1, 3, -3, 1), [3, -6, 3, 0],
Array(3, -6, 3, 0), [-3, 0, 3, 0],
Array(-3, 0, 3, 0), [1, 4, 1, 0]
Array(1, 4, 1, 0) ];
);
spline.x = S * ( spline.x = S * (
(p0.x * m[0][0] + p1.x * m[0][1] + p2.x * m[0][2] + p3.x * m[0][3] ) * t3 + (p0.x * m[0][0] + p1.x * m[0][1] + p2.x * m[0][2] + p3.x * m[0][3] ) * t3 +
(p0.x * m[1][0] + p1.x * m[1][1] + p2.x * m[1][2] + p3.x * m[1][3] ) * t2 + (p0.x * m[1][0] + p1.x * m[1][1] + p2.x * m[1][2] + p3.x * m[1][3] ) * t2 +
(p0.x * m[2][0] + p1.x * m[2][1] + p2.x * m[2][2] + p3.x * m[2][3] ) * t + (p0.x * m[2][0] + p1.x * m[2][1] + p2.x * m[2][2] + p3.x * m[2][3] ) * t +
(p0.x * m[3][0] + p1.x * m[3][1] + p2.x * m[3][2] + p3.x * m[3][3] ) ); (p0.x * m[3][0] + p1.x * m[3][1] + p2.x * m[3][2] + p3.x * m[3][3] )
);
spline.y = S * ( spline.y = S * (
(p0.y * m[0][0] + p1.y * m[0][1] + p2.y * m[0][2] + p3.y * m[0][3] ) * t3 + (p0.y * m[0][0] + p1.y * m[0][1] + p2.y * m[0][2] + p3.y * m[0][3] ) * t3 +
(p0.y * m[1][0] + p1.y * m[1][1] + p2.y * m[1][2] + p3.y * m[1][3] ) * t2 + (p0.y * m[1][0] + p1.y * m[1][1] + p2.y * m[1][2] + p3.y * m[1][3] ) * t2 +
(p0.y * m[2][0] + p1.y * m[2][1] + p2.y * m[2][2] + p3.y * m[2][3] ) * t + (p0.y * m[2][0] + p1.y * m[2][1] + p2.y * m[2][2] + p3.y * m[2][3] ) * t +
(p0.y * m[3][0] + p1.y * m[3][1] + p2.y * m[3][2] + p3.y * m[3][3] ) ); (p0.y * m[3][0] + p1.y * m[3][1] + p2.y * m[3][2] + p3.y * m[3][3] )
);
return { return {
x:spline.x, x:spline.x,
@ -1292,9 +1300,8 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
// but the action is not recorded until mousing up // but the action is not recorded until mousing up
// - when we are in select mode, select the element, remember the position // - when we are in select mode, select the element, remember the position
// and do nothing else // and do nothing else
var mouseDown = function(evt) var mouseDown = function(evt) {
{ if (canvas.spaceKey || evt.button === 1) {return;}
if (canvas.spaceKey || evt.button === 1) return;
var right_click = evt.button === 2; var right_click = evt.button === 2;
@ -1329,8 +1336,10 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} }
// real_x/y ignores grid-snap value // real_x/y ignores grid-snap value
var real_x = r_start_x = start_x = x; var real_x = x;
var real_y = r_start_y = start_y = y; r_start_x = start_x = x;
var real_y = y;
r_start_y = start_y = y;
if (curConfig.gridSnapping){ if (curConfig.gridSnapping){
x = svgedit.utilities.snapToGrid(x); x = svgedit.utilities.snapToGrid(x);
@ -1358,12 +1367,13 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} }
startTransform = mouse_target.getAttribute("transform"); startTransform = mouse_target.getAttribute("transform");
var tlist = svgedit.transformlist.getTransformList(mouse_target); var i,
tlist = svgedit.transformlist.getTransformList(mouse_target);
switch (current_mode) { switch (current_mode) {
case "select": case "select":
started = true; started = true;
current_resize_mode = "none"; current_resize_mode = "none";
if (right_click) started = false; if (right_click) {started = false;}
if (mouse_target != svgroot) { if (mouse_target != svgroot) {
// if this element is not yet selected, clear selection and select it // if this element is not yet selected, clear selection and select it
@ -1383,8 +1393,8 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
if (!right_click) { if (!right_click) {
// insert a dummy transform so if the element(s) are moved it will have // insert a dummy transform so if the element(s) are moved it will have
// a transform to use for its translate // a transform to use for its translate
for (var i = 0; i < selectedElements.length; ++i) { for (i = 0; i < selectedElements.length; ++i) {
if (selectedElements[i] == null) continue; if (selectedElements[i] == null) {continue;}
var slist = svgedit.transformlist.getTransformList(selectedElements[i]); var slist = svgedit.transformlist.getTransformList(selectedElements[i]);
if (slist.numberOfItems) { if (slist.numberOfItems) {
slist.insertItemBefore(svgroot.createSVGTransform(), 0); slist.insertItemBefore(svgroot.createSVGTransform(), 0);
@ -1471,11 +1481,12 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
}; };
} }
mouse_target.style.vectorEffect = 'non-scaling-stroke'; mouse_target.style.vectorEffect = 'non-scaling-stroke';
if (isWebkit) delayedStroke(mouse_target); if (isWebkit) {delayedStroke(mouse_target);}
var all = mouse_target.getElementsByTagName('*'), var i,
all = mouse_target.getElementsByTagName('*'),
len = all.length; len = all.length;
for (var i = 0; i < len; i++) { for (i = 0; i < len; i++) {
all[i].style.vectorEffect = 'non-scaling-stroke'; all[i].style.vectorEffect = 'non-scaling-stroke';
if (isWebkit) delayedStroke(all[i]); if (isWebkit) delayedStroke(all[i]);
} }
@ -1659,8 +1670,8 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
// any elements that are still being created, moved or resized on the canvas) // any elements that are still being created, moved or resized on the canvas)
var mouseMove = function(evt) var mouseMove = function(evt)
{ {
if (!started) return; if (!started) {return;}
if (evt.button === 1 || canvas.spaceKey) return; if (evt.button === 1 || canvas.spaceKey) {return;}
var selected = selectedElements[0], var selected = selectedElements[0],
pt = svgedit.math.transformPoint( evt.pageX, evt.pageY, root_sctm ), pt = svgedit.math.transformPoint( evt.pageX, evt.pageY, root_sctm ),
@ -1668,8 +1679,10 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
mouse_y = pt.y * current_zoom, mouse_y = pt.y * current_zoom,
shape = svgedit.utilities.getElem(getId()); shape = svgedit.utilities.getElem(getId());
var real_x = x = mouse_x / current_zoom; var real_x = mouse_x / current_zoom;
var real_y = y = mouse_y / current_zoom; x = real_x;
var real_y = mouse_y / current_zoom;
y = real_y;
if (curConfig.gridSnapping){ if (curConfig.gridSnapping){
x = svgedit.utilities.snapToGrid(x); x = svgedit.utilities.snapToGrid(x);
@ -1699,10 +1712,11 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} }
if (dx != 0 || dy != 0) { if (dx != 0 || dy != 0) {
var len = selectedElements.length; var i,
for (var i = 0; i < len; ++i) { len = selectedElements.length;
for (i = 0; i < len; ++i) {
var selected = selectedElements[i]; var selected = selectedElements[i];
if (selected == null) break; if (selected == null) {break;}
// if (i==0) { // if (i==0) {
// var box = svgedit.utilities.getBBox(selected); // var box = svgedit.utilities.getBBox(selected);
// selectedBBoxes[i].x = box.x + dx; // selectedBBoxes[i].x = box.x + dx;
@ -1746,11 +1760,12 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
// - if newList contains selected, do nothing // - if newList contains selected, do nothing
// - if newList doesn't contain selected, remove it from selected // - if newList doesn't contain selected, remove it from selected
// - for any newList that was not in selectedElements, add it to selected // - for any newList that was not in selectedElements, add it to selected
var elemsToRemove = [], elemsToAdd = [], var i,
elemsToRemove = [], elemsToAdd = [],
newList = getIntersectionList(), newList = getIntersectionList(),
len = selectedElements.length; len = selectedElements.length;
for (var i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
var ind = newList.indexOf(selectedElements[i]); var ind = newList.indexOf(selectedElements[i]);
if (ind == -1) { if (ind == -1) {
elemsToRemove.push(selectedElements[i]); elemsToRemove.push(selectedElements[i]);
@ -1760,13 +1775,17 @@ var getMouseTarget = this.getMouseTarget = function(evt) {
} }
len = newList.length; len = newList.length;
for (i = 0; i < len; ++i) { if (newList[i]) elemsToAdd.push(newList[i]); } for (i = 0; i < len; ++i) {
if (newList[i]) {elemsToAdd.push(newList[i]);}
}
if (elemsToRemove.length > 0) if (elemsToRemove.length > 0) {
canvas.removeFromSelection(elemsToRemove); canvas.removeFromSelection(elemsToRemove);
}
if (elemsToAdd.length > 0) if (elemsToAdd.length > 0) {
addToSelection(elemsToAdd); addToSelection(elemsToAdd);
}
break; break;
case "resize": case "resize":
@ -5010,7 +5029,7 @@ var identifyLayers = canvas.identifyLayers = function() {
// Function: createLayer // Function: createLayer
// Creates a new top-level layer in the drawing with the given name, sets the current layer // Creates a new top-level layer in the drawing with the given name, sets the current layer
// to it, and then clears the selection This function then calls the 'changed' handler. // to it, and then clears the selection. This function then calls the 'changed' handler.
// This is an undoable action. // This is an undoable action.
// //
// Parameters: // Parameters:
@ -5026,7 +5045,7 @@ this.createLayer = function(name) {
// Function: cloneLayer // Function: cloneLayer
// Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents // Creates a new top-level layer in the drawing with the given name, copies all the current layer's contents
// to it, and then clears the selection This function then calls the 'changed' handler. // to it, and then clears the selection. This function then calls the 'changed' handler.
// This is an undoable action. // This is an undoable action.
// //
// Parameters: // Parameters:
@ -6679,7 +6698,7 @@ var changeSelectedAttributeNoUndo = function(attr, newValue, elems) {
// TODO: FIXME: This doesn't seem right. Where's the body of this if statement? // TODO: FIXME: This doesn't seem right. Where's the body of this if statement?
if (elem.tagName === "g" && good_g_attrs.indexOf(attr) >= 0); if (elem.tagName === "g" && good_g_attrs.indexOf(attr) >= 0);
var oldval = attr === "#text" ? elem.textContent : elem.getAttribute(attr); var oldval = attr === "#text" ? elem.textContent : elem.getAttribute(attr);
if (oldval == null) oldval = ""; if (oldval == null) {oldval = "";}
if (oldval !== String(newValue)) { if (oldval !== String(newValue)) {
if (attr == "#text") { if (attr == "#text") {
var old_w = svgedit.utilities.getBBox(elem).width; var old_w = svgedit.utilities.getBBox(elem).width;