import { Box2, BufferGeometry, FileLoader, Float32BufferAttribute, Loader, Matrix3, Path, Shape, ShapePath, ShapeUtils, SRGBColorSpace, Vector2, Vector3 } from 'three'; const COLOR_SPACE_SVG = SRGBColorSpace; class SVGLoader extends Loader { constructor( manager ) { super( manager ); // Default dots per inch this.defaultDPI = 90; // Accepted units: 'mm', 'cm', 'in', 'pt', 'pc', 'px' this.defaultUnit = 'px'; } load( url, onLoad, onProgress, onError ) { const scope = this; const loader = new FileLoader( scope.manager ); loader.setPath( scope.path ); loader.setRequestHeader( scope.requestHeader ); loader.setWithCredentials( scope.withCredentials ); loader.load( url, function ( text ) { try { onLoad( scope.parse( text ) ); } catch ( e ) { if ( onError ) { onError( e ); } else { console.error( e ); } scope.manager.itemError( url ); } }, onProgress, onError ); } parse( text ) { const scope = this; function parseNode( node, style ) { if ( node.nodeType !== 1 ) return; const transform = getNodeTransform( node ); let isDefsNode = false; let path = null; switch ( node.nodeName ) { case 'svg': style = parseStyle( node, style ); break; case 'style': parseCSSStylesheet( node ); break; case 'g': style = parseStyle( node, style ); break; case 'path': style = parseStyle( node, style ); if ( node.hasAttribute( 'd' ) ) path = parsePathNode( node ); break; case 'rect': style = parseStyle( node, style ); path = parseRectNode( node ); break; case 'polygon': style = parseStyle( node, style ); path = parsePolygonNode( node ); break; case 'polyline': style = parseStyle( node, style ); path = parsePolylineNode( node ); break; case 'circle': style = parseStyle( node, style ); path = parseCircleNode( node ); break; case 'ellipse': style = parseStyle( node, style ); path = parseEllipseNode( node ); break; case 'line': style = parseStyle( node, style ); path = parseLineNode( node ); break; case 'defs': isDefsNode = true; break; case 'use': style = parseStyle( node, style ); const href = node.getAttributeNS( 'http://www.w3.org/1999/xlink', 'href' ) || ''; const usedNodeId = href.substring( 1 ); const usedNode = node.viewportElement.getElementById( usedNodeId ); if ( usedNode ) { parseNode( usedNode, style ); } else { console.warn( 'SVGLoader: \'use node\' references non-existent node id: ' + usedNodeId ); } break; default: // console.log( node ); } if ( path ) { if ( style.fill !== undefined && style.fill !== 'none' ) { path.color.setStyle( style.fill, COLOR_SPACE_SVG ); } transformPath( path, currentTransform ); paths.push( path ); path.userData = { node: node, style: style }; } const childNodes = node.childNodes; for ( let i = 0; i < childNodes.length; i ++ ) { const node = childNodes[ i ]; if ( isDefsNode && node.nodeName !== 'style' && node.nodeName !== 'defs' ) { // Ignore everything in defs except CSS style definitions // and nested defs, because it is OK by the standard to have //