define(function(require, exports, module) { var data = require('../core/data'); /** * 导出svg时删除全部svg元素中的transform * @auth Naixor * @method removeTransform * @param {[type]} svgDom [description] * @return {[type]} [description] */ function cleanSVG(svgDom, x, y) { function getTransformToElement(target, source) { var matrix; try { matrix = source.getScreenCTM().inverse(); } catch (e) { throw new Error("Can not inverse source element' ctm."); } return matrix.multiply(target.getScreenCTM()); } function dealWithPath(d, dealWithPattern) { if (!(dealWithPattern instanceof Function)) { dealWithPattern = function() {}; } var strArr = [], pattern = [], cache = []; for (var i = 0, l = d.length; i < l; i++) { switch (d[i]) { case "M": case "L": case "T": case "S": case "A": case "C": case "H": case "V": case "Q": { if (cache.length) { pattern.push(cache.join("")); cache = []; } // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 C..", 那空格几个意思 - - if (pattern[pattern.length-1] === ",") { pattern.pop(); } if (pattern.length) { dealWithPattern(pattern); strArr.push(pattern.join("")); pattern = []; } pattern.push(d[i]); break; } case "Z": case "z": { pattern.push(cache.join(""), d[i]); dealWithPattern(pattern); strArr.push(pattern.join("")); cache = []; pattern = []; break; } case ".": case "e": { cache.push(d[i]); break; } case "-": { if (d[i-1] !== "e") { if (cache.length) { pattern.push(cache.join(""), ","); } cache = []; } cache.push("-"); break; } case " ": case ",": { if (cache.length) { pattern.push(cache.join(""), ","); cache = []; } break; } default: { if (/\d/.test(d[i])) { cache.push(d[i]); } else { // m a c s q h v l t z情况 if (cache.length) { pattern.push(cache.join(""), d[i]); cache = []; } else { // 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 c..", 那空格几个意思 - - if (pattern[pattern.length-1] === ",") { pattern.pop(); } pattern.push(d[i]); } } if (i + 1 === l) { if (cache.length) { pattern.push(cache.join("")); } dealWithPattern(pattern); strArr.push(pattern.join("")); cache = null; pattern = null; } } } } return strArr.join(""); } function replaceWithNode(svgNode, parentX, parentY) { if (!svgNode) { return; } if (svgNode.tagName === "defs") { return; } if (svgNode.getAttribute('fill') === 'transparent') { svgNode.setAttribute('fill', 'none'); } if (svgNode.getAttribute('marker-end')) { svgNode.removeAttribute('marker-end'); } parentX = parentX || 0; parentY = parentY || 0; if (svgNode.getAttribute("transform")) { var ctm = getTransformToElement(svgNode, svgNode.parentElement); parentX -= ctm.e; parentY -= ctm.f; svgNode.removeAttribute("transform"); } switch (svgNode.tagName.toLowerCase()) { case "g": break; case "path": { var d = svgNode.getAttribute("d"); if (d) { d = dealWithPath(d, function(pattern) { switch (pattern[0]) { case "V": { pattern[1] = +pattern[1] - parentY; break; } case "H": { pattern[1] = +pattern[1] - parentX; break; } case "M": case "L": case "T": { pattern[1] = +pattern[1] - parentX; pattern[3] = +pattern[3] - parentY; break; } case "Q": case "S": { pattern[1] = +pattern[1] - parentX; pattern[3] = +pattern[3] - parentY; pattern[5] = +pattern[5] - parentX; pattern[7] = +pattern[7] - parentY; break; } case "A": { pattern[11] = +pattern[11] - parentX; pattern[13] = +pattern[13] - parentY; break; } case "C": { pattern[1] = +pattern[1] - parentX; pattern[3] = +pattern[3] - parentY; pattern[5] = +pattern[5] - parentX; pattern[7] = +pattern[7] - parentY; pattern[9] = +pattern[9] - parentX; pattern[11] = +pattern[11] - parentY; } } }); svgNode.setAttribute("d", d); svgNode.removeAttribute("transform"); } return; } case "image": case "text": { if (parentX && parentY) { var x = +svgNode.getAttribute("x") || 0, y = +svgNode.getAttribute("y") || 0; svgNode.setAttribute("x", x - parentX); svgNode.setAttribute("y", y - parentY); } if (svgNode.getAttribute("dominant-baseline")) { svgNode.removeAttribute("dominant-baseline"); svgNode.setAttribute("dy", ".8em"); } svgNode.removeAttribute("transform"); return; } } if (svgNode.children) { for (var i = 0, l = svgNode.children.length; i < l; i++) { replaceWithNode(svgNode.children[i], parentX, parentY); } } } svgDom.style.visibility = "hidden"; replaceWithNode(svgDom, x || 0, y || 0); svgDom.style.visibility = "visible"; } data.registerProtocol("svg", module.exports = { fileDescription: "SVG 矢量图", fileExtension: ".svg", mineType: "image/svg+xml", dataType: "text", encode: function(json, minder) { var paper = minder.getPaper(), paperTransform = paper.shapeNode.getAttribute("transform"), svgXml, svgContainer, svgDom, renderContainer = minder.getRenderContainer(), renderBox = renderContainer.getRenderBox(), transform = renderContainer.getTransform(), width = renderBox.width, height = renderBox.height, padding = 20; paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)"); svgXml = paper.container.innerHTML; paper.shapeNode.setAttribute("transform", paperTransform); svgContainer = document.createElement("div"); document.body.appendChild(svgContainer); svgContainer.innerHTML = svgXml; svgDom = svgContainer.querySelector("svg"); svgDom.setAttribute("width", width + padding * 2 | 0); svgDom.setAttribute("height", height + padding * 2 | 0); svgDom.setAttribute("style", "background: " + minder.getStyle("background"));//"font-family: Arial, Microsoft Yahei, Heiti SC; " + svgDom.setAttribute("viewBox", [ 0, 0, width + padding * 2 | 0, height + padding * 2 | 0 ].join(" ")); tempSvgContainer = document.createElement("div"); cleanSVG(svgDom, renderBox.x - padding | 0, renderBox.y - padding | 0); document.body.removeChild(svgContainer); tempSvgContainer.appendChild(svgDom); // need a xml with width and height svgXml = tempSvgContainer.innerHTML; // svg 含有   符号导出报错 Entity 'nbsp' not defined svgXml = svgXml.replace(/ /g, " "); // svg 含有   符号导出报错 Entity 'nbsp' not defined return svgXml; } }); });