Jelajahi Sumber

Implement defs and use nodes. First test.

yomboprime 4 tahun lalu
induk
melakukan
10ba26e9fa
1 mengubah file dengan 112 tambahan dan 82 penghapusan
  1. 112 82
      examples/jsm/loaders/SVGLoader.js

+ 112 - 82
examples/jsm/loaders/SVGLoader.js

@@ -69,6 +69,8 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 			var transform = getNodeTransform( node );
 
+			var traverseChildNodes = true;
+
 			var path = null;
 
 			switch ( node.nodeName ) {
@@ -119,6 +121,17 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 					path = parseLineNode( node );
 					break;
 
+				case 'defs':
+					traverseChildNodes = false;
+					break;
+
+				case 'use':
+					var usedNode = node.viewportElement.getElementById( node.href.baseVal.substring( 1 ) );
+					parseNode( usedNode, style );
+					break;
+
+				break;
+
 				default:
 					// console.log( node );
 
@@ -140,11 +153,15 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 			}
 
-			var nodes = node.childNodes;
+			if ( traverseChildNodes ) {
+
+				var nodes = node.childNodes;
 
-			for ( var i = 0; i < nodes.length; i ++ ) {
+				for ( var i = 0; i < nodes.length; i ++ ) {
 
-				parseNode( nodes[ i ], style );
+					parseNode( nodes[ i ], style );
+
+				}
 
 			}
 
@@ -1079,7 +1096,7 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 		function getNodeTransform( node ) {
 
-			if ( ! node.hasAttribute( 'transform' ) ) {
+			if ( ! ( node.hasAttribute( 'transform' ) || node.nodeName === 'use' ) ) {
 
 				return null;
 
@@ -1104,142 +1121,155 @@ SVGLoader.prototype = Object.assign( Object.create( Loader.prototype ), {
 
 			var transform = new Matrix3();
 			var currentTransform = tempTransform0;
-			var transformsTexts = node.getAttribute( 'transform' ).split( ')' );
 
-			for ( var tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) {
+			if ( node.nodeName === 'use' ) {
+
+				var tx = parseFloatWithUnits( node.getAttribute( 'x' ) );
+				var ty = parseFloatWithUnits( node.getAttribute( 'y' ) );
 
-				var transformText = transformsTexts[ tIndex ].trim();
+				transform.translate( tx, ty );
 
-				if ( transformText === '' ) continue;
+			}
+			else {
 
-				var openParPos = transformText.indexOf( '(' );
-				var closeParPos = transformText.length;
+				var transformsTexts = node.getAttribute( 'transform' ).split( ')' );
 
-				if ( openParPos > 0 && openParPos < closeParPos ) {
+				for ( var tIndex = transformsTexts.length - 1; tIndex >= 0; tIndex -- ) {
 
-					var transformType = transformText.substr( 0, openParPos );
+					var transformText = transformsTexts[ tIndex ].trim();
 
-					var array = parseFloats( transformText.substr( openParPos + 1, closeParPos - openParPos - 1 ) );
+					if ( transformText === '' ) continue;
 
-					currentTransform.identity();
+					var openParPos = transformText.indexOf( '(' );
+					var closeParPos = transformText.length;
+
+					if ( openParPos > 0 && openParPos < closeParPos ) {
+
+						var transformType = transformText.substr( 0, openParPos );
+
+						var array = parseFloats( transformText.substr( openParPos + 1, closeParPos - openParPos - 1 ) );
 
-					switch ( transformType ) {
+						currentTransform.identity();
 
-						case "translate":
+						switch ( transformType ) {
 
-							if ( array.length >= 1 ) {
+							case "translate":
 
-								var tx = array[ 0 ];
-								var ty = tx;
+								if ( array.length >= 1 ) {
 
-								if ( array.length >= 2 ) {
+									var tx = array[ 0 ];
+									var ty = tx;
 
-									ty = array[ 1 ];
+									if ( array.length >= 2 ) {
+
+										ty = array[ 1 ];
+
+									}
+
+									currentTransform.translate( tx, ty );
 
 								}
 
-								currentTransform.translate( tx, ty );
+								break;
 
-							}
+							case "rotate":
 
-							break;
+								if ( array.length >= 1 ) {
 
-						case "rotate":
+									var angle = 0;
+									var cx = 0;
+									var cy = 0;
 
-							if ( array.length >= 1 ) {
+									// Angle
+									angle = - array[ 0 ] * Math.PI / 180;
 
-								var angle = 0;
-								var cx = 0;
-								var cy = 0;
+									if ( array.length >= 3 ) {
 
-								// Angle
-								angle = - array[ 0 ] * Math.PI / 180;
+										// Center x, y
+										cx = array[ 1 ];
+										cy = array[ 2 ];
 
-								if ( array.length >= 3 ) {
+									}
 
-									// Center x, y
-									cx = array[ 1 ];
-									cy = array[ 2 ];
+									// Rotate around center (cx, cy)
+									tempTransform1.identity().translate( - cx, - cy );
+									tempTransform2.identity().rotate( angle );
+									tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );
+									tempTransform1.identity().translate( cx, cy );
+									currentTransform.multiplyMatrices( tempTransform1, tempTransform3 );
 
 								}
 
-								// Rotate around center (cx, cy)
-								tempTransform1.identity().translate( - cx, - cy );
-								tempTransform2.identity().rotate( angle );
-								tempTransform3.multiplyMatrices( tempTransform2, tempTransform1 );
-								tempTransform1.identity().translate( cx, cy );
-								currentTransform.multiplyMatrices( tempTransform1, tempTransform3 );
+								break;
 
-							}
+							case "scale":
 
-							break;
+								if ( array.length >= 1 ) {
 
-						case "scale":
+									var scaleX = array[ 0 ];
+									var scaleY = scaleX;
 
-							if ( array.length >= 1 ) {
+									if ( array.length >= 2 ) {
 
-								var scaleX = array[ 0 ];
-								var scaleY = scaleX;
+										scaleY = array[ 1 ];
 
-								if ( array.length >= 2 ) {
+									}
 
-									scaleY = array[ 1 ];
+									currentTransform.scale( scaleX, scaleY );
 
 								}
 
-								currentTransform.scale( scaleX, scaleY );
+								break;
 
-							}
-
-							break;
+							case "skewX":
 
-						case "skewX":
+								if ( array.length === 1 ) {
 
-							if ( array.length === 1 ) {
+									currentTransform.set(
+										1, Math.tan( array[ 0 ] * Math.PI / 180 ), 0,
+										0, 1, 0,
+										0, 0, 1
+									);
 
-								currentTransform.set(
-									1, Math.tan( array[ 0 ] * Math.PI / 180 ), 0,
-									0, 1, 0,
-									0, 0, 1
-								);
+								}
 
-							}
+								break;
 
-							break;
+							case "skewY":
 
-						case "skewY":
+								if ( array.length === 1 ) {
 
-							if ( array.length === 1 ) {
+									currentTransform.set(
+										1, 0, 0,
+										Math.tan( array[ 0 ] * Math.PI / 180 ), 1, 0,
+										0, 0, 1
+									);
 
-								currentTransform.set(
-									1, 0, 0,
-									Math.tan( array[ 0 ] * Math.PI / 180 ), 1, 0,
-									0, 0, 1
-								);
+								}
 
-							}
+								break;
 
-							break;
+							case "matrix":
 
-						case "matrix":
+								if ( array.length === 6 ) {
 
-							if ( array.length === 6 ) {
+									currentTransform.set(
+										array[ 0 ], array[ 2 ], array[ 4 ],
+										array[ 1 ], array[ 3 ], array[ 5 ],
+										0, 0, 1
+									);
 
-								currentTransform.set(
-									array[ 0 ], array[ 2 ], array[ 4 ],
-									array[ 1 ], array[ 3 ], array[ 5 ],
-									0, 0, 1
-								);
+								}
 
-							}
+								break;
 
-							break;
+						}
 
 					}
 
-				}
+					transform.premultiply( currentTransform );
 
-				transform.premultiply( currentTransform );
+				}
 
 			}