Handle view size and transformation correctly when exporting SVG.

Closes #277.
This commit is contained in:
Jürg Lehni 2014-05-14 13:29:20 +02:00
parent aac98f2b25
commit f38d3ee674

View file

@ -38,8 +38,9 @@ new function() {
document.createElementNS('http://www.w3.org/2000/svg', tag), attrs); document.createElementNS('http://www.w3.org/2000/svg', tag), attrs);
} }
function getTransform(item, attrs, coordinates, center) { function getTransform(matrix, coordinates, center) {
var matrix = item._matrix, // Use new Base() so we can use Base#set() on it.
var attrs = new Base(),
trans = matrix.getTranslation(); trans = matrix.getTranslation();
if (coordinates) { if (coordinates) {
// If the item suppports x- and y- coordinates, we're taking out the // If the item suppports x- and y- coordinates, we're taking out the
@ -78,7 +79,7 @@ new function() {
} }
function exportGroup(item, options) { function exportGroup(item, options) {
var attrs = getTransform(item, {}), var attrs = getTransform(item._matrix),
children = item._children; children = item._children;
var node = createElement('g', attrs); var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) { for (var i = 0, l = children.length; i < l; i++) {
@ -101,7 +102,7 @@ new function() {
} }
function exportRaster(item) { function exportRaster(item) {
var attrs = getTransform(item, {}, true), var attrs = getTransform(item._matrix, true),
size = item.getSize(); size = item.getSize();
// Take into account that rasters are centered: // Take into account that rasters are centered:
attrs.x -= size.width / 2; attrs.x -= size.width / 2;
@ -120,7 +121,7 @@ new function() {
} }
var segments = item._segments, var segments = item._segments,
type, type,
attrs; attrs = getTransform(item._matrix);
if (segments.length === 0) if (segments.length === 0)
return null; return null;
if (item.isPolygon()) { if (item.isPolygon()) {
@ -129,32 +130,29 @@ new function() {
var parts = []; var parts = [];
for(i = 0, l = segments.length; i < l; i++) for(i = 0, l = segments.length; i < l; i++)
parts.push(formatter.point(segments[i]._point)); parts.push(formatter.point(segments[i]._point));
attrs = { attrs.points = parts.join(' ');
points: parts.join(' ')
};
} else { } else {
type = 'line'; type = 'line';
var first = segments[0]._point, var first = segments[0]._point,
last = segments[segments.length - 1]._point; last = segments[segments.length - 1]._point;
attrs = { attrs.set({
x1: first.x, x1: first.x,
y1: first.y, y1: first.y,
x2: last.x, x2: last.x,
y2: last.y y2: last.y
}; });
} }
} else { } else {
type = 'path'; type = 'path';
var data = item.getPathData(null, options.precision); attrs.d = item.getPathData(null, options.precision);
attrs = data && { d: data };
} }
return createElement(type, getTransform(item, attrs)); return createElement(type, attrs);
} }
function exportShape(item) { function exportShape(item) {
var type = item._type, var type = item._type,
radius = item._radius, radius = item._radius,
attrs = getTransform(item, {}, true, type !== 'rectangle'); attrs = getTransform(item._matrix, true, type !== 'rectangle');
if (type === 'rectangle') { if (type === 'rectangle') {
type = 'rect'; // SVG type = 'rect'; // SVG
var size = item._size, var size = item._size,
@ -179,7 +177,7 @@ new function() {
} }
function exportCompoundPath(item, options) { function exportCompoundPath(item, options) {
var attrs = getTransform(item, {}); var attrs = getTransform(item._matrix);
var data = item.getPathData(null, options.precision); var data = item.getPathData(null, options.precision);
if (data) if (data)
attrs.d = data; attrs.d = data;
@ -187,7 +185,7 @@ new function() {
} }
function exportPlacedSymbol(item, options) { function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, {}, true), var attrs = getTransform(item._matrix, true),
symbol = item.getSymbol(), symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'), symbolNode = getDefinition(symbol, 'symbol'),
definition = symbol.getDefinition(), definition = symbol.getDefinition(),
@ -264,7 +262,7 @@ new function() {
} }
function exportText(item) { function exportText(item) {
var node = createElement('text', getTransform(item, {}, true)); var node = createElement('text', getTransform(item._matrix, true));
node.textContent = item._content; node.textContent = item._content;
return node; return node;
} }
@ -413,7 +411,8 @@ new function() {
exportSVG: function(options) { exportSVG: function(options) {
options = setOptions(options); options = setOptions(options);
var layers = this.layers, var layers = this.layers,
size = this.getView().getSize(), view = this.getView(),
size = view.getViewSize(),
node = createElement('svg', { node = createElement('svg', {
x: 0, x: 0,
y: 0, y: 0,
@ -422,7 +421,13 @@ new function() {
version: '1.1', version: '1.1',
xmlns: 'http://www.w3.org/2000/svg', xmlns: 'http://www.w3.org/2000/svg',
'xmlns:xlink': 'http://www.w3.org/1999/xlink' 'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}); }),
matrix = view._matrix;
// If the view has a transformation, wrap all layers in a group with
// that transformation applied to.
if (!matrix.isIdentity())
node = node.appendChild(
createElement('g', getTransform(matrix)));
for (var i = 0, l = layers.length; i < l; i++) for (var i = 0, l = layers.length; i < l; i++)
node.appendChild(exportSVG(layers[i], options)); node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options); return exportDefinitions(node, options);