Commit 063250a9 authored by hy's avatar hy

export clean SVG for AI and IE.

parent 8bfdc2b0
...@@ -8,136 +8,169 @@ define(function(require, exports, module) { ...@@ -8,136 +8,169 @@ define(function(require, exports, module) {
* @param {[type]} svgDom [description] * @param {[type]} svgDom [description]
* @return {[type]} [description] * @return {[type]} [description]
*/ */
function removeTransform(svgDom) { function cleanSVG(svgDom, x, y) {
function getTransformToElement(target, source) { function getTransformToElement(target, source) {
var matrix; var matrix;
try { try {
matrix = source.getScreenCTM().inverse(); matrix = source.getScreenCTM().inverse();
} catch(e) { } catch (e) {
throw new Error('Can not inverse source element\' ctm.'); throw new Error("Can not inverse source element' ctm.");
} }
return matrix.multiply(target.getScreenCTM()); return matrix.multiply(target.getScreenCTM());
} }
function dealWithPath(d, dealWithPattern) { function dealWithPath(d, dealWithPattern) {
if (!(dealWithPattern instanceof Function)) { if (!(dealWithPattern instanceof Function)) {
dealWithPattern = function () {}; dealWithPattern = function() {};
} }
var strArr = [], var strArr = [], pattern = [], cache = [];
pattern = [],
cache = [];
for (var i = 0, l = d.length; i < l; i++) { for (var i = 0, l = d.length; i < l; i++) {
switch (d[i]) { switch (d[i]) {
case 'M': case "M":
case 'L': case "L":
case 'T': case "T":
case 'S': case "S":
case 'A': case "A":
case 'C': { case "C":
case "H":
case "V":
case "Q": {
if (cache.length) { if (cache.length) {
pattern.push(cache.join('')); pattern.push(cache.join(""));
cache = []; cache = [];
} }
// 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 C..", 那空格几个意思 - -
if (pattern[pattern.length-1] === ",") {
pattern.pop();
}
if (pattern.length) { if (pattern.length) {
dealWithPattern(pattern); dealWithPattern(pattern);
strArr.push(pattern.join('')); strArr.push(pattern.join(""));
pattern = []; pattern = [];
} }
pattern.push(d[i]); pattern.push(d[i]);
break; break;
} }
case 'Z': case "Z":
case 'z': { case "z": {
pattern.push(cache.join(''), d[i]); pattern.push(cache.join(""), d[i]);
dealWithPattern(pattern); dealWithPattern(pattern);
strArr.push(pattern.join('')); strArr.push(pattern.join(""));
cache = []; cache = [];
pattern = []; pattern = [];
break; break;
} }
case '.': { case ".":
cache.push('.'); case "e": {
cache.push(d[i]);
break; break;
} }
case '-': { case "-": {
if (d[i-1] !== "e") {
if (cache.length) { if (cache.length) {
pattern.push(cache.join(''), ','); pattern.push(cache.join(""), ",");
} }
cache = []; cache = [];
cache.push('-'); }
cache.push("-");
break; break;
} }
case ' ': case " ":
case ',': { case ",": {
pattern.push(cache.join(''), ','); if (cache.length) {
pattern.push(cache.join(""), ",");
cache = []; cache = [];
}
break; break;
} }
default: { default: {
if (/\d/.test(d[i])) { if (/\d/.test(d[i])) {
cache.push(d[i]); cache.push(d[i]);
} else { } else {
// m a c s q h v l t z情况
if (cache.length) { if (cache.length) {
pattern.push(cache.join(''), d[i]); pattern.push(cache.join(""), d[i]);
cache = []; cache = [];
} else {
// 脑图的path格式真奇怪...偶尔就给我蹦出来一个"..V123 c..", 那空格几个意思 - -
if (pattern[pattern.length-1] === ",") {
pattern.pop();
}
pattern.push(d[i]);
} }
} }
if (i+1 === l) { if (i + 1 === l) {
if (cache.length) { if (cache.length) {
pattern.push(cache.join('')); pattern.push(cache.join(""));
} }
dealWithPattern(pattern); dealWithPattern(pattern);
strArr.push(pattern.join('')); strArr.push(pattern.join(""));
cache = null; cache = null;
pattern = null; pattern = null;
} }
} }
} }
} }
return strArr.join(''); return strArr.join("");
} }
function replaceWithNode(parent, svgNode, parentX, parentY) { function replaceWithNode(svgNode, parentX, parentY) {
if (!svgNode) { if (!svgNode) {
return; 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; parentX = parentX || 0;
parentY = parentY || 0; parentY = parentY || 0;
if (svgNode.getAttribute('transform')) { if (svgNode.getAttribute("transform")) {
var ctm = getTransformToElement(svgNode, parent); var ctm = getTransformToElement(svgNode, svgNode.parentElement);
parentX -= ctm.e; parentX -= ctm.e;
parentY -= ctm.f; parentY -= ctm.f;
svgNode.removeAttribute('transform'); svgNode.removeAttribute("transform");
} }
switch (svgNode.tagName.toLowerCase()) { switch (svgNode.tagName.toLowerCase()) {
case 'g': { case "g":
break; break;
} case "path": {
case 'path': { var d = svgNode.getAttribute("d");
var d = svgNode.getAttribute('d');
if (d) { if (d) {
d = dealWithPath(d, function(pattern) { d = dealWithPath(d, function(pattern) {
switch (pattern[0]) { switch (pattern[0]) {
case 'M': case "V": {
case 'L': pattern[1] = +pattern[1] - parentY;
case 'T': { break;
}
case "H": {
pattern[1] = +pattern[1] - parentX;
break;
}
case "M":
case "L":
case "T": {
pattern[1] = +pattern[1] - parentX; pattern[1] = +pattern[1] - parentX;
pattern[3] = +pattern[3] - parentY; pattern[3] = +pattern[3] - parentY;
break; break;
} }
case 'S': { case "Q":
case "S": {
pattern[1] = +pattern[1] - parentX; pattern[1] = +pattern[1] - parentX;
pattern[3] = +pattern[3] - parentY; pattern[3] = +pattern[3] - parentY;
pattern[5] = +pattern[5] - parentX; pattern[5] = +pattern[5] - parentX;
pattern[7] = +pattern[7] - parentY; pattern[7] = +pattern[7] - parentY;
break; break;
} }
case 'A': { case "A": {
pattern[11] = +pattern[11] - parentX; pattern[11] = +pattern[11] - parentX;
pattern[13] = +pattern[13] - parentY; pattern[13] = +pattern[13] - parentY;
break; break;
} }
case 'C': { case "C": {
pattern[1] = +pattern[1] - parentX; pattern[1] = +pattern[1] - parentX;
pattern[3] = +pattern[3] - parentY; pattern[3] = +pattern[3] - parentY;
pattern[5] = +pattern[5] - parentX; pattern[5] = +pattern[5] - parentX;
...@@ -147,89 +180,63 @@ define(function(require, exports, module) { ...@@ -147,89 +180,63 @@ define(function(require, exports, module) {
} }
} }
}); });
svgNode.setAttribute('d', d); svgNode.setAttribute("d", d);
svgNode.removeAttribute('transform'); svgNode.removeAttribute("transform");
} }
return; return;
} }
case 'image': case "image":
case 'text': { case "text": {
if (parentX && parentY) { if (parentX && parentY) {
var x = +svgNode.getAttribute('x') || 0, var x = +svgNode.getAttribute("x") || 0, y = +svgNode.getAttribute("y") || 0;
y = +svgNode.getAttribute('y') || 0; svgNode.setAttribute("x", x - parentX);
svgNode.setAttribute('x', x - parentX); svgNode.setAttribute("y", y - parentY);
svgNode.setAttribute('y', y - parentY); }
if (svgNode.getAttribute("dominant-baseline")) {
svgNode.removeAttribute("dominant-baseline");
svgNode.setAttribute("dy", ".8em");
} }
svgNode.removeAttribute('transform'); svgNode.removeAttribute("transform");
return; return;
} }
} }
if (svgNode.children) { if (svgNode.children) {
for (var i = 0, l = svgNode.children.length; i < l; i++){ for (var i = 0, l = svgNode.children.length; i < l; i++) {
replaceWithNode(svgNode, svgNode.children[i], parentX, parentY) replaceWithNode(svgNode.children[i], parentX, parentY);
};
} }
} }
svgDom.style.display = 'none';
replaceWithNode(null, svgDom, 0, 0);
svgDom.style.display = 'inline';
} }
svgDom.style.display = "none";
data.registerProtocol('svg', module.exports = { replaceWithNode(svgDom, x || 0, y || 0);
fileDescription: 'SVG 矢量图', svgDom.style.display = "inline";
fileExtension: '.svg', }
mineType: 'image/svg+xml', data.registerProtocol("svg", module.exports = {
dataType: 'text', fileDescription: "SVG 矢量图",
fileExtension: ".svg",
mineType: "image/svg+xml",
dataType: "text",
encode: function(json, minder) { 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;
var paper = minder.getPaper(), paper.shapeNode.setAttribute("transform", "translate(0.5, 0.5)");
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; svgXml = paper.container.innerHTML;
paper.shapeNode.setAttribute('transform', paperTransform); paper.shapeNode.setAttribute("transform", paperTransform);
svgContainer = document.createElement("div");
svgContainer = document.createElement('div');
svgContainer.innerHTML = svgXml; svgContainer.innerHTML = svgXml;
svgDom = svgContainer.querySelector("svg");
svgDom = svgContainer.querySelector('svg'); svgDom.setAttribute("width", width + padding * 2 | 0);
svgDom.setAttribute('width', width + padding * 2 | 0); svgDom.setAttribute("height", height + 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('style', svgDom.setAttribute("viewBox", [ 0, 0, width + padding * 2 | 0, height + padding * 2 | 0 ].join(" "));
'font-family: Arial, Microsoft Yahei, Heiti SC; ' + svgContainer = document.createElement("div");
'background: ' + minder.getStyle('background')); cleanSVG(svgDom, renderBox.x - padding | 0, renderBox.y - padding | 0);
svgDom.setAttribute('viewBox', [
renderBox.x - padding | 0,
renderBox.y - padding | 0,
width + padding * 2 | 0,
height + padding * 2 | 0
].join(' '));
svgContainer = document.createElement('div');
removeTransform(svgDom);
svgContainer.appendChild(svgDom); svgContainer.appendChild(svgDom);
// need a xml with width and height // need a xml with width and height
svgXml = svgContainer.innerHTML; svgXml = svgContainer.innerHTML;
// svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
svgXml = svgXml.replace(/&nbsp;/g, '&#xa0;'); svgXml = svgXml.replace(/&nbsp;/g, "&#xa0;");
// svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined // svg 含有 &nbsp; 符号导出报错 Entity 'nbsp' not defined
return svgXml; return svgXml;
} }
}); });
}
}); });
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment