Pārlūkot izejas kodu

add css stylesheet support for svg
add "opacity" support

Maciek Jurczyk 5 gadi atpakaļ
vecāks
revīzija
4ee8bbe7ca
2 mainītis faili ar 62 papildinājumiem un 1 dzēšanām
  1. 61 1
      examples/js/loaders/SVGLoader.js
  2. 1 0
      src/extras/core/ShapePath.js

+ 61 - 1
examples/js/loaders/SVGLoader.js

@@ -51,6 +51,10 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 				case 'svg':
 					break;
 
+				case 'style':
+					parseCSSStylesheet( node );
+					break;
+
 				case 'g':
 					style = parseStyle( node, style );
 					break;
@@ -91,7 +95,7 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 					break;
 
 				default:
-					console.log( node );
+					// console.log( node );
 
 			}
 
@@ -103,6 +107,8 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 				}
 
+				path.opacity = style.opacity || 1.0;
+
 				transformPath( path, currentTransform );
 
 				paths.push( path );
@@ -558,6 +564,34 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 		}
 
+		function parseCSSStylesheet( node ) {
+
+			if ( !node.sheet || !node.sheet.cssRules || !node.sheet.cssRules.length ) return;
+
+			for ( var i = 0; i < node.sheet.cssRules.length; i ++ ) {
+
+				var stylesheet = node.sheet.cssRules[ i ];
+
+				if ( stylesheet.type !== 1 ) continue;
+
+				var selectorList = stylesheet.selectorText
+					.split( /,/gm )
+					.filter( Boolean )
+					.map( i => i.trim() );
+
+				for ( var j = 0; j < selectorList.length; j ++ ) {
+
+					stylesheets[ selectorList[ j ] ] = Object.assign(
+						stylesheets[ selectorList[ j ] ] || {},
+						stylesheet.style
+					);
+
+				}
+				
+			}
+
+		}
+
 		/**
 		 * https://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
 		 * https://mortoray.com/2017/02/16/rendering-an-svg-elliptical-arc-as-bezier-curves/ Appendix: Endpoint to center arc conversion
@@ -794,6 +828,29 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 			style = Object.assign( {}, style ); // clone style
 
+			var stylesheetStyles = {};
+
+			if ( node.hasAttribute( 'class' ) ) {
+
+				var classSelectors = node.getAttribute( 'class' )
+					.split( /\s/ )
+					.filter( Boolean )
+					.map( i => i.trim() );
+
+				for ( var i = 0; i < classSelectors.length; i ++ ) {
+
+					stylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '.' + classSelectors[ i ] ] );
+
+				}
+
+			}
+
+			if ( node.hasAttribute( 'id' ) ) {
+
+				stylesheetStyles = Object.assign( stylesheetStyles, stylesheets[ '#' + node.getAttribute( 'id' ) ] );
+
+			}
+
 			function addStyle( svgName, jsName, adjustFunction ) {
 
 				if ( adjustFunction === undefined ) adjustFunction = function copy( v ) {
@@ -803,6 +860,7 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 				};
 
 				if ( node.hasAttribute( svgName ) ) style[ jsName ] = adjustFunction( node.getAttribute( svgName ) );
+				if ( stylesheetStyles[ svgName ] ) style[ jsName ] = adjustFunction( stylesheetStyles[ svgName ] );
 				if ( node.style && node.style[ svgName ] !== '' ) style[ jsName ] = adjustFunction( node.style[ svgName ] );
 
 			}
@@ -821,6 +879,7 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 
 			addStyle( 'fill', 'fill' );
 			addStyle( 'fill-opacity', 'fillOpacity', clamp );
+			addStyle( 'opacity', 'opacity', clamp );
 			addStyle( 'stroke', 'stroke' );
 			addStyle( 'stroke-opacity', 'strokeOpacity', clamp );
 			addStyle( 'stroke-width', 'strokeWidth', positive );
@@ -1233,6 +1292,7 @@ THREE.SVGLoader.prototype = Object.assign( Object.create( THREE.Loader.prototype
 		//
 
 		var paths = [];
+		var stylesheets = {};
 
 		var transformStack = [];
 

+ 1 - 0
src/extras/core/ShapePath.js

@@ -13,6 +13,7 @@ function ShapePath() {
 	this.type = 'ShapePath';
 
 	this.color = new Color();
+	this.opacity = 1.0;
 
 	this.subPaths = [];
 	this.currentPath = null;