|
@@ -71,6 +71,7 @@ THREE.SVGLoader.prototype = {
|
|
|
|
|
|
var path = new THREE.ShapePath();
|
|
var path = new THREE.ShapePath();
|
|
var point = new THREE.Vector2();
|
|
var point = new THREE.Vector2();
|
|
|
|
+ var control = new THREE.Vector2();
|
|
|
|
|
|
var d = node.getAttribute( 'd' );
|
|
var d = node.getAttribute( 'd' );
|
|
|
|
|
|
@@ -90,18 +91,24 @@ THREE.SVGLoader.prototype = {
|
|
case 'M':
|
|
case 'M':
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.fromArray( numbers );
|
|
point.fromArray( numbers );
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.moveTo( point.x, point.y );
|
|
path.moveTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
case 'H':
|
|
case 'H':
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.x = numbers[ 0 ];
|
|
point.x = numbers[ 0 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
case 'V':
|
|
case 'V':
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.y = numbers[ 0 ];
|
|
point.y = numbers[ 0 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -109,6 +116,8 @@ THREE.SVGLoader.prototype = {
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.x = numbers[ 0 ];
|
|
point.x = numbers[ 0 ];
|
|
point.y = numbers[ 1 ];
|
|
point.y = numbers[ 1 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -122,19 +131,84 @@ THREE.SVGLoader.prototype = {
|
|
numbers[ 4 ],
|
|
numbers[ 4 ],
|
|
numbers[ 5 ],
|
|
numbers[ 5 ],
|
|
);
|
|
);
|
|
|
|
+ control.x = numbers[ 2 ];
|
|
|
|
+ control.y = numbers[ 3 ];
|
|
point.x = numbers[ 4 ];
|
|
point.x = numbers[ 4 ];
|
|
point.y = numbers[ 5 ];
|
|
point.y = numbers[ 5 ];
|
|
break;
|
|
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':
|
|
case 'h':
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.x += numbers[ 0 ];
|
|
point.x += numbers[ 0 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
case 'v':
|
|
case 'v':
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.y += numbers[ 0 ];
|
|
point.y += numbers[ 0 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -142,6 +216,8 @@ THREE.SVGLoader.prototype = {
|
|
var numbers = parseFloats( data );
|
|
var numbers = parseFloats( data );
|
|
point.x += numbers[ 0 ];
|
|
point.x += numbers[ 0 ];
|
|
point.y += numbers[ 1 ];
|
|
point.y += numbers[ 1 ];
|
|
|
|
+ control.x = point.x;
|
|
|
|
+ control.y = point.y;
|
|
path.lineTo( point.x, point.y );
|
|
path.lineTo( point.x, point.y );
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -159,6 +235,58 @@ THREE.SVGLoader.prototype = {
|
|
point.y += numbers[ 5 ];
|
|
point.y += numbers[ 5 ];
|
|
break;
|
|
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':
|
|
case 'z':
|
|
case 'z':
|
|
path.currentPath.autoClose = true;
|
|
path.currentPath.autoClose = true;
|
|
@@ -191,6 +319,14 @@ THREE.SVGLoader.prototype = {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ // http://www.w3.org/TR/SVG11/implnote.html#PathElementImplementationNotes
|
|
|
|
+
|
|
|
|
+ function getReflection( a, b ) {
|
|
|
|
+
|
|
|
|
+ return 2 * a - ( b - a );
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
function parseFloats( string ) {
|
|
function parseFloats( string ) {
|
|
|
|
|
|
var array = string.split( /[\s,]+|(?=\s?[+\-])/ );
|
|
var array = string.split( /[\s,]+|(?=\s?[+\-])/ );
|