diff --git a/editor/svg-editor.css b/editor/svg-editor.css
index 5b293d51..e3c41a28 100644
--- a/editor/svg-editor.css
+++ b/editor/svg-editor.css
@@ -137,6 +137,10 @@ div.color_block {
display: none;
}
+#svg_editor #image_panel {
+ display: none;
+}
+
#svg_editor #text_panel {
display: none;
}
@@ -157,6 +161,10 @@ div.color_block {
vertical-align: 12px;
}
+#svg_editor #image_panel .image_tool {
+ vertical-align: 12px;
+}
+
#svg_editor #circle_panel .circle_tool {
vertical-align:12px;
}
diff --git a/editor/svg-editor.html b/editor/svg-editor.html
index 61f6b5b8..88c147b5 100644
--- a/editor/svg-editor.html
+++ b/editor/svg-editor.html
@@ -117,6 +117,21 @@
+
+
+
diff --git a/editor/svg-editor.js b/editor/svg-editor.js
index 554b3725..87c2b4e4 100644
--- a/editor/svg-editor.js
+++ b/editor/svg-editor.js
@@ -81,7 +81,7 @@ function svg_edit_setup() {
// updates the toolbar (colors, opacity, etc) based on the selected element
var updateToolbar = function() {
- if (selectedElement != null) {
+ if (selectedElement != null) { //the image thing might be a hack.
// get opacity values
var fillOpacity = parseFloat(selectedElement.getAttribute("fill-opacity"));
if (isNaN(fillOpacity)) {
@@ -168,7 +168,7 @@ function svg_edit_setup() {
}
$('#selected_panel, #multiselected_panel, #rect_panel, #circle_panel,\
- #ellipse_panel, #line_panel, #text_panel').hide();
+ #ellipse_panel, #line_panel, #text_panel, #image_panel').hide();
if (elem != null) {
$('#angle').val(svgCanvas.getRotationAngle(elem));
$('#selected_panel').show();
@@ -176,6 +176,7 @@ function svg_edit_setup() {
// update contextual tools here
var panels = {
rect: ['radius','x','y','width','height'],
+ image: ['x','y','width','height'],
circle: ['cx','cy','r'],
ellipse: ['cx','cy','rx','ry'],
line: ['x1','y1','x2','y2'],
@@ -215,7 +216,13 @@ function svg_edit_setup() {
if (svgCanvas.addedNew) {
$('#text').focus().select();
}
- }
+ }else if(el_name == 'image') {
+ var xlinkNS="http://www.w3.org/1999/xlink";
+ $('#image_url').val(elem.getAttributeNS(xlinkNS, "href"));
+
+ }
+
+
}
} // if (elem != null)
else if (multiselected) {
@@ -242,6 +249,8 @@ function svg_edit_setup() {
$('#text').focus( function(){ textBeingEntered = true; } );
$('#text').blur( function(){ textBeingEntered = false; } );
+ $('#image_url').blur(function(){ svgCanvas.setImageURL(this.value); });
+
// bind the selected event to our function that handles updates to the UI
svgCanvas.bind("selected", selectedChanged);
svgCanvas.bind("changed", elementChanged);
@@ -296,6 +305,7 @@ function svg_edit_setup() {
$('#text').keyup(function(){
svgCanvas.setTextContent(this.value);
});
+
$('.attr_changer').change(function() {
var attr = this.getAttribute("alt");
@@ -423,6 +433,12 @@ function svg_edit_setup() {
$('#tools_rect_show').attr('src', 'images/rect.png');
};
+ var clickImage = function(){
+ if (toolButtonClick('#tool_image')) {
+ svgCanvas.setMode('image');
+ }
+ };
+
var clickFHRect = function(){
if (toolButtonClick('#tools_rect_show')) {
svgCanvas.setMode('fhrect');
@@ -623,6 +639,7 @@ function svg_edit_setup() {
$('#tool_circle').mouseup(clickCircle);
$('#tool_ellipse').mouseup(clickEllipse);
$('#tool_fhellipse').mouseup(clickFHEllipse);
+ $('#tool_image').mouseup(clickImage);
$('#tool_text').click(clickText);
$('#tool_poly').click(clickPoly);
$('#tool_clear').click(clickClear);
diff --git a/editor/svgcanvas.js b/editor/svgcanvas.js
index 5e506af4..8693fac1 100644
--- a/editor/svgcanvas.js
+++ b/editor/svgcanvas.js
@@ -22,6 +22,7 @@ var svgWhiteList = {
"rect": ["fill", "fill-opacity", "height", "id", "opacity", "rx", "ry", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-opacity", "stroke-width", "transform", "width", "x", "y"],
"stop": ["id", "offset", "stop-color", "stop-opacity"],
"svg": ["id", "height", "transform", "width", "xmlns"],
+ "image": ["id","width","height","opacity","x","y"],
"text": ["fill", "fill-opacity", "font-family", "font-size", "font-style", "font-weight", "id", "opacity", "stroke", "stroke-dasharray", "stroke-linecap", "stroke-linejoin", "stroke-opacity", "stroke-width", "transform", "text-anchor", "x", "y"],
};
@@ -1116,6 +1117,20 @@ function BatchCommand(text) {
'y': pt.y
}, 1000);
break;
+
+ case "image":
+ changes["x"] = selected.getAttribute("x");
+ changes["y"] = selected.getAttribute("y");
+ changes["width"] = selected.getAttribute("width");
+ changes["height"] = selected.getAttribute("height");
+ var pt = remap(changes["x"], changes["y"]);
+ assignAttributes(selected, {
+ 'x': pt.x,
+ 'y': pt.y,
+ 'width': scalew(changes["width"]),
+ 'height': scaleh(changes["height"])
+ }, 1000);
+ break;
case "rect":
changes["x"] = selected.getAttribute("x");
changes["y"] = selected.getAttribute("y");
@@ -1220,6 +1235,8 @@ function BatchCommand(text) {
var x = evt.pageX - container.parentNode.offsetLeft + container.parentNode.scrollLeft;
var y = evt.pageY - container.parentNode.offsetTop + container.parentNode.scrollTop;
+ evt.preventDefault()
+
if($.inArray(current_mode, ['select', 'resize']) == -1) {
addGradient();
}
@@ -1290,6 +1307,24 @@ function BatchCommand(text) {
freehand_min_y = y;
freehand_max_y = y;
break;
+ case "image":
+ started = true;
+ start_x = x;
+ start_y = y;
+ var newImage = addSvgElementFromJson({
+ "element": "image",
+ "attr": {
+ "x": x,
+ "y": y,
+ "width": 0,
+ "height": 0,
+ "id": getNextId(),
+ "opacity": cur_shape.opacity / 2
+ }
+ });
+ var xlinkNS="http://www.w3.org/1999/xlink";
+ newImage.setAttributeNS(xlinkNS, "href", "images/logo.png")
+ break;
case "square":
// FIXME: once we create the rect, we lose information that this was a square
// (for resizing purposes this could be important)
@@ -1447,6 +1482,10 @@ function BatchCommand(text) {
var x = evt.pageX - container.parentNode.offsetLeft + container.parentNode.scrollLeft;
var y = evt.pageY - container.parentNode.offsetTop + container.parentNode.scrollTop;
var shape = svgdoc.getElementById(getId());
+
+ evt.preventDefault()
+
+
switch (current_mode)
{
case "select":
@@ -1649,6 +1688,14 @@ function BatchCommand(text) {
'y': Math.min(start_y,y)
},1000);
break;
+ case "image":
+ assignAttributes(shape,{
+ 'width': Math.abs(x-start_x),
+ 'height': Math.abs(y-start_y),
+ 'x': Math.min(start_x,x),
+ 'y': Math.min(start_y,y)
+ },1000);
+ break;
case "circle":
var cx = shape.getAttributeNS(null, "cx");
var cy = shape.getAttributeNS(null, "cy");
@@ -1929,6 +1976,10 @@ function BatchCommand(text) {
keep = (element.getAttribute('width') != 0 ||
element.getAttribute('height') != 0);
break;
+ case "image":
+ keep = (element.getAttribute('width') != 0 ||
+ element.getAttribute('height') != 0);
+ break;
case "circle":
keep = (element.getAttribute('r') != 0);
break;
@@ -2714,6 +2765,10 @@ function BatchCommand(text) {
this.changeSelectedAttribute("#text", val);
};
+ this.setImageURL = function(val) {
+ this.changeSelectedAttribute("#href", val);
+ };
+
this.setRectRadius = function(val) {
var selected = selectedElements[0];
if (selected != null && selected.tagName == "rect") {
@@ -2780,7 +2835,10 @@ function BatchCommand(text) {
if (attr == "#text") {
elem.textContent = newValue;
elem = canvas.quickClone(elem);
- }
+ } else if (attr == "#href") {
+ var xlinkNS="http://www.w3.org/1999/xlink";
+ elem.setAttributeNS(xlinkNS, "href", val);
+ }
else elem.setAttribute(attr, newValue);
selectedBBoxes[i] = this.getBBox(elem);
// Use the Firefox quickClone hack for text elements with gradients or