📄 svg.js
字号:
/* 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -