Largely fixed issue 185: Allow elements and selections to be visible outside the image canvas

git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1225 eee81c28-f429-11dd-99c0-75d572ba1ddd
master
Alexis Deveria 2010-01-15 15:04:57 +00:00
parent 03a335646f
commit 8c3488ab31
2 changed files with 126 additions and 58 deletions

View File

@ -42,6 +42,7 @@ function svg_edit_setup() {
var default_img_url = "images/logo.png"; var default_img_url = "images/logo.png";
var workarea = $("#workarea"); var workarea = $("#workarea");
// Store and retrieve preferences // Store and retrieve preferences
$.pref = function(key, val) { $.pref = function(key, val) {
if(val) curPrefs[key] = val; if(val) curPrefs[key] = val;
@ -207,9 +208,10 @@ function svg_edit_setup() {
// if the element changed was the svg, then it could be a resolution change // if the element changed was the svg, then it could be a resolution change
if (elem && elem.tagName == "svg" && elem.getAttribute("viewBox")) { if (elem && elem.tagName == "svg" && elem.getAttribute("viewBox")) {
var vb = elem.getAttribute("viewBox").split(' ');
changeResolution(parseInt(vb[2]), // var vb = elem.getAttribute("viewBox").split(' ');
parseInt(vb[3])); // changeResolution(parseInt(vb[2]),
// parseInt(vb[3]));
populateLayers(); populateLayers();
} }
// Update selectedElement if element is no longer part of the image. // Update selectedElement if element is no longer part of the image.
@ -248,7 +250,7 @@ function svg_edit_setup() {
var zoomlevel = z_info.zoom; var zoomlevel = z_info.zoom;
var bb = z_info.bbox; var bb = z_info.bbox;
$('#zoom').val(Math.round(zoomlevel*100)); $('#zoom').val(Math.round(zoomlevel*100));
setResolution(res.w * zoomlevel, res.h * zoomlevel); // setResolution(res.w * zoomlevel, res.h * zoomlevel);
var scrLeft = bb.x * zoomlevel; var scrLeft = bb.x * zoomlevel;
var scrOffX = w_area.width()/2 - (bb.width * zoomlevel)/2; var scrOffX = w_area.width()/2 - (bb.width * zoomlevel)/2;
w_area[0].scrollLeft = Math.max(0,scrLeft - scrOffX) + Math.max(0,canvas_pos.left); w_area[0].scrollLeft = Math.max(0,scrLeft - scrOffX) + Math.max(0,canvas_pos.left);
@ -1049,7 +1051,8 @@ function svg_edit_setup() {
$.confirm(uiStrings.QwantToClear, function(ok) { $.confirm(uiStrings.QwantToClear, function(ok) {
if(!ok) return; if(!ok) return;
svgCanvas.clear(); svgCanvas.clear();
svgCanvas.setResolution(640, 480); // svgCanvas.setResolution(640, 480);
updateCanvas();
zoomImage(); zoomImage();
populateLayers(); populateLayers();
updateContextPanel(); updateContextPanel();
@ -1119,7 +1122,8 @@ function svg_edit_setup() {
var zoomImage = function(multiplier) { var zoomImage = function(multiplier) {
var res = svgCanvas.getResolution(); var res = svgCanvas.getResolution();
multiplier = multiplier?res.zoom * multiplier:1; multiplier = multiplier?res.zoom * multiplier:1;
setResolution(res.w * multiplier, res.h * multiplier, true); // setResolution(res.w * multiplier, res.h * multiplier, true);
updateCanvas();
$('#zoom').val(multiplier * 100); $('#zoom').val(multiplier * 100);
svgCanvas.setZoom(multiplier); svgCanvas.setZoom(multiplier);
zoomDone(); zoomDone();
@ -1128,6 +1132,7 @@ function svg_edit_setup() {
var zoomDone = function() { var zoomDone = function() {
updateBgImage(); updateBgImage();
updateWireFrame(); updateWireFrame();
updateCanvas();
} }
var clickWireframe = function() { var clickWireframe = function() {
@ -1267,6 +1272,7 @@ function svg_edit_setup() {
// set icon size // set icon size
setIconSize($('#iconsize').val()); setIconSize($('#iconsize').val());
updateCanvas();
hideDocProperties(); hideDocProperties();
}; };
@ -2009,10 +2015,10 @@ function svg_edit_setup() {
}; };
populateLayers(); populateLayers();
function changeResolution(x,y) { // function changeResolution(x,y) {
var zoom = svgCanvas.getResolution().zoom; // var zoom = svgCanvas.getResolution().zoom;
setResolution(x * zoom, y * zoom); // setResolution(x * zoom, y * zoom);
} // }
var centerCanvas = function() { var centerCanvas = function() {
// this centers the canvas vertically in the workarea (horizontal handled in CSS) // this centers the canvas vertically in the workarea (horizontal handled in CSS)
@ -2061,20 +2067,21 @@ function svg_edit_setup() {
} }
} }
function setResolution(w, h, center) { // function setResolution(w, h, center) {
w-=0; h-=0; // updateCanvas();
$('#svgcanvas').css( { 'width': w, 'height': h } ); // // w-=0; h-=0;
$('#canvas_width').val(w); // // $('#svgcanvas').css( { 'width': w, 'height': h } );
$('#canvas_height').val(h); // // $('#canvas_width').val(w);
// // $('#canvas_height').val(h);
if(center) { // //
var w_area = workarea; // // if(center) {
var scroll_y = h/2 - w_area.height()/2; // // var w_area = workarea;
var scroll_x = w/2 - w_area.width()/2; // // var scroll_y = h/2 - w_area.height()/2;
w_area[0].scrollTop = scroll_y; // // var scroll_x = w/2 - w_area.width()/2;
w_area[0].scrollLeft = scroll_x; // // w_area[0].scrollTop = scroll_y;
} // // w_area[0].scrollLeft = scroll_x;
} // // }
// }
$('#resolution').change(function(){ $('#resolution').change(function(){
var wh = $('#canvas_width,#canvas_height'); var wh = $('#canvas_width,#canvas_height');
@ -2316,8 +2323,28 @@ function svg_edit_setup() {
$("#tool_open").show().prepend(inp); $("#tool_open").show().prepend(inp);
} }
var updateCanvas = function() {
var w = workarea.width(), h = workarea.height();
var w_orig = w, h_orig = h;
var zoom = svgCanvas.getZoom();
var multi = (5*(zoom>1?zoom:1));
// Make the canvas bigger than the viewport
w *= multi;
h *= multi;
$("#svgcanvas").width(w).height(h);
svgCanvas.updateCanvas(w, h);
var w_area = workarea;
var scroll_y = h/2 - h_orig/2;
var scroll_x = w/2 - w_orig/2;
w_area[0].scrollTop = scroll_y;
w_area[0].scrollLeft = scroll_x;
}
// set starting resolution (centers canvas) // set starting resolution (centers canvas)
setResolution(640,480); // setResolution(640,480);
$(updateCanvas);
// var revnums = "svg-editor.js ($Rev$) "; // var revnums = "svg-editor.js ($Rev$) ";
// revnums += svgCanvas.getVersion(); // revnums += svgCanvas.getVersion();

View File

@ -561,6 +561,22 @@ function BatchCommand(text) {
mgr.selectorMap = {}; mgr.selectorMap = {};
mgr.selectors = []; mgr.selectors = [];
mgr.rubberBandBox = null; mgr.rubberBandBox = null;
if($("#borderRect").length) return;
var rect = svgdoc.createElementNS(svgns, "rect");
assignAttributes(rect, {
'id':'borderRect',
'width':'640',
'height':'480',
'x':'0',
'y':'0',
'stroke-width':'1',
'stroke':'#000',
'fill':'none',
'style':'pointer-events:none'
});
mgr.selectorParentGroup.appendChild(rect);
}; };
this.requestSelector = function(elem) { this.requestSelector = function(elem) {
@ -860,13 +876,18 @@ function BatchCommand(text) {
container.appendChild(svgroot); container.appendChild(svgroot);
var svgcontent = svgdoc.createElementNS(svgns, "svg"); var svgcontent = svgdoc.createElementNS(svgns, "svg");
svgcontent.setAttribute('id', 'svgcontent'); svgcontent.setAttribute('id', 'svgcontent');
svgcontent.setAttribute('viewBox', '0 0 640 480'); // svgcontent.setAttribute('viewBox', '0 0 640 480');
svgcontent.setAttribute('width', '640');
svgcontent.setAttribute('height', '480');
svgcontent.setAttribute('x', '640');
svgcontent.setAttribute('y', '480');
svgcontent.setAttribute('overflow', 'visible');
svgcontent.setAttribute("xmlns", svgns); svgcontent.setAttribute("xmlns", svgns);
svgcontent.setAttribute("xmlns:xlink", xlinkns); svgcontent.setAttribute("xmlns:xlink", xlinkns);
svgroot.appendChild(svgcontent); svgroot.appendChild(svgcontent);
(function() { (function() {
// TODO: make this string optional and set by the client // TODO: make this string optional and set by the client
var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ "); var comment = svgdoc.createComment(" Created with SVG-edit - http://svg-edit.googlecode.com/ ");
@ -1121,7 +1142,6 @@ function BatchCommand(text) {
} }
var svgCanvasToString = function() { var svgCanvasToString = function() {
// TODO: Find out why Webkit throws an error somewhere here (breaking the editor)
removeUnusedGrads(); removeUnusedGrads();
pathActions.clear(true); pathActions.clear(true);
$.each(svgcontent.childNodes, function(i, node) { $.each(svgcontent.childNodes, function(i, node) {
@ -1141,6 +1161,7 @@ function BatchCommand(text) {
var attr; var attr;
var i; var i;
var childs = elem.childNodes; var childs = elem.childNodes;
for (var i=0; i<indent; i++) out.push(" "); for (var i=0; i<indent; i++) out.push(" ");
out.push("<"); out.push(elem.nodeName); out.push("<"); out.push(elem.nodeName);
if(elem.id == 'svgcontent') { if(elem.id == 'svgcontent') {
@ -1196,7 +1217,6 @@ function BatchCommand(text) {
for (var i=0; i<childs.length; i++) for (var i=0; i<childs.length; i++)
{ {
var child = childs.item(i); var child = childs.item(i);
if (child.id == "selectorParentGroup") continue;
switch(child.nodeType) { switch(child.nodeType) {
case 1: // element node case 1: // element node
out.push("\n"); out.push("\n");
@ -2289,10 +2309,10 @@ function BatchCommand(text) {
// and do nothing else // and do nothing else
var mouseDown = function(evt) var mouseDown = function(evt)
{ {
root_sctm = svgroot.getScreenCTM().inverse(); root_sctm = svgcontent.getScreenCTM().inverse();
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm ); var pt = transformPoint( evt.pageX, evt.pageY, root_sctm );
var mouse_x = pt.x; var mouse_x = pt.x * current_zoom;
var mouse_y = pt.y; var mouse_y = pt.y * current_zoom;
evt.preventDefault(); evt.preventDefault();
if($.inArray(current_mode, ['select', 'resize']) == -1) { if($.inArray(current_mode, ['select', 'resize']) == -1) {
@ -2608,8 +2628,8 @@ function BatchCommand(text) {
if (!started) return; if (!started) return;
var selected = selectedElements[0]; var selected = selectedElements[0];
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm ); var pt = transformPoint( evt.pageX, evt.pageY, root_sctm );
var mouse_x = pt.x; var mouse_x = pt.x * current_zoom;
var mouse_y = pt.y; var mouse_y = pt.y * current_zoom;
var shape = getElem(getId()); var shape = getElem(getId());
x = mouse_x / current_zoom; x = mouse_x / current_zoom;
@ -2892,8 +2912,8 @@ function BatchCommand(text) {
if (!started) return; if (!started) return;
var pt = transformPoint( evt.pageX, evt.pageY, root_sctm ); var pt = transformPoint( evt.pageX, evt.pageY, root_sctm );
var mouse_x = pt.x; var mouse_x = pt.x * current_zoom;
var mouse_y = pt.y; var mouse_y = pt.y * current_zoom;
var x = mouse_x / current_zoom; var x = mouse_x / current_zoom;
var y = mouse_y / current_zoom; var y = mouse_y / current_zoom;
@ -4772,20 +4792,19 @@ function BatchCommand(text) {
else { else {
w = svgcontent.getAttribute("width"); w = svgcontent.getAttribute("width");
h = svgcontent.getAttribute("height"); h = svgcontent.getAttribute("height");
svgcontent.setAttribute("viewBox", ["0", "0", w, h].join(" ")); // svgcontent.setAttribute("viewBox", ["0", "0", w, h].join(" "));
} }
// just to be safe, set width and height to 100%/100% svgcontent.setAttribute('width', w);
// (removing causes bug in Webkit) svgcontent.setAttribute('height', h);
svgcontent.setAttribute('width','100%'); svgcontent.setAttribute('overflow', 'visible');
svgcontent.setAttribute('height','100%');
batchCmd.addSubCommand(new InsertElementCommand(svgcontent)); batchCmd.addSubCommand(new InsertElementCommand(svgcontent));
// update root to the correct size // update root to the correct size
var changes = {}; var changes = {};
changes['width'] = svgroot.getAttribute('width'); changes['width'] = svgcontent.getAttribute('width');
changes['height'] = svgroot.getAttribute('height'); changes['height'] = svgcontent.getAttribute('height');
svgroot.setAttribute('width', w); // svgroot.setAttribute('width', w);
svgroot.setAttribute('height', h); // svgroot.setAttribute('height', h);
batchCmd.addSubCommand(new ChangeElementCommand(svgroot, changes)); batchCmd.addSubCommand(new ChangeElementCommand(svgroot, changes));
// reset zoom // reset zoom
@ -5235,9 +5254,14 @@ function BatchCommand(text) {
} }
this.getResolution = function() { this.getResolution = function() {
// return [svgroot.getAttribute("width"), svgroot.getAttribute("height")]; // var vb = svgcontent.getAttribute("viewBox").split(' ');
var vb = svgcontent.getAttribute("viewBox").split(' '); // return {'w':vb[2], 'h':vb[3], 'zoom': current_zoom};
return {'w':vb[2], 'h':vb[3], 'zoom': current_zoom};
return {
'w':svgcontent.getAttribute("width"),
'h':svgcontent.getAttribute("height"),
'zoom': current_zoom
};
}; };
this.getImageTitle = function() { this.getImageTitle = function() {
@ -5306,18 +5330,16 @@ function BatchCommand(text) {
return false; return false;
} }
} }
x *= current_zoom;
y *= current_zoom;
if (x != w || y != h) { if (x != w || y != h) {
var handle = svgroot.suspendRedraw(1000); var handle = svgroot.suspendRedraw(1000);
if(!batchCmd) { if(!batchCmd) {
batchCmd = new BatchCommand("Change Image Dimensions"); batchCmd = new BatchCommand("Change Image Dimensions");
} }
svgroot.setAttribute('width', x); svgcontent.setAttribute('width', x);
svgroot.setAttribute('height', y); svgcontent.setAttribute('height', y);
batchCmd.addSubCommand(new ChangeElementCommand(svgroot, {"width":w, "height":h})); batchCmd.addSubCommand(new ChangeElementCommand(svgcontent, {"width":w, "height":h}));
svgcontent.setAttribute("viewBox", ["0 0", x/current_zoom, y/current_zoom].join(' ')); svgcontent.setAttribute("viewBox", [0, 0, x/current_zoom, y/current_zoom].join(' '));
batchCmd.addSubCommand(new ChangeElementCommand(svgcontent, {"viewBox": ["0 0", w, h].join(' ')})); batchCmd.addSubCommand(new ChangeElementCommand(svgcontent, {"viewBox": ["0 0", w, h].join(' ')}));
addCommandToHistory(batchCmd); addCommandToHistory(batchCmd);
@ -5373,8 +5395,7 @@ function BatchCommand(text) {
this.setZoom = function(zoomlevel) { this.setZoom = function(zoomlevel) {
var res = canvas.getResolution(); var res = canvas.getResolution();
svgroot.setAttribute("width", res.w * zoomlevel); svgcontent.setAttribute("viewBox", "0 0 " + res.w/zoomlevel + " " + res.h/zoomlevel);
svgroot.setAttribute("height", res.h * zoomlevel);
current_zoom = zoomlevel; current_zoom = zoomlevel;
$.each(selectedElements, function(i, elem) { $.each(selectedElements, function(i, elem) {
if(!elem) return; if(!elem) return;
@ -6340,6 +6361,26 @@ function BatchCommand(text) {
}; };
} }
this.updateCanvas = function(w, h, w_orig, h_orig) {
svgroot.setAttribute("width", w);
svgroot.setAttribute("height", h);
var rect = $('#borderRect')[0];
var x = (w/2 - svgcontent.getAttribute('width')*current_zoom/2);
var y = (h/2 - svgcontent.getAttribute('height')*current_zoom/2);
assignAttributes(svgcontent, {
'x': x,
'y': y
});
assignAttributes(rect, {
width: svgcontent.getAttribute('width') * current_zoom,
height: svgcontent.getAttribute('height') * current_zoom
});
selectorManager.selectorParentGroup.setAttribute("transform","translate(" + x + "," + y + ")");
}
this.getStrokedBBox = function(elems) { this.getStrokedBBox = function(elems) {
if(!elems) elems = canvas.getVisibleElements(); if(!elems) elems = canvas.getVisibleElements();
if(!elems.length) return false; if(!elems.length) return false;