mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@5282 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
662 lines
21 KiB
JavaScript
662 lines
21 KiB
JavaScript
/*
|
|
Copyright (c) 2004-2006, The Dojo Foundation
|
|
All Rights Reserved.
|
|
|
|
Licensed under the Academic Free License version 2.1 or above OR the
|
|
modified BSD license. For more information on Dojo licensing, see:
|
|
|
|
http://dojotoolkit.org/community/licensing.shtml
|
|
*/
|
|
|
|
dojo.provide("dojo.gfx.svg");
|
|
|
|
dojo.require("dojo.lang.declare");
|
|
dojo.require("dojo.svg");
|
|
|
|
dojo.require("dojo.gfx.color");
|
|
dojo.require("dojo.gfx.common");
|
|
dojo.require("dojo.gfx.shape");
|
|
dojo.require("dojo.gfx.path");
|
|
|
|
dojo.require("dojo.experimental");
|
|
dojo.experimental("dojo.gfx.svg");
|
|
|
|
dojo.gfx.svg.getRef = function(fill){
|
|
// summary: returns a DOM Node specified by the fill argument or null
|
|
// fill: String: an SVG fill
|
|
if(!fill || fill == "none") return null;
|
|
if(fill.match(/^url\(#.+\)$/)){
|
|
return dojo.byId(fill.slice(5, -1)); // Node
|
|
}
|
|
// Opera's bug: incorrect representation of a reference
|
|
if(dojo.render.html.opera && fill.match(/^#dj_unique_.+$/)){
|
|
// we assume here that a reference was generated by dojo.gfx
|
|
return dojo.byId(fill.slice(1)); // Node
|
|
}
|
|
return null; // Node
|
|
};
|
|
|
|
dojo.lang.extend(dojo.gfx.Shape, {
|
|
// summary: SVG-specific implementation of dojo.gfx.Shape methods
|
|
|
|
setFill: function(fill){
|
|
// summary: sets a fill object (SVG)
|
|
// fill: Object: a fill object
|
|
// (see dojo.gfx.defaultLinearGradient,
|
|
// dojo.gfx.defaultRadialGradient,
|
|
// dojo.gfx.defaultPattern,
|
|
// or dojo.gfx.color.Color)
|
|
|
|
if(!fill){
|
|
// don't fill
|
|
this.fillStyle = null;
|
|
this.rawNode.setAttribute("fill", "none");
|
|
this.rawNode.setAttribute("fill-opacity", 0);
|
|
return this;
|
|
}
|
|
if(typeof(fill) == "object" && "type" in fill){
|
|
// gradient
|
|
switch(fill.type){
|
|
case "linear":
|
|
var f = dojo.gfx.makeParameters(dojo.gfx.defaultLinearGradient, fill);
|
|
var gradient = this._setFillObject(f, "linearGradient");
|
|
dojo.lang.forEach(["x1", "y1", "x2", "y2"], function(x){
|
|
gradient.setAttribute(x, f[x].toFixed(8));
|
|
});
|
|
break;
|
|
case "radial":
|
|
var f = dojo.gfx.makeParameters(dojo.gfx.defaultRadialGradient, fill);
|
|
var gradient = this._setFillObject(f, "radialGradient");
|
|
dojo.lang.forEach(["cx", "cy", "r"], function(x){
|
|
gradient.setAttribute(x, f[x].toFixed(8));
|
|
});
|
|
break;
|
|
case "pattern":
|
|
var f = dojo.gfx.makeParameters(dojo.gfx.defaultPattern, fill);
|
|
var pattern = this._setFillObject(f, "pattern");
|
|
dojo.lang.forEach(["x", "y", "width", "height"], function(x){
|
|
pattern.setAttribute(x, f[x].toFixed(8));
|
|
});
|
|
break;
|
|
}
|
|
return this;
|
|
}
|
|
// color object
|
|
var f = dojo.gfx.normalizeColor(fill);
|
|
this.fillStyle = f;
|
|
this.rawNode.setAttribute("fill", f.toCss());
|
|
this.rawNode.setAttribute("fill-opacity", f.a);
|
|
return this; // self
|
|
},
|
|
|
|
setStroke: function(stroke){
|
|
// summary: sets a stroke object (SVG)
|
|
// stroke: Object: a stroke object
|
|
// (see dojo.gfx.defaultStroke)
|
|
|
|
if(!stroke){
|
|
// don't stroke
|
|
this.strokeStyle = null;
|
|
this.rawNode.setAttribute("stroke", "none");
|
|
this.rawNode.setAttribute("stroke-opacity", 0);
|
|
return this;
|
|
}
|
|
// normalize the stroke
|
|
this.strokeStyle = dojo.gfx.makeParameters(dojo.gfx.defaultStroke, stroke);
|
|
this.strokeStyle.color = dojo.gfx.normalizeColor(this.strokeStyle.color);
|
|
// generate attributes
|
|
var s = this.strokeStyle;
|
|
var rn = this.rawNode;
|
|
if(s){
|
|
rn.setAttribute("stroke", s.color.toCss());
|
|
rn.setAttribute("stroke-opacity", s.color.a);
|
|
rn.setAttribute("stroke-width", s.width);
|
|
rn.setAttribute("stroke-linecap", s.cap);
|
|
if(typeof(s.join) == "number"){
|
|
rn.setAttribute("stroke-linejoin", "miter");
|
|
rn.setAttribute("stroke-miterlimit", s.join);
|
|
}else{
|
|
rn.setAttribute("stroke-linejoin", s.join);
|
|
}
|
|
}
|
|
return this; // self
|
|
},
|
|
|
|
_setFillObject: function(f, nodeType){
|
|
var def_elems = this.rawNode.parentNode.getElementsByTagName("defs");
|
|
if(def_elems.length == 0){ return this; }
|
|
this.fillStyle = f;
|
|
var defs = def_elems[0];
|
|
var fill = this.rawNode.getAttribute("fill");
|
|
var ref = dojo.gfx.svg.getRef(fill);
|
|
if(ref){
|
|
fill = ref;
|
|
if(fill.tagName.toLowerCase() != nodeType.toLowerCase()){
|
|
var id = fill.id;
|
|
fill.parentNode.removeChild(fill);
|
|
fill = document.createElementNS(dojo.svg.xmlns.svg, nodeType);
|
|
fill.setAttribute("id", id);
|
|
defs.appendChild(fill);
|
|
}else{
|
|
while(fill.childNodes.length){
|
|
fill.removeChild(fill.lastChild);
|
|
}
|
|
}
|
|
}else{
|
|
fill = document.createElementNS(dojo.svg.xmlns.svg, nodeType);
|
|
fill.setAttribute("id", dojo.dom.getUniqueId());
|
|
defs.appendChild(fill);
|
|
}
|
|
if(nodeType == "pattern"){
|
|
fill.setAttribute("patternUnits", "userSpaceOnUse");
|
|
var img = document.createElementNS(dojo.svg.xmlns.svg, "image");
|
|
img.setAttribute("x", 0);
|
|
img.setAttribute("y", 0);
|
|
img.setAttribute("width", f.width .toFixed(8));
|
|
img.setAttribute("height", f.height.toFixed(8));
|
|
img.setAttributeNS(dojo.svg.xmlns.xlink, "href", f.src);
|
|
fill.appendChild(img);
|
|
}else{
|
|
fill.setAttribute("gradientUnits", "userSpaceOnUse");
|
|
for(var i = 0; i < f.colors.length; ++i){
|
|
f.colors[i].color = dojo.gfx.normalizeColor(f.colors[i].color);
|
|
var t = document.createElementNS(dojo.svg.xmlns.svg, "stop");
|
|
t.setAttribute("offset", f.colors[i].offset.toFixed(8));
|
|
t.setAttribute("stop-color", f.colors[i].color.toCss());
|
|
fill.appendChild(t);
|
|
}
|
|
}
|
|
this.rawNode.setAttribute("fill", "url(#" + fill.getAttribute("id") +")");
|
|
this.rawNode.removeAttribute("fill-opacity");
|
|
return fill;
|
|
},
|
|
|
|
_applyTransform: function() {
|
|
var matrix = this._getRealMatrix();
|
|
if(matrix){
|
|
var tm = this.matrix;
|
|
this.rawNode.setAttribute("transform", "matrix(" +
|
|
tm.xx.toFixed(8) + "," + tm.yx.toFixed(8) + "," +
|
|
tm.xy.toFixed(8) + "," + tm.yy.toFixed(8) + "," +
|
|
tm.dx.toFixed(8) + "," + tm.dy.toFixed(8) + ")");
|
|
}else{
|
|
this.rawNode.removeAttribute("transform");
|
|
}
|
|
return this;
|
|
},
|
|
|
|
setRawNode: function(rawNode){
|
|
// summary:
|
|
// assigns and clears the underlying node that will represent this
|
|
// shape. Once set, transforms, gradients, etc, can be applied.
|
|
// (no fill & stroke by default)
|
|
with(rawNode){
|
|
setAttribute("fill", "none");
|
|
setAttribute("fill-opacity", 0);
|
|
setAttribute("stroke", "none");
|
|
setAttribute("stroke-opacity", 0);
|
|
setAttribute("stroke-width", 1);
|
|
setAttribute("stroke-linecap", "butt");
|
|
setAttribute("stroke-linejoin", "miter");
|
|
setAttribute("stroke-miterlimit", 4);
|
|
}
|
|
this.rawNode = rawNode;
|
|
},
|
|
|
|
moveToFront: function(){
|
|
// summary: moves a shape to front of its parent's list of shapes (SVG)
|
|
this.rawNode.parentNode.appendChild(this.rawNode);
|
|
return this; // self
|
|
},
|
|
moveToBack: function(){
|
|
// summary: moves a shape to back of its parent's list of shapes (SVG)
|
|
this.rawNode.parentNode.insertBefore(this.rawNode, this.rawNode.parentNode.firstChild);
|
|
return this; // self
|
|
},
|
|
|
|
setShape: function(newShape){
|
|
// summary: sets a shape object (SVG)
|
|
// newShape: Object: a shape object
|
|
// (see dojo.gfx.defaultPath,
|
|
// dojo.gfx.defaultPolyline,
|
|
// dojo.gfx.defaultRect,
|
|
// dojo.gfx.defaultEllipse,
|
|
// dojo.gfx.defaultCircle,
|
|
// dojo.gfx.defaultLine,
|
|
// or dojo.gfx.defaultImage)
|
|
this.shape = dojo.gfx.makeParameters(this.shape, newShape);
|
|
for(var i in this.shape){
|
|
if(i != "type"){ this.rawNode.setAttribute(i, this.shape[i]); }
|
|
}
|
|
return this; // self
|
|
},
|
|
|
|
attachFill: function(rawNode){
|
|
// summary: deduces a fill style from a Node.
|
|
// rawNode: Node: an SVG node
|
|
var fillStyle = null;
|
|
if(rawNode){
|
|
var fill = rawNode.getAttribute("fill");
|
|
if(fill == "none"){ return; }
|
|
var ref = dojo.gfx.svg.getRef(fill);
|
|
if(ref){
|
|
var gradient = ref;
|
|
switch(gradient.tagName.toLowerCase()){
|
|
case "lineargradient":
|
|
fillStyle = this._getGradient(dojo.gfx.defaultLinearGradient, gradient);
|
|
dojo.lang.forEach(["x1", "y1", "x2", "y2"], function(x){
|
|
fillStyle[x] = gradient.getAttribute(x);
|
|
});
|
|
break;
|
|
case "radialgradient":
|
|
fillStyle = this._getGradient(dojo.gfx.defaultRadialGradient, gradient);
|
|
dojo.lang.forEach(["cx", "cy", "r"], function(x){
|
|
fillStyle[x] = gradient.getAttribute(x);
|
|
});
|
|
fillStyle.cx = gradient.getAttribute("cx");
|
|
fillStyle.cy = gradient.getAttribute("cy");
|
|
fillStyle.r = gradient.getAttribute("r");
|
|
break;
|
|
case "pattern":
|
|
fillStyle = dojo.lang.shallowCopy(dojo.gfx.defaultPattern, true);
|
|
dojo.lang.forEach(["x", "y", "width", "height"], function(x){
|
|
fillStyle[x] = gradient.getAttribute(x);
|
|
});
|
|
fillStyle.src = gradient.firstChild.getAttributeNS(dojo.svg.xmlns.xlink, "href");
|
|
break;
|
|
}
|
|
}else{
|
|
fillStyle = new dojo.gfx.color.Color(fill);
|
|
var opacity = rawNode.getAttribute("fill-opacity");
|
|
if(opacity != null) fillStyle.a = opacity;
|
|
}
|
|
}
|
|
return fillStyle; // Object
|
|
},
|
|
|
|
_getGradient: function(defaultGradient, gradient){
|
|
var fillStyle = dojo.lang.shallowCopy(defaultGradient, true);
|
|
fillStyle.colors = [];
|
|
for(var i = 0; i < gradient.childNodes.length; ++i){
|
|
fillStyle.colors.push({
|
|
offset: gradient.childNodes[i].getAttribute("offset"),
|
|
color: new dojo.gfx.color.Color(gradient.childNodes[i].getAttribute("stop-color"))
|
|
});
|
|
}
|
|
return fillStyle;
|
|
},
|
|
|
|
attachStroke: function(rawNode){
|
|
// summary: deduces a stroke style from a Node.
|
|
// rawNode: Node: an SVG node
|
|
if(!rawNode){ return; }
|
|
var stroke = rawNode.getAttribute("stroke");
|
|
if(stroke == null || stroke == "none") return null;
|
|
var strokeStyle = dojo.lang.shallowCopy(dojo.gfx.defaultStroke, true);
|
|
var color = new dojo.gfx.color.Color(stroke);
|
|
if(color){
|
|
strokeStyle.color = color;
|
|
strokeStyle.color.a = rawNode.getAttribute("stroke-opacity");
|
|
strokeStyle.width = rawNode.getAttribute("stroke-width");
|
|
strokeStyle.cap = rawNode.getAttribute("stroke-linecap");
|
|
strokeStyle.join = rawNode.getAttribute("stroke-linejoin");
|
|
if(strokeStyle.join == "miter"){
|
|
strokeStyle.join = rawNode.getAttribute("stroke-miterlimit");
|
|
}
|
|
}
|
|
return strokeStyle; // Object
|
|
},
|
|
|
|
attachTransform: function(rawNode){
|
|
// summary: deduces a transformation matrix from a Node.
|
|
// rawNode: Node: an SVG node
|
|
var matrix = null;
|
|
if(rawNode){
|
|
matrix = rawNode.getAttribute("transform");
|
|
if(matrix.match(/^matrix\(.+\)$/)){
|
|
var t = matrix.slice(7, -1).split(",");
|
|
matrix = dojo.gfx.matrix.normalize({
|
|
xx: parseFloat(t[0]), xy: parseFloat(t[2]),
|
|
yx: parseFloat(t[1]), yy: parseFloat(t[3]),
|
|
dx: parseFloat(t[4]), dy: parseFloat(t[5])
|
|
});
|
|
}
|
|
}
|
|
return matrix; // dojo.gfx.matrix.Matrix
|
|
},
|
|
|
|
attachShape: function(rawNode){
|
|
// summary: builds a shape from a Node.
|
|
// rawNode: Node: an SVG node
|
|
var shape = null;
|
|
if(rawNode){
|
|
shape = dojo.lang.shallowCopy(this.shape, true);
|
|
for(var i in shape) {
|
|
shape[i] = rawNode.getAttribute(i);
|
|
}
|
|
}
|
|
return shape; // dojo.gfx.Shape
|
|
},
|
|
|
|
attach: function(rawNode){
|
|
// summary: reconstructs all shape parameters from a Node.
|
|
// rawNode: Node: an SVG node
|
|
if(rawNode) {
|
|
this.rawNode = rawNode;
|
|
this.fillStyle = this.attachFill(rawNode);
|
|
this.strokeStyle = this.attachStroke(rawNode);
|
|
this.matrix = this.attachTransform(rawNode);
|
|
this.shape = this.attachShape(rawNode);
|
|
}
|
|
}
|
|
});
|
|
|
|
dojo.declare("dojo.gfx.Group", dojo.gfx.Shape, {
|
|
// summary: a group shape (SVG), which can be used
|
|
// to logically group shapes (e.g, to propagate matricies)
|
|
|
|
setRawNode: function(rawNode){
|
|
// summary: sets a raw SVG node to be used by this shape
|
|
// rawNode: Node: an SVG node
|
|
this.rawNode = rawNode;
|
|
}
|
|
});
|
|
dojo.gfx.Group.nodeType = "g";
|
|
|
|
dojo.declare("dojo.gfx.Rect", dojo.gfx.shape.Rect, {
|
|
// summary: a rectangle shape (SVG)
|
|
|
|
attachShape: function(rawNode){
|
|
// summary: builds a rectangle shape from a Node.
|
|
// rawNode: Node: an SVG node
|
|
var shape = null;
|
|
if(rawNode){
|
|
shape = dojo.gfx.Rect.superclass.attachShape.apply(this, arguments);
|
|
shape.r = Math.min(rawNode.getAttribute("rx"), rawNode.getAttribute("ry"));
|
|
}
|
|
return shape; // dojo.gfx.shape.Rect
|
|
},
|
|
setShape: function(newShape){
|
|
// summary: sets a rectangle shape object (SVG)
|
|
// newShape: Object: a rectangle shape object
|
|
this.shape = dojo.gfx.makeParameters(this.shape, newShape);
|
|
this.bbox = null;
|
|
for(var i in this.shape){
|
|
if(i != "type" && i != "r"){ this.rawNode.setAttribute(i, this.shape[i]); }
|
|
}
|
|
this.rawNode.setAttribute("rx", this.shape.r);
|
|
this.rawNode.setAttribute("ry", this.shape.r);
|
|
return this; // self
|
|
}
|
|
});
|
|
dojo.gfx.Rect.nodeType = "rect";
|
|
|
|
dojo.gfx.Ellipse = dojo.gfx.shape.Ellipse;
|
|
dojo.gfx.Ellipse.nodeType = "ellipse";
|
|
|
|
dojo.gfx.Circle = dojo.gfx.shape.Circle;
|
|
dojo.gfx.Circle.nodeType = "circle";
|
|
|
|
dojo.gfx.Line = dojo.gfx.shape.Line;
|
|
dojo.gfx.Line.nodeType = "line";
|
|
|
|
dojo.declare("dojo.gfx.Polyline", dojo.gfx.shape.Polyline, {
|
|
// summary: a polyline/polygon shape (SVG)
|
|
|
|
setShape: function(points){
|
|
// summary: sets a polyline/polygon shape object (SVG)
|
|
// points: Object: a polyline/polygon shape object
|
|
if(points && points instanceof Array){
|
|
// branch
|
|
// points: Array: an array of points
|
|
this.shape = dojo.gfx.makeParameters(this.shape, { points: points });
|
|
if(closed && this.shape.points.length){
|
|
this.shape.points.push(this.shape.points[0]);
|
|
}
|
|
}else{
|
|
this.shape = dojo.gfx.makeParameters(this.shape, points);
|
|
}
|
|
this.box = null;
|
|
var attr = [];
|
|
var p = this.shape.points;
|
|
for(var i = 0; i < p.length; ++i){
|
|
attr.push(p[i].x.toFixed(8));
|
|
attr.push(p[i].y.toFixed(8));
|
|
}
|
|
this.rawNode.setAttribute("points", attr.join(" "));
|
|
return this; // self
|
|
}
|
|
});
|
|
dojo.gfx.Polyline.nodeType = "polyline";
|
|
|
|
dojo.declare("dojo.gfx.Image", dojo.gfx.shape.Image, {
|
|
// summary: an image (SVG)
|
|
|
|
setShape: function(newShape){
|
|
// summary: sets an image shape object (SVG)
|
|
// newShape: Object: an image shape object
|
|
this.shape = dojo.gfx.makeParameters(this.shape, newShape);
|
|
this.bbox = null;
|
|
var rawNode = this.rawNode;
|
|
for(var i in this.shape){
|
|
if(i != "type" && i != "src"){ rawNode.setAttribute(i, this.shape[i]); }
|
|
}
|
|
rawNode.setAttributeNS(dojo.svg.xmlns.xlink, "href", this.shape.src);
|
|
return this; // self
|
|
},
|
|
setStroke: function(){
|
|
// summary: ignore setting a stroke style
|
|
return this; // self
|
|
},
|
|
setFill: function(){
|
|
// summary: ignore setting a fill style
|
|
return this; // self
|
|
},
|
|
attachStroke: function(rawNode){
|
|
// summary: ignore attaching a stroke style
|
|
return null;
|
|
},
|
|
attachFill: function(rawNode){
|
|
// summary: ignore attaching a fill style
|
|
return null;
|
|
}
|
|
});
|
|
dojo.gfx.Image.nodeType = "image";
|
|
|
|
dojo.declare("dojo.gfx.Path", dojo.gfx.path.Path, {
|
|
// summary: a path shape (SVG)
|
|
|
|
_updateWithSegment: function(segment){
|
|
// summary: updates the bounding box of path with new segment
|
|
// segment: Object: a segment
|
|
dojo.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
|
|
if(typeof(this.shape.path) == "string"){
|
|
this.rawNode.setAttribute("d", this.shape.path);
|
|
}
|
|
},
|
|
setShape: function(newShape){
|
|
// summary: forms a path using a shape (SVG)
|
|
// newShape: Object: an SVG path string or a path object (see dojo.gfx.defaultPath)
|
|
dojo.gfx.Path.superclass.setShape.apply(this, arguments);
|
|
this.rawNode.setAttribute("d", this.shape.path);
|
|
return this; // self
|
|
}
|
|
});
|
|
dojo.gfx.Path.nodeType = "path";
|
|
|
|
dojo.gfx._creators = {
|
|
// summary: SVG shape creators
|
|
createPath: function(path){
|
|
// summary: creates an SVG path shape
|
|
// path: Object: a path object (see dojo.gfx.defaultPath)
|
|
return this.createObject(dojo.gfx.Path, path); // dojo.gfx.Path
|
|
},
|
|
createRect: function(rect){
|
|
// summary: creates an SVG rectangle shape
|
|
// rect: Object: a path object (see dojo.gfx.defaultRect)
|
|
return this.createObject(dojo.gfx.Rect, rect); // dojo.gfx.Rect
|
|
},
|
|
createCircle: function(circle){
|
|
// summary: creates an SVG circle shape
|
|
// circle: Object: a circle object (see dojo.gfx.defaultCircle)
|
|
return this.createObject(dojo.gfx.Circle, circle); // dojo.gfx.Circle
|
|
},
|
|
createEllipse: function(ellipse){
|
|
// summary: creates an SVG ellipse shape
|
|
// ellipse: Object: an ellipse object (see dojo.gfx.defaultEllipse)
|
|
return this.createObject(dojo.gfx.Ellipse, ellipse); // dojo.gfx.Ellipse
|
|
},
|
|
createLine: function(line){
|
|
// summary: creates an SVG line shape
|
|
// line: Object: a line object (see dojo.gfx.defaultLine)
|
|
return this.createObject(dojo.gfx.Line, line); // dojo.gfx.Line
|
|
},
|
|
createPolyline: function(points){
|
|
// summary: creates an SVG polyline/polygon shape
|
|
// points: Object: a points object (see dojo.gfx.defaultPolyline)
|
|
// or an Array of points
|
|
return this.createObject(dojo.gfx.Polyline, points); // dojo.gfx.Polyline
|
|
},
|
|
createImage: function(image){
|
|
// summary: creates an SVG image shape
|
|
// image: Object: an image object (see dojo.gfx.defaultImage)
|
|
return this.createObject(dojo.gfx.Image, image); // dojo.gfx.Image
|
|
},
|
|
createGroup: function(){
|
|
// summary: creates an SVG group shape
|
|
return this.createObject(dojo.gfx.Group); // dojo.gfx.Group
|
|
},
|
|
createObject: function(shapeType, rawShape){
|
|
// summary: creates an instance of the passed shapeType class
|
|
// shapeType: Function: a class constructor to create an instance of
|
|
// rawShape: Object: properties to be passed in to the classes "setShape" method
|
|
if(!this.rawNode){ return null; }
|
|
var shape = new shapeType();
|
|
var node = document.createElementNS(dojo.svg.xmlns.svg, shapeType.nodeType);
|
|
shape.setRawNode(node);
|
|
this.rawNode.appendChild(node);
|
|
shape.setShape(rawShape);
|
|
this.add(shape);
|
|
return shape; // dojo.gfx.Shape
|
|
},
|
|
// group control
|
|
add: function(shape){
|
|
// summary: adds a shape to a group/surface
|
|
// shape: dojo.gfx.Shape: an SVG shape object
|
|
var oldParent = shape.getParent();
|
|
if(oldParent){
|
|
oldParent.remove(shape, true);
|
|
}
|
|
shape._setParent(this, null);
|
|
this.rawNode.appendChild(shape.rawNode);
|
|
return this; // self
|
|
},
|
|
remove: function(shape, silently){
|
|
// summary: remove a shape from a group/surface
|
|
// shape: dojo.gfx.Shape: an SVG shape object
|
|
// silently: Boolean?: if true, regenerate a picture
|
|
if(this.rawNode == shape.rawNode.parentNode){
|
|
this.rawNode.removeChild(shape.rawNode);
|
|
}
|
|
shape._setParent(null, null);
|
|
return this; // self
|
|
}
|
|
};
|
|
|
|
dojo.gfx.attachNode = function(node){
|
|
// summary: creates a shape from a Node
|
|
// node: Node: an SVG node
|
|
if(!node) return null;
|
|
var s = null;
|
|
switch(node.tagName.toLowerCase()){
|
|
case dojo.gfx.Rect.nodeType:
|
|
s = new dojo.gfx.Rect();
|
|
break;
|
|
case dojo.gfx.Ellipse.nodeType:
|
|
s = new dojo.gfx.Ellipse();
|
|
break;
|
|
case dojo.gfx.Polyline.nodeType:
|
|
s = new dojo.gfx.Polyline();
|
|
break;
|
|
case dojo.gfx.Path.nodeType:
|
|
s = new dojo.gfx.Path();
|
|
break;
|
|
case dojo.gfx.Circle.nodeType:
|
|
s = new dojo.gfx.Circle();
|
|
break;
|
|
case dojo.gfx.Line.nodeType:
|
|
s = new dojo.gfx.Line();
|
|
break;
|
|
case dojo.gfx.Image.nodeType:
|
|
s = new dojo.gfx.Image();
|
|
break;
|
|
default:
|
|
dojo.debug("FATAL ERROR! tagName = " + node.tagName);
|
|
}
|
|
s.attach(node);
|
|
return s; // dojo.gfx.Shape
|
|
};
|
|
|
|
dojo.lang.extend(dojo.gfx.Surface, {
|
|
// summary: a surface object to be used for drawings (SVG)
|
|
|
|
setDimensions: function(width, height){
|
|
// summary: sets the width and height of the rawNode
|
|
// width: String: width of surface, e.g., "100px"
|
|
// height: String: height of surface, e.g., "100px"
|
|
if(!this.rawNode){ return this; }
|
|
this.rawNode.setAttribute("width", width);
|
|
this.rawNode.setAttribute("height", height);
|
|
return this; // self
|
|
},
|
|
getDimensions: function(){
|
|
// summary: returns an object with properties "width" and "height"
|
|
return this.rawNode ? {width: this.rawNode.getAttribute("width"), height: this.rawNode.getAttribute("height")} : null; // Object
|
|
}
|
|
});
|
|
|
|
dojo.gfx.createSurface = function(parentNode, width, height){
|
|
// summary: creates a surface (SVG)
|
|
// parentNode: Node: a parent node
|
|
// width: String: width of surface, e.g., "100px"
|
|
// height: String: height of surface, e.g., "100px"
|
|
|
|
var s = new dojo.gfx.Surface();
|
|
s.rawNode = document.createElementNS(dojo.svg.xmlns.svg, "svg");
|
|
s.rawNode.setAttribute("width", width);
|
|
s.rawNode.setAttribute("height", height);
|
|
|
|
var defs = new dojo.gfx.svg.Defines();
|
|
var node = document.createElementNS(dojo.svg.xmlns.svg, dojo.gfx.svg.Defines.nodeType);
|
|
defs.setRawNode(node);
|
|
s.rawNode.appendChild(node);
|
|
|
|
dojo.byId(parentNode).appendChild(s.rawNode);
|
|
return s; // dojo.gfx.Surface
|
|
};
|
|
|
|
dojo.gfx.attachSurface = function(node){
|
|
// summary: creates a surface from a Node
|
|
// node: Node: an SVG node
|
|
var s = new dojo.gfx.Surface();
|
|
s.rawNode = node;
|
|
return s; // dojo.gfx.Surface
|
|
};
|
|
|
|
dojo.lang.extend(dojo.gfx.Group, dojo.gfx._creators);
|
|
dojo.lang.extend(dojo.gfx.Surface, dojo.gfx._creators);
|
|
|
|
delete dojo.gfx._creators;
|
|
|
|
// Gradient and pattern
|
|
|
|
dojo.gfx.svg.Defines = function(){
|
|
this.rawNode = null;
|
|
};
|
|
dojo.lang.extend(dojo.gfx.svg.Defines, {
|
|
setRawNode: function(rawNode){
|
|
this.rawNode = rawNode;
|
|
}
|
|
});
|
|
dojo.gfx.svg.Defines.nodeType = "defs";
|