2012-11-02 20:47:14 -04:00
|
|
|
/*
|
2012-09-30 17:51:50 -04:00
|
|
|
* Paper.js
|
|
|
|
*
|
|
|
|
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
|
|
|
|
* based on Scriptographer.org and designed to be largely API compatible.
|
|
|
|
* http://paperjs.org/
|
|
|
|
* http://scriptographer.org/
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
|
|
|
*
|
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* The base for this code was donated by Stetson-Team-Alpha.
|
2012-09-30 17:51:50 -04:00
|
|
|
* @author Stetson-Team-Alpha
|
2012-09-13 20:45:27 -04:00
|
|
|
*/
|
|
|
|
|
2012-09-30 17:51:50 -04:00
|
|
|
/**
|
2012-11-02 20:47:14 -04:00
|
|
|
* @name SvgExporter
|
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* @class The SvgExporter object holds all the functionality to convert a
|
|
|
|
* Paper.js DOM to a SVG DOM.
|
2012-11-02 20:47:14 -04:00
|
|
|
*/
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-04 01:43:45 -05:00
|
|
|
var SvgExporter = this.SvgExporter = new function() {
|
2012-10-24 23:21:59 -04:00
|
|
|
|
2012-11-04 01:43:45 -05:00
|
|
|
function createElement(tag) {
|
2012-10-24 23:21:59 -04:00
|
|
|
return document.createElementNS('http://www.w3.org/2000/svg', tag);
|
2012-11-04 01:43:45 -05:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-04 01:43:45 -05:00
|
|
|
function exportGroup(group) {
|
|
|
|
var svg = createElement('g'),
|
2012-11-02 19:51:42 -04:00
|
|
|
children = group._children;
|
2012-11-04 01:43:45 -05:00
|
|
|
for (var i = 0, l = children.length; i < l; i++)
|
|
|
|
svg.appendChild(SvgExporter.exportItem(children[i]));
|
2012-11-02 19:51:42 -04:00
|
|
|
return svg;
|
2012-11-04 01:43:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
function exportItem(path) {
|
2012-11-02 19:51:42 -04:00
|
|
|
var svg;
|
2012-09-30 17:51:50 -04:00
|
|
|
//Getting all of the segments(a point, a HandleIn and a HandleOut) in the path
|
|
|
|
var segArray;
|
|
|
|
var pointArray;
|
|
|
|
var handleInArray;
|
|
|
|
var handleOutArray;
|
2012-10-22 19:31:08 -04:00
|
|
|
var type;
|
2012-09-30 17:51:50 -04:00
|
|
|
//finding the type of path to export
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.content) {
|
2012-09-30 17:51:50 -04:00
|
|
|
type = 'text';
|
|
|
|
} else {
|
|
|
|
//Values are only defined if the path is not text because
|
|
|
|
// text does not have these values
|
|
|
|
segArray = path.getSegments();
|
2012-10-22 19:31:08 -04:00
|
|
|
pointArray = [];
|
|
|
|
handleInArray = [];
|
|
|
|
handleOutArray = [];
|
2012-11-02 21:22:38 -04:00
|
|
|
for (var i = 0; i < segArray.length; i++) {
|
2012-09-30 17:51:50 -04:00
|
|
|
pointArray[i] = segArray[i].getPoint();
|
|
|
|
handleInArray[i] = segArray[i].getHandleIn();
|
|
|
|
handleOutArray[i] = segArray[i].getHandleOut();
|
|
|
|
}
|
2012-11-04 01:43:45 -05:00
|
|
|
type = determineType(path, segArray, pointArray, handleInArray, handleOutArray);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//switch statement that determines what type of SVG element to add to the SVG Object
|
|
|
|
switch (type) {
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'rect':
|
2012-11-02 19:51:42 -04:00
|
|
|
var width = pointArray[0].getDistance(pointArray[3]);
|
|
|
|
var height = pointArray[0].getDistance(pointArray[1]);
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('rect');
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('x', path.bounds.topLeft.getX());
|
|
|
|
svg.setAttribute('y', path.bounds.topLeft.getY());
|
|
|
|
svg.setAttribute('width', width);
|
|
|
|
svg.setAttribute('height', height);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
2012-11-02 21:23:23 -04:00
|
|
|
case 'roundrect':
|
2012-10-22 19:31:08 -04:00
|
|
|
//d variables and point are used to determine the rounded corners for the rounded rectangle
|
2012-11-02 19:51:42 -04:00
|
|
|
var dx1 = pointArray[1].getDistance(pointArray[6]);
|
|
|
|
var dx2 = pointArray[0].getDistance(pointArray[7]);
|
2012-10-22 19:31:08 -04:00
|
|
|
var dx3 = (dx1 - dx2) / 2;
|
2012-11-02 19:51:42 -04:00
|
|
|
var dy1 = pointArray[0].getDistance(pointArray[3]);
|
|
|
|
var dy2 = pointArray[1].getDistance(pointArray[2]);
|
2012-10-22 19:31:08 -04:00
|
|
|
var dy3 = (dy1 - dy2) / 2;
|
|
|
|
var point = new Point((pointArray[3].getX() - dx3), (pointArray[2].getY() - dy3));
|
|
|
|
var width = Math.round(dx1);
|
|
|
|
var height = Math.round(dy1);
|
|
|
|
var rx = pointArray[3].getX() - point.x;
|
|
|
|
var ry = pointArray[2].getY() - point.y;
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('rect');
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('x', path.bounds.topLeft.getX());
|
|
|
|
svg.setAttribute('y', path.bounds.topLeft.getY());
|
|
|
|
svg.setAttribute('rx', rx);
|
|
|
|
svg.setAttribute('ry', ry);
|
|
|
|
svg.setAttribute('width', width);
|
|
|
|
svg.setAttribute('height', height);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case'line':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('line');
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('x1', pointArray[0].getX());
|
|
|
|
svg.setAttribute('y1', pointArray[0].getY());
|
|
|
|
svg.setAttribute('x2', pointArray[pointArray.length - 1].getX());
|
|
|
|
svg.setAttribute('y2', pointArray[pointArray.length - 1].getY());
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case 'circle':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('circle');
|
2012-11-02 21:23:23 -04:00
|
|
|
var radius = (pointArray[0].getDistance(pointArray[2])) /2;
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('cx', path.bounds.center.x);
|
|
|
|
svg.setAttribute('cy', path.bounds.center.y);
|
|
|
|
svg.setAttribute('r', radius);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case 'ellipse':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('ellipse');
|
2012-11-02 21:23:23 -04:00
|
|
|
var radiusX = pointArray[2].getDistance(pointArray[0]) / 2;
|
|
|
|
var radiusY = pointArray[3].getDistance(pointArray[1]) /2;
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('cx', path.bounds.center.x);
|
|
|
|
svg.setAttribute('cy', path.bounds.center.y);
|
|
|
|
svg.setAttribute('rx', radiusX);
|
|
|
|
svg.setAttribute('ry', radiusY);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case 'polyline':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('polyline');
|
2012-10-22 19:31:08 -04:00
|
|
|
var pointString = '';
|
2012-11-02 21:22:38 -04:00
|
|
|
for(var i = 0; i < pointArray.length; i++) {
|
2012-10-22 19:31:08 -04:00
|
|
|
pointString += pointArray[i].getX() + ',' + pointArray[i].getY() + ' ';
|
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('points', pointString);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case 'polygon':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('polygon');
|
2012-10-22 19:31:08 -04:00
|
|
|
var pointString = '';
|
2012-11-02 21:22:38 -04:00
|
|
|
for(i = 0; i < pointArray.length; i++) {
|
2012-10-22 19:31:08 -04:00
|
|
|
pointString += pointArray[i].getX() + ',' + pointArray[i].getY() + ' ';
|
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('points', pointString);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
case 'text':
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('text');
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('x', path.getPoint().getX());
|
|
|
|
svg.setAttribute('y', path.getPoint().getY());
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.style.font != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('font', path.style.font);
|
2012-10-22 19:31:08 -04:00
|
|
|
}
|
|
|
|
if (path.characterStyle.font != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('font-family', path.characterStyle.font);
|
2012-10-22 19:31:08 -04:00
|
|
|
}
|
|
|
|
if (path.characterStyle.fontSize != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('font-size',path.characterStyle.fontSize);
|
2012-10-22 19:31:08 -04:00
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.textContent = path.getContent();
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
|
|
|
default:
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('path');
|
|
|
|
svg = pathSetup(path, pointArray, handleInArray, handleOutArray);
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//If the object is a circle, ellipse, rectangle, or rounded rectangle, it will find the angle
|
2012-09-30 21:11:00 -04:00
|
|
|
//found by the determineIfTransformed method and make a path that accommodates for the transformed object
|
2012-10-22 19:31:08 -04:00
|
|
|
if (type != 'text' && type != undefined && type != 'polygon' && type != 'polyline' && type != 'line') {
|
2012-09-30 18:05:21 -04:00
|
|
|
//TODO: Need to implement exported transforms for circle, ellipse, and rectangles instead of
|
|
|
|
//making them paths
|
2012-11-04 01:43:45 -05:00
|
|
|
var angle = determineIfTransformed(path, pointArray, type) + 90;
|
2012-10-22 19:31:08 -04:00
|
|
|
if (angle != 0) {
|
2012-11-02 21:23:23 -04:00
|
|
|
if (type == 'rect' || type == 'roundrect') {
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('path');
|
|
|
|
svg = pathSetup(path, pointArray, handleInArray, handleOutArray);
|
2012-09-30 17:51:50 -04:00
|
|
|
} else {
|
2012-11-04 01:43:45 -05:00
|
|
|
svg = createElement('path');
|
|
|
|
svg = pathSetup(path, pointArray, handleInArray, handleOutArray);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-10-22 19:31:08 -04:00
|
|
|
if (type == 'text') {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('transform','rotate(' + path.matrix.getRotation() + ',' + path.getPoint().getX() + ',' +path.getPoint().getY() +')');
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.id != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('id', path.id);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//checks if there is a stroke color in the passed in path
|
|
|
|
//adds an SVG element attribute with the defined stroke color
|
|
|
|
if (path.strokeColor != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke', path.strokeColor.toCssString());
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as above except checking for a fill color
|
|
|
|
if (path.fillColor != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('fill', path.fillColor.toCssString());
|
2012-09-30 17:51:50 -04:00
|
|
|
} else {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('fill', 'rgba(0,0,0,0)');
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with stroke width
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.strokeWidth != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-width', path.strokeWidth);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the path name
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.name != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('name', path.name);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the strokeCap
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.strokeCap != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-linecap', path.strokeCap);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the strokeJoin
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.strokeJoin != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-linejoin', path.strokeJoin);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the opacity
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.opacity != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('opacity', path.opacity);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//checks to see if there the dashArray is set, then adds the attribute if there is.
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.dashArray[0] != undefined) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var dashVals = '';
|
2012-11-02 19:51:42 -04:00
|
|
|
for (var i = 0, l = path.dashArray.length; i < l; i++) {
|
2012-10-22 19:31:08 -04:00
|
|
|
if (i != path.dashArray.length -1) {
|
2012-09-30 17:51:50 -04:00
|
|
|
dashVals += path.dashArray[i] + ", ";
|
|
|
|
} else {
|
|
|
|
dashVals += path.dashArray[i];
|
|
|
|
}
|
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-dasharray', dashVals);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the dash offset
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.dashOffset != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-dashoffset', path.dashOffset);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the miter limit
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.miterLimit != undefined) {
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('stroke-miterlimit', path.miterLimit);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
//same thing as stroke color except with the visibility
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.visibility != undefined) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var visString = '';
|
2012-10-22 19:31:08 -04:00
|
|
|
if (path.visibility) {
|
2012-09-30 17:51:50 -04:00
|
|
|
visString = 'visible';
|
|
|
|
} else {
|
|
|
|
visString = 'hidden';
|
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
svg.setAttribute('visibility', visString);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 19:51:42 -04:00
|
|
|
return svg;
|
2012-11-04 01:43:45 -05:00
|
|
|
}
|
|
|
|
var exporters = {
|
|
|
|
group: exportGroup,
|
|
|
|
layer: exportGroup,
|
|
|
|
path: exportItem,
|
|
|
|
pointtext: exportItem
|
|
|
|
// TODO:
|
|
|
|
// raster:
|
|
|
|
// placedsymbol:
|
|
|
|
// compoundpath:
|
|
|
|
};
|
2012-09-13 20:45:27 -04:00
|
|
|
|
2012-11-04 01:43:45 -05:00
|
|
|
// Determines whether the object has been transformed or not through finding the angle
|
|
|
|
function determineIfTransformed(path, pointArray, type) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var topMidBoundx = (path.bounds.topRight.getX() + path.bounds.topLeft.getX() )/2;
|
|
|
|
var topMidBoundy = (path.bounds.topRight.getY() + path.bounds.topLeft.getY() )/2;
|
|
|
|
var topMidBound = new Point(topMidBoundx, topMidBoundy);
|
|
|
|
var centerPoint = path.getPosition();
|
|
|
|
var topMidPathx;
|
|
|
|
var topMidPathy;
|
|
|
|
var topMidPath;
|
|
|
|
switch (type) {
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'rect':
|
|
|
|
topMidPathx = (pointArray[1].getX() + pointArray[2].getX() )/2;
|
|
|
|
topMidPathy = (pointArray[1].getY() + pointArray[2].getY() )/2;
|
|
|
|
topMidPath = new Point(topMidPathx, topMidPathy);
|
|
|
|
break;
|
|
|
|
case 'ellipse':
|
|
|
|
topMidPath = new Point(pointArray[1].getX(), pointArray[1].getY());
|
|
|
|
break;
|
|
|
|
case 'circle':
|
|
|
|
topMidPath = new Point(pointArray[1].getX(), pointArray[1].getY());
|
|
|
|
break;
|
2012-11-02 21:23:23 -04:00
|
|
|
case 'roundrect':
|
2012-10-22 19:31:08 -04:00
|
|
|
topMidPathx = (pointArray[3].getX() + pointArray[4].getX())/2;
|
|
|
|
topMidPathy = (pointArray[3].getY() + pointArray[4].getY())/2;
|
|
|
|
topMidPath = new Point(topMidPathx, topMidPathy);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
//Nothing happens here
|
|
|
|
break;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
var deltaY = topMidPath.y - centerPoint.getY();
|
|
|
|
var deltaX = topMidPath.x - centerPoint.getX();
|
|
|
|
var angleInDegrees = Math.atan2(deltaY, deltaX) * 180 / Math.PI;
|
|
|
|
return angleInDegrees;
|
2012-11-04 01:43:45 -05:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-04 01:43:45 -05:00
|
|
|
function pathSetup(path, pointArray, hIArray, hOArray) {
|
|
|
|
var svgPath = createElement('path');
|
2012-09-30 17:51:50 -04:00
|
|
|
var pointString = '';
|
|
|
|
var x1;
|
|
|
|
var x2;
|
|
|
|
var y1;
|
|
|
|
var y2;
|
|
|
|
var handleOut1;
|
|
|
|
var handleIn2;
|
2012-11-02 21:23:37 -04:00
|
|
|
// pointstring is formatted in the way the SVG XML will be reading.
|
|
|
|
// Namely, a point and the way to traverse to that point.
|
2012-09-30 17:51:50 -04:00
|
|
|
pointString += 'M' + pointArray[0].getX() + ',' + pointArray[0].getY() + ' ';
|
|
|
|
//Checks 2 points and the angles in between the 2 points
|
|
|
|
for (i = 0; i < pointArray.length-1; i++) {
|
|
|
|
x1 = pointArray[i].getX();
|
|
|
|
y1 = pointArray[i].getY();
|
|
|
|
x2 = pointArray[i + 1].getX();
|
|
|
|
y2 = pointArray[i + 1].getY();
|
|
|
|
handleOut1 = hOArray[i];
|
|
|
|
handleIn2 = hIArray[i+1];
|
2012-10-27 22:25:52 -04:00
|
|
|
if (handleOut1.getX() == 0 && handleOut1.getY() == 0 && handleIn2.getX() == 0 && handleIn2.getY() == 0) {
|
2012-11-02 21:23:37 -04:00
|
|
|
// L is lineto, moving to a point with drawing
|
2012-09-30 17:51:50 -04:00
|
|
|
pointString+= 'L' + x2 + ',' + y2 + ' ';
|
|
|
|
} else {
|
2012-11-02 21:23:37 -04:00
|
|
|
// c is curveto, relative: handleOut, handleIn - endpoint, endpoint - startpoint
|
2012-09-30 17:51:50 -04:00
|
|
|
pointString+= 'c' + (handleOut1.getX()) + ',' + (handleOut1.getY()) + ' ';
|
|
|
|
pointString+= (x2 - x1 + handleIn2.getX()) + ',' + (y2 - y1 + handleIn2.getY()) + ' ';
|
|
|
|
pointString+= (x2 - x1) + ',' + (y2-y1) + ' ';
|
|
|
|
}
|
|
|
|
}
|
2012-10-27 22:25:52 -04:00
|
|
|
if (!hOArray[hOArray.length - 1].equals([0, 0]) && !hIArray[0].equals([0, 0])) {
|
2012-09-30 17:51:50 -04:00
|
|
|
handleOut1 = hOArray[hOArray.length - 1];
|
|
|
|
handleIn2 = hIArray[0];
|
|
|
|
// Bezier curve from last point to first
|
|
|
|
x1 = pointArray[pointArray.length - 1].getX();
|
|
|
|
y1 = pointArray[pointArray.length - 1].getY();
|
|
|
|
x2 = pointArray[0].getX();
|
|
|
|
y2 = pointArray[0].getY();
|
|
|
|
pointString+= 'c' + (handleOut1.getX()) + ',' + (handleOut1.getY()) + ' ';
|
|
|
|
pointString+= (x2 - x1 + handleIn2.getX()) + ',' + (y2 - y1 + handleIn2.getY()) + ' ';
|
|
|
|
pointString+= (x2 - x1) + ',' + (y2-y1) + ' ';
|
|
|
|
}
|
2012-11-02 21:23:37 -04:00
|
|
|
if (path._closed) {
|
|
|
|
// z implies a closed path, connecting the first and last points
|
2012-09-30 17:51:50 -04:00
|
|
|
pointString += 'z';
|
|
|
|
}
|
2012-11-02 21:23:37 -04:00
|
|
|
svgPath.setAttribute('d', pointString);
|
2012-09-30 17:51:50 -04:00
|
|
|
return svgPath;
|
2012-11-04 01:43:45 -05:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks the type SVG object created by converting from Paper.js
|
|
|
|
*/
|
2012-11-04 01:43:45 -05:00
|
|
|
function determineType(path, segArray, pointArray, handleInArray, handleOutArray) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var type;
|
|
|
|
var dPoint12;
|
|
|
|
var dPoint34;
|
2012-11-02 21:22:01 -04:00
|
|
|
var straight = true;
|
2012-09-30 17:51:50 -04:00
|
|
|
var segHandleIn;
|
|
|
|
var segHandleOut;
|
2012-11-02 21:22:01 -04:00
|
|
|
// See if actually have any curves in the path. Differentiate
|
|
|
|
// between straight objects (line, polyline, rect, and polygon) and
|
|
|
|
// objects with curves(circle, ellipse, roundedRectangle).
|
|
|
|
for( var i = 0, l = segArray.length; i < l && straight; i++) {
|
2012-09-30 17:51:50 -04:00
|
|
|
segHandleIn = segArray[i].getHandleIn();
|
|
|
|
segHandleOut = segArray[i].getHandleOut();
|
2012-11-02 21:22:01 -04:00
|
|
|
if (!segHandleIn.isZero() || !segHandleOut.isZero())
|
|
|
|
straight = false;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:22:01 -04:00
|
|
|
// Checks if the type of the passed in path is a rounded rectangle, an
|
|
|
|
// ellipse, a circle, or if it's simply a path.
|
|
|
|
// If there aren't any curves (straight == true), then check if the type
|
|
|
|
// is a rectangle, a polygon, a polyline, or simply a line.
|
|
|
|
if (straight) {
|
|
|
|
if (segArray.length == 4) {
|
|
|
|
// If the distance between (point0 and point1) and (point2 and
|
|
|
|
// point3) are equal, then it is a rectangle
|
|
|
|
dPoint12 = Math.round(pointArray[0].getDistance(pointArray[1]));
|
|
|
|
dPoint34 = Math.round(pointArray[3].getDistance(pointArray[2]));
|
|
|
|
if (dPoint12 == dPoint34) {
|
|
|
|
type = 'rect';
|
|
|
|
}
|
|
|
|
} else if (segArray.length >= 3) {
|
|
|
|
//If it is an object with more than 3 segments and the path is closed, it is a polygon
|
|
|
|
if (path.getClosed()) {
|
|
|
|
type = 'polygon';
|
|
|
|
} else {
|
|
|
|
type = 'polyline';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//if all of the handle values are == 0 and there are only 2 segments, it is a line
|
|
|
|
type = 'line';
|
|
|
|
}
|
|
|
|
} else {
|
2012-10-22 19:31:08 -04:00
|
|
|
if (segArray.length == 8) {
|
2012-11-02 21:22:01 -04:00
|
|
|
// If the distance between (point0 and point3) and (point7 and
|
|
|
|
// point4) are equal then it is a roundedRectangle
|
|
|
|
dPoint12 = Math.round(pointArray[0].getDistance(pointArray[3]));
|
|
|
|
dPoint34 = Math.round(pointArray[7].getDistance(pointArray[4]));
|
2012-10-22 19:31:08 -04:00
|
|
|
if (dPoint12 == dPoint34) {
|
2012-11-02 21:22:01 -04:00
|
|
|
type = 'roundrect';
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-10-22 19:31:08 -04:00
|
|
|
} else if (segArray.length == 4) {
|
2012-11-02 21:22:01 -04:00
|
|
|
// Check if the values of the point have values similar to
|
|
|
|
// circles and ellipses.
|
2012-09-30 17:51:50 -04:00
|
|
|
var checkPointValues = true;
|
2012-11-02 21:22:01 -04:00
|
|
|
for (i = 0; i < pointArray.length && checkPointValues; i++) {
|
|
|
|
if (handleInArray[i].getX() != 0 || handleInArray[i].getY() != 0
|
|
|
|
&& Math.round(Math.abs(handleInArray[i].getX())) === Math.round(Math.abs(handleOutArray[i].getX()))
|
|
|
|
&& Math.round(Math.abs(handleInArray[i].getY())) === Math.round(Math.abs(handleOutArray[i].getY()))) {
|
2012-09-30 17:51:50 -04:00
|
|
|
checkPointValues = true;
|
|
|
|
} else {
|
|
|
|
checkPointValues = false;
|
|
|
|
}
|
|
|
|
}
|
2012-11-02 21:22:01 -04:00
|
|
|
if (checkPointValues) {
|
|
|
|
// If the distance between (point0 and point2) and (point1
|
|
|
|
// and point3) are equal, then it is a circle
|
|
|
|
var d1 = Math.round(pointArray[0].getDistance(pointArray[2]));
|
|
|
|
var d2 = Math.round(pointArray[1].getDistance(pointArray[3]));
|
2012-10-22 19:31:08 -04:00
|
|
|
if (d1 == d2) {
|
2012-09-30 17:51:50 -04:00
|
|
|
type = 'circle';
|
|
|
|
} else {
|
|
|
|
type = 'ellipse';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return type;
|
|
|
|
}
|
2012-11-04 01:43:45 -05:00
|
|
|
|
|
|
|
return /** @Lends SvgExporter */{
|
|
|
|
/**
|
|
|
|
* Takes the selected Paper.js project and parses all of its layers and
|
|
|
|
* groups to be placed into SVG groups, converting the project into one
|
|
|
|
* SVG group.
|
|
|
|
*
|
|
|
|
* @function
|
|
|
|
* @param {Project} project a Paper.js project
|
|
|
|
* @return {SVGSVGElement} the imported project converted to an SVG project
|
|
|
|
*/
|
|
|
|
// TODO: Implement symbols and Gradients
|
|
|
|
exportProject: function(project) {
|
|
|
|
var svg = createElement('svg'),
|
|
|
|
layers = project.layers;
|
|
|
|
for (var i = 0, l = layers.length; i < l; i++) {
|
|
|
|
svg.appendChild(this.exportItem(layers[i]));
|
|
|
|
}
|
|
|
|
return svg;
|
|
|
|
},
|
|
|
|
|
|
|
|
exportItem: function(item) {
|
|
|
|
var exporter = exporters[item._type];
|
|
|
|
// TODO: exporter == null: Not supported yet.
|
|
|
|
var svg = exporter && exporter(item);
|
|
|
|
return svg;
|
|
|
|
}
|
|
|
|
};
|
2012-11-02 19:19:45 -04:00
|
|
|
};
|