|
@@ -58,6 +58,26 @@ THREE.SVGLoader.prototype = {
|
|
|
paths.push( parseRectNode( node ) );
|
|
|
break;
|
|
|
|
|
|
+ case 'polygon':
|
|
|
+ paths.push( parsePolygonNode( node ) );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'polyline':
|
|
|
+ paths.push( parsePolylineNode( node ) );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'circle':
|
|
|
+ paths.push( parseCircleNode( node ) );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'ellipse':
|
|
|
+ paths.push( parseEllipseNode( node ) );
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'line':
|
|
|
+ paths.push( parseLineNode( node ) );
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
console.log( node );
|
|
|
|
|
@@ -71,6 +91,7 @@ THREE.SVGLoader.prototype = {
|
|
|
|
|
|
var path = new THREE.ShapePath();
|
|
|
var point = new THREE.Vector2();
|
|
|
+ var control = new THREE.Vector2();
|
|
|
|
|
|
var d = node.getAttribute( 'd' );
|
|
|
|
|
@@ -90,18 +111,24 @@ THREE.SVGLoader.prototype = {
|
|
|
case 'M':
|
|
|
var numbers = parseFloats( data );
|
|
|
point.fromArray( numbers );
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.moveTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
|
case 'H':
|
|
|
var numbers = parseFloats( data );
|
|
|
point.x = numbers[ 0 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
|
case 'V':
|
|
|
var numbers = parseFloats( data );
|
|
|
point.y = numbers[ 0 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
@@ -109,6 +136,8 @@ THREE.SVGLoader.prototype = {
|
|
|
var numbers = parseFloats( data );
|
|
|
point.x = numbers[ 0 ];
|
|
|
point.y = numbers[ 1 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
@@ -122,19 +151,84 @@ THREE.SVGLoader.prototype = {
|
|
|
numbers[ 4 ],
|
|
|
numbers[ 5 ],
|
|
|
);
|
|
|
+ control.x = numbers[ 2 ];
|
|
|
+ control.y = numbers[ 3 ];
|
|
|
point.x = numbers[ 4 ];
|
|
|
point.y = numbers[ 5 ];
|
|
|
break;
|
|
|
|
|
|
+ case 'S':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ path.bezierCurveTo(
|
|
|
+ getReflection( point.x, control.x ),
|
|
|
+ getReflection( point.y, control.y ),
|
|
|
+ numbers[ 0 ],
|
|
|
+ numbers[ 1 ],
|
|
|
+ numbers[ 2 ],
|
|
|
+ numbers[ 3 ]
|
|
|
+ );
|
|
|
+ control.x = numbers[ 0 ];
|
|
|
+ control.y = numbers[ 1 ];
|
|
|
+ point.x = numbers[ 2 ];
|
|
|
+ point.y = numbers[ 3 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'Q':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ path.quadraticCurveTo(
|
|
|
+ numbers[ 0 ],
|
|
|
+ numbers[ 1 ],
|
|
|
+ numbers[ 2 ],
|
|
|
+ numbers[ 3 ]
|
|
|
+ );
|
|
|
+ control.x = numbers[ 0 ];
|
|
|
+ control.y = numbers[ 1 ];
|
|
|
+ point.x = numbers[ 2 ];
|
|
|
+ point.y = numbers[ 3 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'T':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ var rx = getReflection( point.x, control.x );
|
|
|
+ var ry = getReflection( point.y, control.y );
|
|
|
+ path.quadraticCurveTo(
|
|
|
+ rx,
|
|
|
+ ry,
|
|
|
+ numbers[ 0 ],
|
|
|
+ numbers[ 1 ]
|
|
|
+ );
|
|
|
+ control.x = rx;
|
|
|
+ control.y = ry;
|
|
|
+ point.x = numbers[ 0 ];
|
|
|
+ point.y = numbers[ 1 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'A':
|
|
|
+ // TODO:
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'm':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ point.x += numbers[ 0 ];
|
|
|
+ point.y += numbers[ 1 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
+ path.moveTo( point.x, point.y );
|
|
|
+ break;
|
|
|
+
|
|
|
case 'h':
|
|
|
var numbers = parseFloats( data );
|
|
|
point.x += numbers[ 0 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
|
case 'v':
|
|
|
var numbers = parseFloats( data );
|
|
|
point.y += numbers[ 0 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
@@ -142,6 +236,8 @@ THREE.SVGLoader.prototype = {
|
|
|
var numbers = parseFloats( data );
|
|
|
point.x += numbers[ 0 ];
|
|
|
point.y += numbers[ 1 ];
|
|
|
+ control.x = point.x;
|
|
|
+ control.y = point.y;
|
|
|
path.lineTo( point.x, point.y );
|
|
|
break;
|
|
|
|
|
@@ -159,6 +255,58 @@ THREE.SVGLoader.prototype = {
|
|
|
point.y += numbers[ 5 ];
|
|
|
break;
|
|
|
|
|
|
+ case 's':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ path.bezierCurveTo(
|
|
|
+ // TODO: Not sure if point needs
|
|
|
+ // to be added to reflection...
|
|
|
+ getReflection( point.x, control.x ),
|
|
|
+ getReflection( point.y, control.y ),
|
|
|
+ point.x + numbers[ 0 ],
|
|
|
+ point.y + numbers[ 1 ],
|
|
|
+ point.x + numbers[ 2 ],
|
|
|
+ point.y + numbers[ 3 ]
|
|
|
+ );
|
|
|
+ control.x = point.x + numbers[ 0 ];
|
|
|
+ control.y = point.y + numbers[ 1 ];
|
|
|
+ point.x += numbers[ 2 ];
|
|
|
+ point.y += numbers[ 3 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'q':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ path.quadraticCurveTo(
|
|
|
+ point.x + numbers[ 0 ],
|
|
|
+ point.y + numbers[ 1 ],
|
|
|
+ point.x + numbers[ 2 ],
|
|
|
+ point.y + numbers[ 3 ]
|
|
|
+ );
|
|
|
+ control.x = point.x + numbers[ 0 ];
|
|
|
+ control.y = point.y + numbers[ 1 ];
|
|
|
+ point.x += numbers[ 2 ];
|
|
|
+ point.y += numbers[ 3 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 't':
|
|
|
+ var numbers = parseFloats( data );
|
|
|
+ var rx = getReflection( point.x, control.x );
|
|
|
+ var ry = getReflection( point.y, control.y );
|
|
|
+ path.quadraticCurveTo(
|
|
|
+ rx,
|
|
|
+ ry,
|
|
|
+ point.x + numbers[ 0 ],
|
|
|
+ point.y + numbers[ 1 ]
|
|
|
+ );
|
|
|
+ control.x = rx;
|
|
|
+ control.y = ry;
|
|
|
+ point.x = point.x + numbers[ 0 ];
|
|
|
+ point.y = point.y + numbers[ 1 ];
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'a':
|
|
|
+ // TODO:
|
|
|
+ break;
|
|
|
+
|
|
|
case 'Z':
|
|
|
case 'z':
|
|
|
path.currentPath.autoClose = true;
|
|
@@ -191,6 +339,117 @@ THREE.SVGLoader.prototype = {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function parsePolygonNode( node ) {
|
|
|
+
|
|
|
+ function iterator( match, a, b ) {
|
|
|
+
|
|
|
+ var x = parseFloat( a );
|
|
|
+ var y = parseFloat( b );
|
|
|
+
|
|
|
+ if ( index === 0 ) {
|
|
|
+ path.moveTo( x, y );
|
|
|
+ } else {
|
|
|
+ path.lineTo( x, y );
|
|
|
+ }
|
|
|
+
|
|
|
+ index++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;
|
|
|
+ var path = new THREE.ShapePath();
|
|
|
+ var index = 0;
|
|
|
+
|
|
|
+ node.getAttribute( 'points' ).replace(regex, iterator);
|
|
|
+
|
|
|
+ path.currentPath.autoClose = true;
|
|
|
+
|
|
|
+ return path;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function parsePolylineNode( node ) {
|
|
|
+
|
|
|
+ function iterator( match, a, b ) {
|
|
|
+
|
|
|
+ var x = parseFloat( a );
|
|
|
+ var y = parseFloat( b );
|
|
|
+
|
|
|
+ if ( index === 0 ) {
|
|
|
+ path.moveTo( x, y );
|
|
|
+ } else {
|
|
|
+ path.lineTo( x, y );
|
|
|
+ }
|
|
|
+
|
|
|
+ index++;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ var regex = /(-?[\d\.?]+)[,|\s](-?[\d\.?]+)/g;
|
|
|
+ var path = new THREE.ShapePath();
|
|
|
+ var index = 0;
|
|
|
+
|
|
|
+ node.getAttribute( 'points' ).replace(regex, iterator);
|
|
|
+
|
|
|
+ path.currentPath.autoClose = false;
|
|
|
+
|
|
|
+ return path;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseCircleNode( node ) {
|
|
|
+
|
|
|
+ var x = parseFloat( node.getAttribute( 'cx' ) );
|
|
|
+ var y = parseFloat( node.getAttribute( 'cy' ) );
|
|
|
+ var r = parseFloat( node.getAttribute( 'r' ) );
|
|
|
+
|
|
|
+ var path = new THREE.ShapePath();
|
|
|
+
|
|
|
+ path.currentPath.absarc( x, y, r, 0, Math.PI * 2 );
|
|
|
+
|
|
|
+ return path;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseEllipseNode( node ) {
|
|
|
+
|
|
|
+ var x = parseFloat( node.getAttribute( 'cx' ) );
|
|
|
+ var y = parseFloat( node.getAttribute( 'cy' ) );
|
|
|
+ var rx parseFloat( node.getAttribute( 'rx' ) );
|
|
|
+ var ry = parseFloat( node.getAttribute( 'ry' ) );
|
|
|
+
|
|
|
+ var path = new THREE.ShapePath();
|
|
|
+
|
|
|
+ path.currentPath.absellipse( x, y, rx, ry, 0, Math.PI * 2 );
|
|
|
+
|
|
|
+ return path;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ function parseLineNode( node ) {
|
|
|
+
|
|
|
+ var x1 = parseFloat( node.getAttribute( 'x1' ) );
|
|
|
+ var y1 = parseFloat( node.getAttribute( 'y1' ) );
|
|
|
+ var x2 = parseFloat( node.getAttribute( 'x2' ) );
|
|
|
+ var y2 = parseFloat( node.getAttribute( 'y2' ) );
|
|
|
+
|
|
|
+ var path = new THREE.ShapePath();
|
|
|
+ path.moveTo( x1, y1 );
|
|
|
+ path.lineTo( x2, y2 );
|
|
|
+ path.currentPath.autoClose = false;
|
|
|
+
|
|
|
+ return path;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
|
|
|
+
|
|
|
+ function getReflection( a, b ) {
|
|
|
+
|
|
|
+ return 2 * a - ( b - a );
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
function parseFloats( string ) {
|
|
|
|
|
|
var array = string.split( /[\s,]+|(?=\s?[+\-])/ );
|