浏览代码

Examples: Convert renderers to ES6. (#21601)

* Examples: Convert renderers to ES6.

* Examples: Clean up.
Michael Herzog 4 年之前
父节点
当前提交
7b0d2e97ed

+ 120 - 104
examples/js/renderers/CSS2DRenderer.js

@@ -1,176 +1,192 @@
 ( function () {
 
-	var CSS2DObject = function ( element ) {
+	class CSS2DObject extends THREE.Object3D {
 
-		THREE.Object3D.call( this );
-		this.element = element || document.createElement( 'div' );
-		this.element.style.position = 'absolute';
-		this.addEventListener( 'removed', function () {
+		constructor( element ) {
 
-			this.traverse( function ( object ) {
+			super();
+			this.element = element || document.createElement( 'div' );
+			this.element.style.position = 'absolute';
+			this.addEventListener( 'removed', function () {
 
-				if ( object.element instanceof Element && object.element.parentNode !== null ) {
+				this.traverse( function ( object ) {
 
-					object.element.parentNode.removeChild( object.element );
+					if ( object.element instanceof Element && object.element.parentNode !== null ) {
 
-				}
+						object.element.parentNode.removeChild( object.element );
 
-			} );
+					}
 
-		} );
+				} );
 
-	};
+			} );
+
+		}
 
-	CSS2DObject.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), {
-		constructor: CSS2DObject,
-		copy: function ( source, recursive ) {
+		copy( source, recursive ) {
 
-			THREE.Object3D.prototype.copy.call( this, source, recursive );
+			super.copy( source, recursive );
 			this.element = source.element.cloneNode( true );
 			return this;
 
 		}
-	} ); //
 
-	var CSS2DRenderer = function () {
+	}
+
+	CSS2DObject.prototype.isCSS2DObject = true; //
+
+	const _vector = new THREE.Vector3();
+
+	const _viewMatrix = new THREE.Matrix4();
+
+	const _viewProjectionMatrix = new THREE.Matrix4();
+
+	const _a = new THREE.Vector3();
 
-		var _this = this;
+	const _b = new THREE.Vector3();
 
-		var _width, _height;
+	class CSS2DRenderer {
 
-		var _widthHalf, _heightHalf;
+		constructor() {
 
-		var vector = new THREE.Vector3();
-		var viewMatrix = new THREE.Matrix4();
-		var viewProjectionMatrix = new THREE.Matrix4();
-		var cache = {
-			objects: new WeakMap()
-		};
-		var domElement = document.createElement( 'div' );
-		domElement.style.overflow = 'hidden';
-		this.domElement = domElement;
+			const _this = this;
 
-		this.getSize = function () {
+			let _width, _height;
 
-			return {
-				width: _width,
-				height: _height
+			let _widthHalf, _heightHalf;
+
+			const cache = {
+				objects: new WeakMap()
 			};
+			const domElement = document.createElement( 'div' );
+			domElement.style.overflow = 'hidden';
+			this.domElement = domElement;
 
-		};
+			this.getSize = function () {
 
-		this.setSize = function ( width, height ) {
+				return {
+					width: _width,
+					height: _height
+				};
 
-			_width = width;
-			_height = height;
-			_widthHalf = _width / 2;
-			_heightHalf = _height / 2;
-			domElement.style.width = width + 'px';
-			domElement.style.height = height + 'px';
+			};
 
-		};
+			this.render = function ( scene, camera ) {
 
-		var renderObject = function ( object, scene, camera ) {
+				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
+				if ( camera.parent === null ) camera.updateMatrixWorld();
 
-			if ( object instanceof CSS2DObject ) {
+				_viewMatrix.copy( camera.matrixWorldInverse );
 
-				object.onBeforeRender( _this, scene, camera );
-				vector.setFromMatrixPosition( object.matrixWorld );
-				vector.applyMatrix4( viewProjectionMatrix );
-				var element = object.element;
+				_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
 
-				if ( /apple/i.test( navigator.vendor ) ) {
+				renderObject( scene, scene, camera );
+				zOrder( scene );
 
-					// https://github.com/mrdoob/three.js/issues/21415
-					element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - vector.y * _heightHalf + _heightHalf ) + 'px)';
+			};
 
-				} else {
+			this.setSize = function ( width, height ) {
 
-					element.style.transform = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';
+				_width = width;
+				_height = height;
+				_widthHalf = _width / 2;
+				_heightHalf = _height / 2;
+				domElement.style.width = width + 'px';
+				domElement.style.height = height + 'px';
 
-				}
+			};
 
-				element.style.display = object.visible && vector.z >= - 1 && vector.z <= 1 ? '' : 'none';
-				var objectData = {
-					distanceToCameraSquared: getDistanceToSquared( camera, object )
-				};
-				cache.objects.set( object, objectData );
+			function renderObject( object, scene, camera ) {
 
-				if ( element.parentNode !== domElement ) {
+				if ( object.isCSS2DObject ) {
 
-					domElement.appendChild( element );
+					object.onBeforeRender( _this, scene, camera );
 
-				}
+					_vector.setFromMatrixPosition( object.matrixWorld );
 
-				object.onAfterRender( _this, scene, camera );
+					_vector.applyMatrix4( _viewProjectionMatrix );
 
-			}
+					const element = object.element;
 
-			for ( var i = 0, l = object.children.length; i < l; i ++ ) {
+					if ( /apple/i.test( navigator.vendor ) ) {
 
-				renderObject( object.children[ i ], scene, camera );
+						// https://github.com/mrdoob/three.js/issues/21415
+						element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( _vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
 
-			}
+					} else {
 
-		};
+						element.style.transform = 'translate(-50%,-50%) translate(' + ( _vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
 
-		var getDistanceToSquared = function () {
+					}
 
-			var a = new THREE.Vector3();
-			var b = new THREE.Vector3();
-			return function ( object1, object2 ) {
+					element.style.display = object.visible && _vector.z >= - 1 && _vector.z <= 1 ? '' : 'none';
+					const objectData = {
+						distanceToCameraSquared: getDistanceToSquared( camera, object )
+					};
+					cache.objects.set( object, objectData );
 
-				a.setFromMatrixPosition( object1.matrixWorld );
-				b.setFromMatrixPosition( object2.matrixWorld );
-				return a.distanceToSquared( b );
+					if ( element.parentNode !== domElement ) {
 
-			};
+						domElement.appendChild( element );
 
-		}();
+					}
 
-		var filterAndFlatten = function ( scene ) {
+					object.onAfterRender( _this, scene, camera );
 
-			var result = [];
-			scene.traverse( function ( object ) {
+				}
 
-				if ( object instanceof CSS2DObject ) result.push( object );
+				for ( let i = 0, l = object.children.length; i < l; i ++ ) {
 
-			} );
-			return result;
+					renderObject( object.children[ i ], scene, camera );
+
+				}
 
-		};
+			}
 
-		var zOrder = function ( scene ) {
+			function getDistanceToSquared( object1, object2 ) {
 
-			var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
+				_a.setFromMatrixPosition( object1.matrixWorld );
 
-				var distanceA = cache.objects.get( a ).distanceToCameraSquared;
-				var distanceB = cache.objects.get( b ).distanceToCameraSquared;
-				return distanceA - distanceB;
+				_b.setFromMatrixPosition( object2.matrixWorld );
 
-			} );
-			var zMax = sorted.length;
+				return _a.distanceToSquared( _b );
+
+			}
+
+			function filterAndFlatten( scene ) {
 
-			for ( var i = 0, l = sorted.length; i < l; i ++ ) {
+				const result = [];
+				scene.traverse( function ( object ) {
 
-				sorted[ i ].element.style.zIndex = zMax - i;
+					if ( object.isCSS2DObject ) result.push( object );
+
+				} );
+				return result;
 
 			}
 
-		};
+			function zOrder( scene ) {
+
+				const sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
+
+					const distanceA = cache.objects.get( a ).distanceToCameraSquared;
+					const distanceB = cache.objects.get( b ).distanceToCameraSquared;
+					return distanceA - distanceB;
 
-		this.render = function ( scene, camera ) {
+				} );
+				const zMax = sorted.length;
 
-			if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
-			if ( camera.parent === null ) camera.updateMatrixWorld();
-			viewMatrix.copy( camera.matrixWorldInverse );
-			viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
-			renderObject( scene, scene, camera );
-			zOrder( scene );
+				for ( let i = 0, l = sorted.length; i < l; i ++ ) {
 
-		};
+					sorted[ i ].element.style.zIndex = zMax - i;
+
+				}
+
+			}
+
+		}
 
-	};
+	}
 
 	THREE.CSS2DObject = CSS2DObject;
 	THREE.CSS2DRenderer = CSS2DRenderer;

+ 142 - 126
examples/js/renderers/CSS3DRenderer.js

@@ -4,210 +4,226 @@
  * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs
  */
 
-	var CSS3DObject = function ( element ) {
+	class CSS3DObject extends THREE.Object3D {
 
-		THREE.Object3D.call( this );
-		this.element = element || document.createElement( 'div' );
-		this.element.style.position = 'absolute';
-		this.element.style.pointerEvents = 'auto';
-		this.addEventListener( 'removed', function () {
+		constructor( element ) {
 
-			this.traverse( function ( object ) {
+			super();
+			this.element = element || document.createElement( 'div' );
+			this.element.style.position = 'absolute';
+			this.element.style.pointerEvents = 'auto';
+			this.addEventListener( 'removed', function () {
 
-				if ( object.element instanceof Element && object.element.parentNode !== null ) {
+				this.traverse( function ( object ) {
 
-					object.element.parentNode.removeChild( object.element );
+					if ( object.element instanceof Element && object.element.parentNode !== null ) {
 
-				}
+						object.element.parentNode.removeChild( object.element );
 
-			} );
+					}
 
-		} );
+				} );
 
-	};
+			} );
+
+		}
 
-	CSS3DObject.prototype = Object.assign( Object.create( THREE.Object3D.prototype ), {
-		constructor: CSS3DObject,
-		copy: function ( source, recursive ) {
+		copy( source, recursive ) {
 
-			THREE.Object3D.prototype.copy.call( this, source, recursive );
+			super.copy( source, recursive );
 			this.element = source.element.cloneNode( true );
 			return this;
 
 		}
-	} );
 
-	var CSS3DSprite = function ( element ) {
+	}
 
-		CSS3DObject.call( this, element );
+	CSS3DObject.prototype.isCSS3DObject = true;
 
-	};
+	class CSS3DSprite extends CSS3DObject {
 
-	CSS3DSprite.prototype = Object.create( CSS3DObject.prototype );
-	CSS3DSprite.prototype.constructor = CSS3DSprite; //
+		constructor( element ) {
 
-	var CSS3DRenderer = function () {
+			super( element );
 
-		var _this = this;
-
-		var _width, _height;
+		}
 
-		var _widthHalf, _heightHalf;
+	}
 
-		var matrix = new THREE.Matrix4();
-		var cache = {
-			camera: {
-				fov: 0,
-				style: ''
-			},
-			objects: new WeakMap()
-		};
-		var domElement = document.createElement( 'div' );
-		domElement.style.overflow = 'hidden';
-		this.domElement = domElement;
-		var cameraElement = document.createElement( 'div' );
-		cameraElement.style.transformStyle = 'preserve-3d';
-		cameraElement.style.pointerEvents = 'none';
-		domElement.appendChild( cameraElement );
+	CSS3DSprite.prototype.isCSS3DSprite = true; //
 
-		this.getSize = function () {
+	const _matrix = new THREE.Matrix4();
 
-			return {
-				width: _width,
-				height: _height
-			};
+	class CSS3DRenderer {
 
-		};
+		constructor() {
 
-		this.setSize = function ( width, height ) {
+			const _this = this;
 
-			_width = width;
-			_height = height;
-			_widthHalf = _width / 2;
-			_heightHalf = _height / 2;
-			domElement.style.width = width + 'px';
-			domElement.style.height = height + 'px';
-			cameraElement.style.width = width + 'px';
-			cameraElement.style.height = height + 'px';
+			let _width, _height;
 
-		};
+			let _widthHalf, _heightHalf;
 
-		function epsilon( value ) {
+			const cache = {
+				camera: {
+					fov: 0,
+					style: ''
+				},
+				objects: new WeakMap()
+			};
+			const domElement = document.createElement( 'div' );
+			domElement.style.overflow = 'hidden';
+			this.domElement = domElement;
+			const cameraElement = document.createElement( 'div' );
+			cameraElement.style.transformStyle = 'preserve-3d';
+			cameraElement.style.pointerEvents = 'none';
+			domElement.appendChild( cameraElement );
 
-			return Math.abs( value ) < 1e-10 ? 0 : value;
+			this.getSize = function () {
 
-		}
+				return {
+					width: _width,
+					height: _height
+				};
 
-		function getCameraCSSMatrix( matrix ) {
+			};
 
-			var elements = matrix.elements;
-			return 'matrix3d(' + epsilon( elements[ 0 ] ) + ',' + epsilon( - elements[ 1 ] ) + ',' + epsilon( elements[ 2 ] ) + ',' + epsilon( elements[ 3 ] ) + ',' + epsilon( elements[ 4 ] ) + ',' + epsilon( - elements[ 5 ] ) + ',' + epsilon( elements[ 6 ] ) + ',' + epsilon( elements[ 7 ] ) + ',' + epsilon( elements[ 8 ] ) + ',' + epsilon( - elements[ 9 ] ) + ',' + epsilon( elements[ 10 ] ) + ',' + epsilon( elements[ 11 ] ) + ',' + epsilon( elements[ 12 ] ) + ',' + epsilon( - elements[ 13 ] ) + ',' + epsilon( elements[ 14 ] ) + ',' + epsilon( elements[ 15 ] ) + ')';
+			this.render = function ( scene, camera ) {
 
-		}
+				const fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;
 
-		function getObjectCSSMatrix( matrix ) {
+				if ( cache.camera.fov !== fov ) {
 
-			var elements = matrix.elements;
-			var matrix3d = 'matrix3d(' + epsilon( elements[ 0 ] ) + ',' + epsilon( elements[ 1 ] ) + ',' + epsilon( elements[ 2 ] ) + ',' + epsilon( elements[ 3 ] ) + ',' + epsilon( - elements[ 4 ] ) + ',' + epsilon( - elements[ 5 ] ) + ',' + epsilon( - elements[ 6 ] ) + ',' + epsilon( - elements[ 7 ] ) + ',' + epsilon( elements[ 8 ] ) + ',' + epsilon( elements[ 9 ] ) + ',' + epsilon( elements[ 10 ] ) + ',' + epsilon( elements[ 11 ] ) + ',' + epsilon( elements[ 12 ] ) + ',' + epsilon( elements[ 13 ] ) + ',' + epsilon( elements[ 14 ] ) + ',' + epsilon( elements[ 15 ] ) + ')';
-			return 'translate(-50%,-50%)' + matrix3d;
+					domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : '';
+					cache.camera.fov = fov;
 
-		}
+				}
 
-		function renderObject( object, scene, camera, cameraCSSMatrix ) {
+				if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
+				if ( camera.parent === null ) camera.updateMatrixWorld();
+				let tx, ty;
 
-			if ( object instanceof CSS3DObject ) {
+				if ( camera.isOrthographicCamera ) {
 
-				object.onBeforeRender( _this, scene, camera );
-				var style;
+					tx = - ( camera.right + camera.left ) / 2;
+					ty = ( camera.top + camera.bottom ) / 2;
 
-				if ( object instanceof CSS3DSprite ) {
+				}
 
-					// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
-					matrix.copy( camera.matrixWorldInverse );
-					matrix.transpose();
-					matrix.copyPosition( object.matrixWorld );
-					matrix.scale( object.scale );
-					matrix.elements[ 3 ] = 0;
-					matrix.elements[ 7 ] = 0;
-					matrix.elements[ 11 ] = 0;
-					matrix.elements[ 15 ] = 1;
-					style = getObjectCSSMatrix( matrix );
+				const cameraCSSMatrix = camera.isOrthographicCamera ? 'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) : 'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
+				const style = cameraCSSMatrix + 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';
 
-				} else {
+				if ( cache.camera.style !== style ) {
 
-					style = getObjectCSSMatrix( object.matrixWorld );
+					cameraElement.style.transform = style;
+					cache.camera.style = style;
 
 				}
 
-				var element = object.element;
-				var cachedObject = cache.objects.get( object );
+				renderObject( scene, scene, camera, cameraCSSMatrix );
 
-				if ( cachedObject === undefined || cachedObject.style !== style ) {
+			};
 
-					element.style.transform = style;
-					var objectData = {
-						style: style
-					};
-					cache.objects.set( object, objectData );
+			this.setSize = function ( width, height ) {
 
-				}
+				_width = width;
+				_height = height;
+				_widthHalf = _width / 2;
+				_heightHalf = _height / 2;
+				domElement.style.width = width + 'px';
+				domElement.style.height = height + 'px';
+				cameraElement.style.width = width + 'px';
+				cameraElement.style.height = height + 'px';
 
-				element.style.display = object.visible ? '' : 'none';
+			};
 
-				if ( element.parentNode !== cameraElement ) {
+			function epsilon( value ) {
 
-					cameraElement.appendChild( element );
+				return Math.abs( value ) < 1e-10 ? 0 : value;
 
-				}
+			}
 
-				object.onAfterRender( _this, scene, camera );
+			function getCameraCSSMatrix( matrix ) {
+
+				const elements = matrix.elements;
+				return 'matrix3d(' + epsilon( elements[ 0 ] ) + ',' + epsilon( - elements[ 1 ] ) + ',' + epsilon( elements[ 2 ] ) + ',' + epsilon( elements[ 3 ] ) + ',' + epsilon( elements[ 4 ] ) + ',' + epsilon( - elements[ 5 ] ) + ',' + epsilon( elements[ 6 ] ) + ',' + epsilon( elements[ 7 ] ) + ',' + epsilon( elements[ 8 ] ) + ',' + epsilon( - elements[ 9 ] ) + ',' + epsilon( elements[ 10 ] ) + ',' + epsilon( elements[ 11 ] ) + ',' + epsilon( elements[ 12 ] ) + ',' + epsilon( - elements[ 13 ] ) + ',' + epsilon( elements[ 14 ] ) + ',' + epsilon( elements[ 15 ] ) + ')';
 
 			}
 
-			for ( var i = 0, l = object.children.length; i < l; i ++ ) {
+			function getObjectCSSMatrix( matrix ) {
 
-				renderObject( object.children[ i ], scene, camera, cameraCSSMatrix );
+				const elements = matrix.elements;
+				const matrix3d = 'matrix3d(' + epsilon( elements[ 0 ] ) + ',' + epsilon( elements[ 1 ] ) + ',' + epsilon( elements[ 2 ] ) + ',' + epsilon( elements[ 3 ] ) + ',' + epsilon( - elements[ 4 ] ) + ',' + epsilon( - elements[ 5 ] ) + ',' + epsilon( - elements[ 6 ] ) + ',' + epsilon( - elements[ 7 ] ) + ',' + epsilon( elements[ 8 ] ) + ',' + epsilon( elements[ 9 ] ) + ',' + epsilon( elements[ 10 ] ) + ',' + epsilon( elements[ 11 ] ) + ',' + epsilon( elements[ 12 ] ) + ',' + epsilon( elements[ 13 ] ) + ',' + epsilon( elements[ 14 ] ) + ',' + epsilon( elements[ 15 ] ) + ')';
+				return 'translate(-50%,-50%)' + matrix3d;
 
 			}
 
-		}
+			function renderObject( object, scene, camera, cameraCSSMatrix ) {
 
-		this.render = function ( scene, camera ) {
+				if ( object.isCSS3DObject ) {
 
-			var fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;
+					object.onBeforeRender( _this, scene, camera );
+					let style;
 
-			if ( cache.camera.fov !== fov ) {
+					if ( object.isCSS3DSprite ) {
 
-				domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : '';
-				cache.camera.fov = fov;
+						// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
+						_matrix.copy( camera.matrixWorldInverse );
 
-			}
+						_matrix.transpose();
 
-			if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
-			if ( camera.parent === null ) camera.updateMatrixWorld();
+						_matrix.copyPosition( object.matrixWorld );
 
-			if ( camera.isOrthographicCamera ) {
+						_matrix.scale( object.scale );
 
-				var tx = - ( camera.right + camera.left ) / 2;
-				var ty = ( camera.top + camera.bottom ) / 2;
+						_matrix.elements[ 3 ] = 0;
+						_matrix.elements[ 7 ] = 0;
+						_matrix.elements[ 11 ] = 0;
+						_matrix.elements[ 15 ] = 1;
+						style = getObjectCSSMatrix( _matrix );
 
-			}
+					} else {
 
-			var cameraCSSMatrix = camera.isOrthographicCamera ? 'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) : 'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
-			var style = cameraCSSMatrix + 'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';
+						style = getObjectCSSMatrix( object.matrixWorld );
 
-			if ( cache.camera.style !== style ) {
+					}
 
-				cameraElement.style.transform = style;
-				cache.camera.style = style;
+					const element = object.element;
+					const cachedObject = cache.objects.get( object );
 
-			}
+					if ( cachedObject === undefined || cachedObject.style !== style ) {
+
+						element.style.transform = style;
+						const objectData = {
+							style: style
+						};
+						cache.objects.set( object, objectData );
+
+					}
+
+					element.style.display = object.visible ? '' : 'none';
+
+					if ( element.parentNode !== cameraElement ) {
+
+						cameraElement.appendChild( element );
 
-			renderObject( scene, scene, camera, cameraCSSMatrix );
+					}
 
-		};
+					object.onAfterRender( _this, scene, camera );
+
+				}
+
+				for ( let i = 0, l = object.children.length; i < l; i ++ ) {
+
+					renderObject( object.children[ i ], scene, camera, cameraCSSMatrix );
+
+				}
+
+			}
+
+		}
 
-	};
+	}
 
 	THREE.CSS3DObject = CSS3DObject;
 	THREE.CSS3DRenderer = CSS3DRenderer;

文件差异内容过多而无法显示
+ 541 - 515
examples/js/renderers/Projector.js


+ 325 - 318
examples/js/renderers/SVGRenderer.js

@@ -1,517 +1,526 @@
 ( function () {
 
-	var SVGObject = function ( node ) {
-
-		THREE.Object3D.call( this );
-		this.node = node;
-
-	};
-
-	SVGObject.prototype = Object.create( THREE.Object3D.prototype );
-	SVGObject.prototype.constructor = SVGObject;
-
-	var SVGRenderer = function () {
-
-		var _this = this,
-			_renderData,
-			_elements,
-			_lights,
-			_projector = new THREE.Projector(),
-			_svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ),
-			_svgWidth,
-			_svgHeight,
-			_svgWidthHalf,
-			_svgHeightHalf,
-			_v1,
-			_v2,
-			_v3,
-			_clipBox = new THREE.Box2(),
-			_elemBox = new THREE.Box2(),
-			_color = new THREE.Color(),
-			_diffuseColor = new THREE.Color(),
-			_ambientLight = new THREE.Color(),
-			_directionalLights = new THREE.Color(),
-			_pointLights = new THREE.Color(),
-			_clearColor = new THREE.Color(),
-			_vector3 = new THREE.Vector3(),
-			// Needed for PointLight
-			_centroid = new THREE.Vector3(),
-			_normal = new THREE.Vector3(),
-			_normalViewMatrix = new THREE.Matrix3(),
-			_viewMatrix = new THREE.Matrix4(),
-			_viewProjectionMatrix = new THREE.Matrix4(),
-			_svgPathPool = [],
-			_svgNode,
-			_pathCount = 0,
-			_currentPath,
-			_currentStyle,
-			_quality = 1,
-			_precision = null;
-
-		this.domElement = _svg;
-		this.autoClear = true;
-		this.sortObjects = true;
-		this.sortElements = true;
-		this.overdraw = 0.5;
-		this.info = {
-			render: {
-				vertices: 0,
-				faces: 0
-			}
-		};
+	class SVGObject extends THREE.Object3D {
+
+		constructor( node ) {
+
+			super();
+			this.node = node;
+
+		}
 
-		this.setQuality = function ( quality ) {
+	}
+
+	SVGObject.prototype.isSVGObject = true;
+
+	class SVGRenderer {
+
+		constructor() {
+
+			let _renderData,
+				_elements,
+				_lights,
+				_svgWidth,
+				_svgHeight,
+				_svgWidthHalf,
+				_svgHeightHalf,
+				_v1,
+				_v2,
+				_v3,
+				_svgNode,
+				_pathCount = 0,
+				_precision = null,
+				_quality = 1,
+				_currentPath,
+				_currentStyle;
+
+			const _this = this,
+				_clipBox = new THREE.Box2(),
+				_elemBox = new THREE.Box2(),
+				_color = new THREE.Color(),
+				_diffuseColor = new THREE.Color(),
+				_ambientLight = new THREE.Color(),
+				_directionalLights = new THREE.Color(),
+				_pointLights = new THREE.Color(),
+				_clearColor = new THREE.Color(),
+				_vector3 = new THREE.Vector3(),
+				// Needed for PointLight
+				_centroid = new THREE.Vector3(),
+				_normal = new THREE.Vector3(),
+				_normalViewMatrix = new THREE.Matrix3(),
+				_viewMatrix = new THREE.Matrix4(),
+				_viewProjectionMatrix = new THREE.Matrix4(),
+				_svgPathPool = [],
+				_projector = new THREE.Projector(),
+				_svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );
+
+			this.domElement = _svg;
+			this.autoClear = true;
+			this.sortObjects = true;
+			this.sortElements = true;
+			this.overdraw = 0.5;
+			this.info = {
+				render: {
+					vertices: 0,
+					faces: 0
+				}
+			};
 
-			switch ( quality ) {
+			this.setQuality = function ( quality ) {
 
-				case 'high':
-					_quality = 1;
-					break;
+				switch ( quality ) {
 
-				case 'low':
-					_quality = 0;
-					break;
+					case 'high':
+						_quality = 1;
+						break;
 
-			}
+					case 'low':
+						_quality = 0;
+						break;
 
-		};
+				}
+
+			};
+
+			this.setClearColor = function ( color ) {
 
-		this.setClearColor = function ( color ) {
+				_clearColor.set( color );
 
-			_clearColor.set( color );
+			};
 
-		};
+			this.setPixelRatio = function () {};
 
-		this.setPixelRatio = function () {};
+			this.setSize = function ( width, height ) {
 
-		this.setSize = function ( width, height ) {
+				_svgWidth = width;
+				_svgHeight = height;
+				_svgWidthHalf = _svgWidth / 2;
+				_svgHeightHalf = _svgHeight / 2;
 
-			_svgWidth = width;
-			_svgHeight = height;
-			_svgWidthHalf = _svgWidth / 2;
-			_svgHeightHalf = _svgHeight / 2;
+				_svg.setAttribute( 'viewBox', - _svgWidthHalf + ' ' + - _svgHeightHalf + ' ' + _svgWidth + ' ' + _svgHeight );
 
-			_svg.setAttribute( 'viewBox', - _svgWidthHalf + ' ' + - _svgHeightHalf + ' ' + _svgWidth + ' ' + _svgHeight );
+				_svg.setAttribute( 'width', _svgWidth );
 
-			_svg.setAttribute( 'width', _svgWidth );
+				_svg.setAttribute( 'height', _svgHeight );
 
-			_svg.setAttribute( 'height', _svgHeight );
+				_clipBox.min.set( - _svgWidthHalf, - _svgHeightHalf );
 
-			_clipBox.min.set( - _svgWidthHalf, - _svgHeightHalf );
+				_clipBox.max.set( _svgWidthHalf, _svgHeightHalf );
 
-			_clipBox.max.set( _svgWidthHalf, _svgHeightHalf );
+			};
 
-		};
+			this.getSize = function () {
 
-		this.getSize = function () {
+				return {
+					width: _svgWidth,
+					height: _svgHeight
+				};
 
-			return {
-				width: _svgWidth,
-				height: _svgHeight
 			};
 
-		};
+			this.setPrecision = function ( precision ) {
 
-		this.setPrecision = function ( precision ) {
+				_precision = precision;
 
-			_precision = precision;
+			};
 
-		};
+			function removeChildNodes() {
 
-		function removeChildNodes() {
+				_pathCount = 0;
 
-			_pathCount = 0;
+				while ( _svg.childNodes.length > 0 ) {
 
-			while ( _svg.childNodes.length > 0 ) {
+					_svg.removeChild( _svg.childNodes[ 0 ] );
 
-				_svg.removeChild( _svg.childNodes[ 0 ] );
+				}
 
 			}
 
-		}
+			function convert( c ) {
 
-		function convert( c ) {
+				return _precision !== null ? c.toFixed( _precision ) : c;
 
-			return _precision !== null ? c.toFixed( _precision ) : c;
+			}
 
-		}
+			this.clear = function () {
 
-		this.clear = function () {
+				removeChildNodes();
+				_svg.style.backgroundColor = _clearColor.getStyle();
 
-			removeChildNodes();
-			_svg.style.backgroundColor = _clearColor.getStyle();
+			};
 
-		};
+			this.render = function ( scene, camera ) {
 
-		this.render = function ( scene, camera ) {
+				if ( camera instanceof THREE.Camera === false ) {
 
-			if ( camera instanceof THREE.Camera === false ) {
+					console.error( 'THREE.SVGRenderer.render: camera is not an instance of THREE.Camera.' );
+					return;
 
-				console.error( 'THREE.SVGRenderer.render: camera is not an instance of THREE.Camera.' );
-				return;
+				}
 
-			}
+				const background = scene.background;
 
-			var background = scene.background;
+				if ( background && background.isColor ) {
 
-			if ( background && background.isColor ) {
+					removeChildNodes();
+					_svg.style.backgroundColor = background.getStyle();
 
-				removeChildNodes();
-				_svg.style.backgroundColor = background.getStyle();
+				} else if ( this.autoClear === true ) {
 
-			} else if ( this.autoClear === true ) {
+					this.clear();
 
-				this.clear();
+				}
 
-			}
+				_this.info.render.vertices = 0;
+				_this.info.render.faces = 0;
 
-			_this.info.render.vertices = 0;
-			_this.info.render.faces = 0;
+				_viewMatrix.copy( camera.matrixWorldInverse );
 
-			_viewMatrix.copy( camera.matrixWorldInverse );
+				_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
 
-			_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
+				_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
+				_elements = _renderData.elements;
+				_lights = _renderData.lights;
 
-			_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
-			_elements = _renderData.elements;
-			_lights = _renderData.lights;
+				_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
 
-			_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
+				calculateLights( _lights ); // reset accumulated path
 
-			calculateLights( _lights ); // reset accumulated path
+				_currentPath = '';
+				_currentStyle = '';
 
-			_currentPath = '';
-			_currentStyle = '';
+				for ( let e = 0, el = _elements.length; e < el; e ++ ) {
 
-			for ( var e = 0, el = _elements.length; e < el; e ++ ) {
+					const element = _elements[ e ];
+					const material = element.material;
+					if ( material === undefined || material.opacity === 0 ) continue;
 
-				var element = _elements[ e ];
-				var material = element.material;
-				if ( material === undefined || material.opacity === 0 ) continue;
+					_elemBox.makeEmpty();
 
-				_elemBox.makeEmpty();
+					if ( element instanceof THREE.RenderableSprite ) {
 
-				if ( element instanceof THREE.RenderableSprite ) {
+						_v1 = element;
+						_v1.x *= _svgWidthHalf;
+						_v1.y *= - _svgHeightHalf;
+						renderSprite( _v1, element, material );
 
-					_v1 = element;
-					_v1.x *= _svgWidthHalf;
-					_v1.y *= - _svgHeightHalf;
-					renderSprite( _v1, element, material );
+					} else if ( element instanceof THREE.RenderableLine ) {
 
-				} else if ( element instanceof THREE.RenderableLine ) {
+						_v1 = element.v1;
+						_v2 = element.v2;
+						_v1.positionScreen.x *= _svgWidthHalf;
+						_v1.positionScreen.y *= - _svgHeightHalf;
+						_v2.positionScreen.x *= _svgWidthHalf;
+						_v2.positionScreen.y *= - _svgHeightHalf;
 
-					_v1 = element.v1;
-					_v2 = element.v2;
-					_v1.positionScreen.x *= _svgWidthHalf;
-					_v1.positionScreen.y *= - _svgHeightHalf;
-					_v2.positionScreen.x *= _svgWidthHalf;
-					_v2.positionScreen.y *= - _svgHeightHalf;
+						_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] );
 
-					_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] );
+						if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
-					if ( _clipBox.intersectsBox( _elemBox ) === true ) {
+							renderLine( _v1, _v2, element, material );
 
-						renderLine( _v1, _v2, element, material );
+						}
 
-					}
+					} else if ( element instanceof THREE.RenderableFace ) {
 
-				} else if ( element instanceof THREE.RenderableFace ) {
+						_v1 = element.v1;
+						_v2 = element.v2;
+						_v3 = element.v3;
+						if ( _v1.positionScreen.z < - 1 || _v1.positionScreen.z > 1 ) continue;
+						if ( _v2.positionScreen.z < - 1 || _v2.positionScreen.z > 1 ) continue;
+						if ( _v3.positionScreen.z < - 1 || _v3.positionScreen.z > 1 ) continue;
+						_v1.positionScreen.x *= _svgWidthHalf;
+						_v1.positionScreen.y *= - _svgHeightHalf;
+						_v2.positionScreen.x *= _svgWidthHalf;
+						_v2.positionScreen.y *= - _svgHeightHalf;
+						_v3.positionScreen.x *= _svgWidthHalf;
+						_v3.positionScreen.y *= - _svgHeightHalf;
 
-					_v1 = element.v1;
-					_v2 = element.v2;
-					_v3 = element.v3;
-					if ( _v1.positionScreen.z < - 1 || _v1.positionScreen.z > 1 ) continue;
-					if ( _v2.positionScreen.z < - 1 || _v2.positionScreen.z > 1 ) continue;
-					if ( _v3.positionScreen.z < - 1 || _v3.positionScreen.z > 1 ) continue;
-					_v1.positionScreen.x *= _svgWidthHalf;
-					_v1.positionScreen.y *= - _svgHeightHalf;
-					_v2.positionScreen.x *= _svgWidthHalf;
-					_v2.positionScreen.y *= - _svgHeightHalf;
-					_v3.positionScreen.x *= _svgWidthHalf;
-					_v3.positionScreen.y *= - _svgHeightHalf;
+						if ( this.overdraw > 0 ) {
 
-					if ( this.overdraw > 0 ) {
+							expand( _v1.positionScreen, _v2.positionScreen, this.overdraw );
+							expand( _v2.positionScreen, _v3.positionScreen, this.overdraw );
+							expand( _v3.positionScreen, _v1.positionScreen, this.overdraw );
 
-						expand( _v1.positionScreen, _v2.positionScreen, this.overdraw );
-						expand( _v2.positionScreen, _v3.positionScreen, this.overdraw );
-						expand( _v3.positionScreen, _v1.positionScreen, this.overdraw );
+						}
 
-					}
+						_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen, _v3.positionScreen ] );
 
-					_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen, _v3.positionScreen ] );
+						if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
-					if ( _clipBox.intersectsBox( _elemBox ) === true ) {
+							renderFace3( _v1, _v2, _v3, element, material );
 
-						renderFace3( _v1, _v2, _v3, element, material );
+						}
 
 					}
 
 				}
 
-			}
+				flushPath(); // just to flush last svg:path
 
-			flushPath(); // just to flush last svg:path
+				scene.traverseVisible( function ( object ) {
 
-			scene.traverseVisible( function ( object ) {
+					if ( object.isSVGObject ) {
 
-				if ( object instanceof SVGObject ) {
+						_vector3.setFromMatrixPosition( object.matrixWorld );
 
-					_vector3.setFromMatrixPosition( object.matrixWorld );
+						_vector3.applyMatrix4( _viewProjectionMatrix );
 
-					_vector3.applyMatrix4( _viewProjectionMatrix );
+						if ( _vector3.z < - 1 || _vector3.z > 1 ) return;
+						const x = _vector3.x * _svgWidthHalf;
+						const y = - _vector3.y * _svgHeightHalf;
+						const node = object.node;
+						node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' );
 
-					if ( _vector3.z < - 1 || _vector3.z > 1 ) return;
-					var x = _vector3.x * _svgWidthHalf;
-					var y = - _vector3.y * _svgHeightHalf;
-					var node = object.node;
-					node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' );
+						_svg.appendChild( node );
 
-					_svg.appendChild( node );
+					}
 
-				}
+				} );
 
-			} );
+			};
 
-		};
+			function calculateLights( lights ) {
 
-		function calculateLights( lights ) {
+				_ambientLight.setRGB( 0, 0, 0 );
 
-			_ambientLight.setRGB( 0, 0, 0 );
+				_directionalLights.setRGB( 0, 0, 0 );
 
-			_directionalLights.setRGB( 0, 0, 0 );
+				_pointLights.setRGB( 0, 0, 0 );
 
-			_pointLights.setRGB( 0, 0, 0 );
+				for ( let l = 0, ll = lights.length; l < ll; l ++ ) {
 
-			for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
+					const light = lights[ l ];
+					const lightColor = light.color;
 
-				var light = lights[ l ];
-				var lightColor = light.color;
+					if ( light.isAmbientLight ) {
 
-				if ( light.isAmbientLight ) {
+						_ambientLight.r += lightColor.r;
+						_ambientLight.g += lightColor.g;
+						_ambientLight.b += lightColor.b;
 
-					_ambientLight.r += lightColor.r;
-					_ambientLight.g += lightColor.g;
-					_ambientLight.b += lightColor.b;
+					} else if ( light.isDirectionalLight ) {
 
-				} else if ( light.isDirectionalLight ) {
+						_directionalLights.r += lightColor.r;
+						_directionalLights.g += lightColor.g;
+						_directionalLights.b += lightColor.b;
 
-					_directionalLights.r += lightColor.r;
-					_directionalLights.g += lightColor.g;
-					_directionalLights.b += lightColor.b;
+					} else if ( light.isPointLight ) {
 
-				} else if ( light.isPointLight ) {
+						_pointLights.r += lightColor.r;
+						_pointLights.g += lightColor.g;
+						_pointLights.b += lightColor.b;
 
-					_pointLights.r += lightColor.r;
-					_pointLights.g += lightColor.g;
-					_pointLights.b += lightColor.b;
+					}
 
 				}
 
 			}
 
-		}
+			function calculateLight( lights, position, normal, color ) {
 
-		function calculateLight( lights, position, normal, color ) {
+				for ( let l = 0, ll = lights.length; l < ll; l ++ ) {
 
-			for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
+					const light = lights[ l ];
+					const lightColor = light.color;
 
-				var light = lights[ l ];
-				var lightColor = light.color;
+					if ( light.isDirectionalLight ) {
 
-				if ( light.isDirectionalLight ) {
+						const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize();
 
-					var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize();
+						let amount = normal.dot( lightPosition );
+						if ( amount <= 0 ) continue;
+						amount *= light.intensity;
+						color.r += lightColor.r * amount;
+						color.g += lightColor.g * amount;
+						color.b += lightColor.b * amount;
 
-					var amount = normal.dot( lightPosition );
-					if ( amount <= 0 ) continue;
-					amount *= light.intensity;
-					color.r += lightColor.r * amount;
-					color.g += lightColor.g * amount;
-					color.b += lightColor.b * amount;
+					} else if ( light.isPointLight ) {
 
-				} else if ( light.isPointLight ) {
+						const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld );
 
-					var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld );
+						let amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
+						if ( amount <= 0 ) continue;
+						amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
+						if ( amount == 0 ) continue;
+						amount *= light.intensity;
+						color.r += lightColor.r * amount;
+						color.g += lightColor.g * amount;
+						color.b += lightColor.b * amount;
 
-					var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
-					if ( amount <= 0 ) continue;
-					amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
-					if ( amount == 0 ) continue;
-					amount *= light.intensity;
-					color.r += lightColor.r * amount;
-					color.g += lightColor.g * amount;
-					color.b += lightColor.b * amount;
+					}
 
 				}
 
 			}
 
-		}
+			function renderSprite( v1, element, material ) {
 
-		function renderSprite( v1, element, material ) {
+				let scaleX = element.scale.x * _svgWidthHalf;
+				let scaleY = element.scale.y * _svgHeightHalf;
 
-			var scaleX = element.scale.x * _svgWidthHalf;
-			var scaleY = element.scale.y * _svgHeightHalf;
+				if ( material.isPointsMaterial ) {
 
-			if ( material.isPointsMaterial ) {
+					scaleX *= material.size;
+					scaleY *= material.size;
 
-				scaleX *= material.size;
-				scaleY *= material.size;
+				}
 
-			}
+				const path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert( - scaleX ) + 'z';
+				let style = '';
 
-			var path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert( - scaleX ) + 'z';
-			var style = '';
+				if ( material.isSpriteMaterial || material.isPointsMaterial ) {
 
-			if ( material.isSpriteMaterial || material.isPointsMaterial ) {
+					style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity;
+
+				}
 
-				style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity;
+				addPath( style, path );
 
 			}
 
-			addPath( style, path );
+			function renderLine( v1, v2, element, material ) {
 
-		}
+				const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y );
 
-		function renderLine( v1, v2, element, material ) {
+				if ( material.isLineBasicMaterial ) {
 
-			var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y );
+					let style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
 
-			if ( material.isLineBasicMaterial ) {
+					if ( material.isLineDashedMaterial ) {
 
-				var style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
+						style = style + ';stroke-dasharray:' + material.dashSize + ',' + material.gapSize;
 
-				if ( material.isLineDashedMaterial ) {
+					}
 
-					style = style + ';stroke-dasharray:' + material.dashSize + ',' + material.gapSize;
+					addPath( style, path );
 
 				}
 
-				addPath( style, path );
-
 			}
 
-		}
+			function renderFace3( v1, v2, v3, element, material ) {
 
-		function renderFace3( v1, v2, v3, element, material ) {
+				_this.info.render.vertices += 3;
+				_this.info.render.faces ++;
+				const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z';
+				let style = '';
 
-			_this.info.render.vertices += 3;
-			_this.info.render.faces ++;
-			var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z';
-			var style = '';
+				if ( material.isMeshBasicMaterial ) {
 
-			if ( material.isMeshBasicMaterial ) {
+					_color.copy( material.color );
 
-				_color.copy( material.color );
+					if ( material.vertexColors ) {
 
-				if ( material.vertexColors ) {
+						_color.multiply( element.color );
 
-					_color.multiply( element.color );
+					}
 
-				}
+				} else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial ) {
 
-			} else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial ) {
+					_diffuseColor.copy( material.color );
 
-				_diffuseColor.copy( material.color );
+					if ( material.vertexColors ) {
 
-				if ( material.vertexColors ) {
+						_diffuseColor.multiply( element.color );
 
-					_diffuseColor.multiply( element.color );
+					}
 
-				}
+					_color.copy( _ambientLight );
 
-				_color.copy( _ambientLight );
+					_centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 );
 
-				_centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 );
+					calculateLight( _lights, _centroid, element.normalModel, _color );
 
-				calculateLight( _lights, _centroid, element.normalModel, _color );
+					_color.multiply( _diffuseColor ).add( material.emissive );
 
-				_color.multiply( _diffuseColor ).add( material.emissive );
+				} else if ( material.isMeshNormalMaterial ) {
 
-			} else if ( material.isMeshNormalMaterial ) {
+					_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
 
-				_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
+					_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-				_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+				}
 
-			}
+				if ( material.wireframe ) {
 
-			if ( material.wireframe ) {
+					style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
 
-				style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
+				} else {
 
-			} else {
+					style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity;
 
-				style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity;
+				}
 
-			}
+				addPath( style, path );
 
-			addPath( style, path );
+			} // Hide anti-alias gaps
 
-		} // Hide anti-alias gaps
 
+			function expand( v1, v2, pixels ) {
 
-		function expand( v1, v2, pixels ) {
+				let x = v2.x - v1.x,
+					y = v2.y - v1.y;
+				const det = x * x + y * y;
+				if ( det === 0 ) return;
+				const idet = pixels / Math.sqrt( det );
+				x *= idet;
+				y *= idet;
+				v2.x += x;
+				v2.y += y;
+				v1.x -= x;
+				v1.y -= y;
 
-			var x = v2.x - v1.x,
-				y = v2.y - v1.y,
-				det = x * x + y * y,
-				idet;
-			if ( det === 0 ) return;
-			idet = pixels / Math.sqrt( det );
-			x *= idet;
-			y *= idet;
-			v2.x += x;
-			v2.y += y;
-			v1.x -= x;
-			v1.y -= y;
+			}
 
-		}
+			function addPath( style, path ) {
 
-		function addPath( style, path ) {
+				if ( _currentStyle === style ) {
 
-			if ( _currentStyle === style ) {
+					_currentPath += path;
 
-				_currentPath += path;
+				} else {
 
-			} else {
+					flushPath();
+					_currentStyle = style;
+					_currentPath = path;
 
-				flushPath();
-				_currentStyle = style;
-				_currentPath = path;
+				}
 
 			}
 
-		}
+			function flushPath() {
+
+				if ( _currentPath ) {
 
-		function flushPath() {
+					_svgNode = getPathNode( _pathCount ++ );
 
-			if ( _currentPath ) {
+					_svgNode.setAttribute( 'd', _currentPath );
 
-				_svgNode = getPathNode( _pathCount ++ );
+					_svgNode.setAttribute( 'style', _currentStyle );
 
-				_svgNode.setAttribute( 'd', _currentPath );
+					_svg.appendChild( _svgNode );
 
-				_svgNode.setAttribute( 'style', _currentStyle );
+				}
 
-				_svg.appendChild( _svgNode );
+				_currentPath = '';
+				_currentStyle = '';
 
 			}
 
-			_currentPath = '';
-			_currentStyle = '';
+			function getPathNode( id ) {
 
-		}
+				if ( _svgPathPool[ id ] == null ) {
 
-		function getPathNode( id ) {
+					_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
 
-			if ( _svgPathPool[ id ] == null ) {
+					if ( _quality == 0 ) {
 
-				_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
+						_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
 
-				if ( _quality == 0 ) {
+					}
 
-					_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
+					return _svgPathPool[ id ];
 
 				}
 
@@ -519,11 +528,9 @@
 
 			}
 
-			return _svgPathPool[ id ];
-
 		}
 
-	};
+	}
 
 	THREE.SVGObject = SVGObject;
 	THREE.SVGRenderer = SVGRenderer;

+ 107 - 108
examples/jsm/renderers/CSS2DRenderer.js

@@ -4,37 +4,35 @@ import {
 	Vector3
 } from '../../../build/three.module.js';
 
-var CSS2DObject = function ( element ) {
+class CSS2DObject extends Object3D {
 
-	Object3D.call( this );
+ 	constructor( element ) {
 
-	this.element = element || document.createElement( 'div' );
+		super();
 
-	this.element.style.position = 'absolute';
+		this.element = element || document.createElement( 'div' );
 
-	this.addEventListener( 'removed', function () {
+		this.element.style.position = 'absolute';
 
-		this.traverse( function ( object ) {
+		this.addEventListener( 'removed', function () {
 
-			if ( object.element instanceof Element && object.element.parentNode !== null ) {
+			this.traverse( function ( object ) {
 
-				object.element.parentNode.removeChild( object.element );
+				if ( object.element instanceof Element && object.element.parentNode !== null ) {
 
-			}
-
-		} );
+					object.element.parentNode.removeChild( object.element );
 
-	} );
+				}
 
-};
+			} );
 
-CSS2DObject.prototype = Object.assign( Object.create( Object3D.prototype ), {
+		} );
 
-	constructor: CSS2DObject,
+	}
 
-	copy: function ( source, recursive ) {
+	copy( source, recursive ) {
 
-		Object3D.prototype.copy.call( this, source, recursive );
+		super.copy( source, recursive );
 
 		this.element = source.element.cloneNode( true );
 
@@ -42,164 +40,165 @@ CSS2DObject.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 	}
 
-} );
+}
+
+CSS2DObject.prototype.isCSS2DObject = true;
 
 //
 
-var CSS2DRenderer = function () {
+const _vector = new Vector3();
+const _viewMatrix = new Matrix4();
+const _viewProjectionMatrix = new Matrix4();
+const _a = new Vector3();
+const _b = new Vector3();
 
-	var _this = this;
+class CSS2DRenderer {
 
-	var _width, _height;
-	var _widthHalf, _heightHalf;
+	constructor() {
 
-	var vector = new Vector3();
-	var viewMatrix = new Matrix4();
-	var viewProjectionMatrix = new Matrix4();
+		const _this = this;
 
-	var cache = {
-		objects: new WeakMap()
-	};
+		let _width, _height;
+		let _widthHalf, _heightHalf;
 
-	var domElement = document.createElement( 'div' );
-	domElement.style.overflow = 'hidden';
+		const cache = {
+			objects: new WeakMap()
+		};
 
-	this.domElement = domElement;
+		const domElement = document.createElement( 'div' );
+		domElement.style.overflow = 'hidden';
 
-	this.getSize = function () {
+		this.domElement = domElement;
 
-		return {
-			width: _width,
-			height: _height
-		};
+		this.getSize = function () {
 
-	};
-
-	this.setSize = function ( width, height ) {
+			return {
+				width: _width,
+				height: _height
+			};
 
-		_width = width;
-		_height = height;
+		};
 
-		_widthHalf = _width / 2;
-		_heightHalf = _height / 2;
+		this.render = function ( scene, camera ) {
 
-		domElement.style.width = width + 'px';
-		domElement.style.height = height + 'px';
+			if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
+			if ( camera.parent === null ) camera.updateMatrixWorld();
 
-	};
+			_viewMatrix.copy( camera.matrixWorldInverse );
+			_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
 
-	var renderObject = function ( object, scene, camera ) {
+			renderObject( scene, scene, camera );
+			zOrder( scene );
 
-		if ( object instanceof CSS2DObject ) {
+		};
 
-			object.onBeforeRender( _this, scene, camera );
+		this.setSize = function ( width, height ) {
 
-			vector.setFromMatrixPosition( object.matrixWorld );
-			vector.applyMatrix4( viewProjectionMatrix );
+			_width = width;
+			_height = height;
 
-			var element = object.element;
+			_widthHalf = _width / 2;
+			_heightHalf = _height / 2;
 
-			if ( /apple/i.test( navigator.vendor ) ) {
+			domElement.style.width = width + 'px';
+			domElement.style.height = height + 'px';
 
-				// https://github.com/mrdoob/three.js/issues/21415
-				element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - vector.y * _heightHalf + _heightHalf ) + 'px)';
+		};
 
-			} else {
+		function renderObject( object, scene, camera ) {
 
-				element.style.transform = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';
+			if ( object.isCSS2DObject ) {
 
-			}
+				object.onBeforeRender( _this, scene, camera );
 
-			element.style.display = ( object.visible && vector.z >= - 1 && vector.z <= 1 ) ? '' : 'none';
+				_vector.setFromMatrixPosition( object.matrixWorld );
+				_vector.applyMatrix4( _viewProjectionMatrix );
 
-			var objectData = {
-				distanceToCameraSquared: getDistanceToSquared( camera, object )
-			};
+				const element = object.element;
 
-			cache.objects.set( object, objectData );
+				if ( /apple/i.test( navigator.vendor ) ) {
 
-			if ( element.parentNode !== domElement ) {
+					// https://github.com/mrdoob/three.js/issues/21415
+					element.style.transform = 'translate(-50%,-50%) translate(' + Math.round( _vector.x * _widthHalf + _widthHalf ) + 'px,' + Math.round( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
 
-				domElement.appendChild( element );
+				} else {
 
-			}
+					element.style.transform = 'translate(-50%,-50%) translate(' + ( _vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - _vector.y * _heightHalf + _heightHalf ) + 'px)';
 
-			object.onAfterRender( _this, scene, camera );
+				}
 
-		}
+				element.style.display = ( object.visible && _vector.z >= - 1 && _vector.z <= 1 ) ? '' : 'none';
 
-		for ( var i = 0, l = object.children.length; i < l; i ++ ) {
+				const objectData = {
+					distanceToCameraSquared: getDistanceToSquared( camera, object )
+				};
 
-			renderObject( object.children[ i ], scene, camera );
+				cache.objects.set( object, objectData );
 
-		}
+				if ( element.parentNode !== domElement ) {
 
-	};
+					domElement.appendChild( element );
 
-	var getDistanceToSquared = function () {
+				}
 
-		var a = new Vector3();
-		var b = new Vector3();
+				object.onAfterRender( _this, scene, camera );
 
-		return function ( object1, object2 ) {
+			}
 
-			a.setFromMatrixPosition( object1.matrixWorld );
-			b.setFromMatrixPosition( object2.matrixWorld );
+			for ( let i = 0, l = object.children.length; i < l; i ++ ) {
 
-			return a.distanceToSquared( b );
+				renderObject( object.children[ i ], scene, camera );
 
-		};
+			}
 
-	}();
+		}
 
-	var filterAndFlatten = function ( scene ) {
+		function getDistanceToSquared( object1, object2 ) {
 
-		var result = [];
+			_a.setFromMatrixPosition( object1.matrixWorld );
+			_b.setFromMatrixPosition( object2.matrixWorld );
 
-		scene.traverse( function ( object ) {
+			return _a.distanceToSquared( _b );
 
-			if ( object instanceof CSS2DObject ) result.push( object );
+		}
 
-		} );
+		function filterAndFlatten( scene ) {
 
-		return result;
+			const result = [];
 
-	};
+			scene.traverse( function ( object ) {
 
-	var zOrder = function ( scene ) {
+				if ( object.isCSS2DObject ) result.push( object );
 
-		var sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
+			} );
 
-			var distanceA = cache.objects.get( a ).distanceToCameraSquared;
-			var distanceB = cache.objects.get( b ).distanceToCameraSquared;
+			return result;
 
-			return distanceA - distanceB;
+		}
 
-		} );
+		function zOrder( scene ) {
 
-		var zMax = sorted.length;
+			const sorted = filterAndFlatten( scene ).sort( function ( a, b ) {
 
-		for ( var i = 0, l = sorted.length; i < l; i ++ ) {
+				const distanceA = cache.objects.get( a ).distanceToCameraSquared;
+				const distanceB = cache.objects.get( b ).distanceToCameraSquared;
 
-			sorted[ i ].element.style.zIndex = zMax - i;
+				return distanceA - distanceB;
 
-		}
+			} );
 
-	};
+			const zMax = sorted.length;
 
-	this.render = function ( scene, camera ) {
+			for ( let i = 0, l = sorted.length; i < l; i ++ ) {
 
-		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
-		if ( camera.parent === null ) camera.updateMatrixWorld();
+				sorted[ i ].element.style.zIndex = zMax - i;
 
-		viewMatrix.copy( camera.matrixWorldInverse );
-		viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );
+			}
 
-		renderObject( scene, scene, camera );
-		zOrder( scene );
+		}
 
-	};
+	}
 
-};
+}
 
 export { CSS2DObject, CSS2DRenderer };

+ 173 - 164
examples/jsm/renderers/CSS3DRenderer.js

@@ -7,37 +7,35 @@ import {
  * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs
  */
 
-var CSS3DObject = function ( element ) {
+class CSS3DObject extends Object3D {
 
-	Object3D.call( this );
+	constructor( element ) {
 
-	this.element = element || document.createElement( 'div' );
-	this.element.style.position = 'absolute';
-	this.element.style.pointerEvents = 'auto';
+		super();
 
-	this.addEventListener( 'removed', function () {
+		this.element = element || document.createElement( 'div' );
+		this.element.style.position = 'absolute';
+		this.element.style.pointerEvents = 'auto';
 
-		this.traverse( function ( object ) {
+		this.addEventListener( 'removed', function () {
 
-			if ( object.element instanceof Element && object.element.parentNode !== null ) {
+			this.traverse( function ( object ) {
 
-				object.element.parentNode.removeChild( object.element );
+				if ( object.element instanceof Element && object.element.parentNode !== null ) {
 
-			}
-
-		} );
+					object.element.parentNode.removeChild( object.element );
 
-	} );
+				}
 
-};
+			} );
 
-CSS3DObject.prototype = Object.assign( Object.create( Object3D.prototype ), {
+		} );
 
-	constructor: CSS3DObject,
+	}
 
-	copy: function ( source, recursive ) {
+	copy( source, recursive ) {
 
-		Object3D.prototype.copy.call( this, source, recursive );
+		super.copy( source, recursive );
 
 		this.element = source.element.cloneNode( true );
 
@@ -45,228 +43,239 @@ CSS3DObject.prototype = Object.assign( Object.create( Object3D.prototype ), {
 
 	}
 
-} );
+}
 
-var CSS3DSprite = function ( element ) {
+CSS3DObject.prototype.isCSS3DObject = true;
 
-	CSS3DObject.call( this, element );
+class CSS3DSprite extends CSS3DObject {
 
-};
+	constructor( element ) {
 
-CSS3DSprite.prototype = Object.create( CSS3DObject.prototype );
-CSS3DSprite.prototype.constructor = CSS3DSprite;
+		super( element );
+
+	}
+
+}
+
+CSS3DSprite.prototype.isCSS3DSprite = true;
 
 //
 
-var CSS3DRenderer = function () {
+const _matrix = new Matrix4();
 
-	var _this = this;
+class CSS3DRenderer {
 
-	var _width, _height;
-	var _widthHalf, _heightHalf;
+	constructor() {
 
-	var matrix = new Matrix4();
+		const _this = this;
 
-	var cache = {
-		camera: { fov: 0, style: '' },
-		objects: new WeakMap()
-	};
+		let _width, _height;
+		let _widthHalf, _heightHalf;
 
-	var domElement = document.createElement( 'div' );
-	domElement.style.overflow = 'hidden';
+		const cache = {
+			camera: { fov: 0, style: '' },
+			objects: new WeakMap()
+		};
 
-	this.domElement = domElement;
+		const domElement = document.createElement( 'div' );
+		domElement.style.overflow = 'hidden';
 
-	var cameraElement = document.createElement( 'div' );
+		this.domElement = domElement;
 
-	cameraElement.style.transformStyle = 'preserve-3d';
-	cameraElement.style.pointerEvents = 'none';
+		const cameraElement = document.createElement( 'div' );
 
-	domElement.appendChild( cameraElement );
+		cameraElement.style.transformStyle = 'preserve-3d';
+		cameraElement.style.pointerEvents = 'none';
 
-	this.getSize = function () {
+		domElement.appendChild( cameraElement );
+
+		this.getSize = function () {
+
+			return {
+				width: _width,
+				height: _height
+			};
 
-		return {
-			width: _width,
-			height: _height
 		};
 
-	};
+		this.render = function ( scene, camera ) {
 
-	this.setSize = function ( width, height ) {
+			const fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;
 
-		_width = width;
-		_height = height;
-		_widthHalf = _width / 2;
-		_heightHalf = _height / 2;
+			if ( cache.camera.fov !== fov ) {
 
-		domElement.style.width = width + 'px';
-		domElement.style.height = height + 'px';
+				domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : '';
+				cache.camera.fov = fov;
 
-		cameraElement.style.width = width + 'px';
-		cameraElement.style.height = height + 'px';
+			}
 
-	};
+			if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
+			if ( camera.parent === null ) camera.updateMatrixWorld();
 
-	function epsilon( value ) {
+			let tx, ty;
 
-		return Math.abs( value ) < 1e-10 ? 0 : value;
+			if ( camera.isOrthographicCamera ) {
 
-	}
+				tx = - ( camera.right + camera.left ) / 2;
+				ty = ( camera.top + camera.bottom ) / 2;
 
-	function getCameraCSSMatrix( matrix ) {
-
-		var elements = matrix.elements;
-
-		return 'matrix3d(' +
-			epsilon( elements[ 0 ] ) + ',' +
-			epsilon( - elements[ 1 ] ) + ',' +
-			epsilon( elements[ 2 ] ) + ',' +
-			epsilon( elements[ 3 ] ) + ',' +
-			epsilon( elements[ 4 ] ) + ',' +
-			epsilon( - elements[ 5 ] ) + ',' +
-			epsilon( elements[ 6 ] ) + ',' +
-			epsilon( elements[ 7 ] ) + ',' +
-			epsilon( elements[ 8 ] ) + ',' +
-			epsilon( - elements[ 9 ] ) + ',' +
-			epsilon( elements[ 10 ] ) + ',' +
-			epsilon( elements[ 11 ] ) + ',' +
-			epsilon( elements[ 12 ] ) + ',' +
-			epsilon( - elements[ 13 ] ) + ',' +
-			epsilon( elements[ 14 ] ) + ',' +
-			epsilon( elements[ 15 ] ) +
-		')';
+			}
 
-	}
+			const cameraCSSMatrix = camera.isOrthographicCamera ?
+				'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
+				'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
 
-	function getObjectCSSMatrix( matrix ) {
-
-		var elements = matrix.elements;
-		var matrix3d = 'matrix3d(' +
-			epsilon( elements[ 0 ] ) + ',' +
-			epsilon( elements[ 1 ] ) + ',' +
-			epsilon( elements[ 2 ] ) + ',' +
-			epsilon( elements[ 3 ] ) + ',' +
-			epsilon( - elements[ 4 ] ) + ',' +
-			epsilon( - elements[ 5 ] ) + ',' +
-			epsilon( - elements[ 6 ] ) + ',' +
-			epsilon( - elements[ 7 ] ) + ',' +
-			epsilon( elements[ 8 ] ) + ',' +
-			epsilon( elements[ 9 ] ) + ',' +
-			epsilon( elements[ 10 ] ) + ',' +
-			epsilon( elements[ 11 ] ) + ',' +
-			epsilon( elements[ 12 ] ) + ',' +
-			epsilon( elements[ 13 ] ) + ',' +
-			epsilon( elements[ 14 ] ) + ',' +
-			epsilon( elements[ 15 ] ) +
-		')';
-
-		return 'translate(-50%,-50%)' + matrix3d;
+			const style = cameraCSSMatrix +
+				'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';
 
-	}
+			if ( cache.camera.style !== style ) {
 
-	function renderObject( object, scene, camera, cameraCSSMatrix ) {
+				cameraElement.style.transform = style;
 
-		if ( object instanceof CSS3DObject ) {
+				cache.camera.style = style;
 
-			object.onBeforeRender( _this, scene, camera );
+			}
 
-			var style;
+			renderObject( scene, scene, camera, cameraCSSMatrix );
 
-			if ( object instanceof CSS3DSprite ) {
+		};
 
-				// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
+		this.setSize = function ( width, height ) {
 
-				matrix.copy( camera.matrixWorldInverse );
-				matrix.transpose();
-				matrix.copyPosition( object.matrixWorld );
-				matrix.scale( object.scale );
+			_width = width;
+			_height = height;
+			_widthHalf = _width / 2;
+			_heightHalf = _height / 2;
 
-				matrix.elements[ 3 ] = 0;
-				matrix.elements[ 7 ] = 0;
-				matrix.elements[ 11 ] = 0;
-				matrix.elements[ 15 ] = 1;
+			domElement.style.width = width + 'px';
+			domElement.style.height = height + 'px';
 
-				style = getObjectCSSMatrix( matrix );
+			cameraElement.style.width = width + 'px';
+			cameraElement.style.height = height + 'px';
 
-			} else {
+		};
 
-				style = getObjectCSSMatrix( object.matrixWorld );
+		function epsilon( value ) {
 
-			}
+			return Math.abs( value ) < 1e-10 ? 0 : value;
 
-			var element = object.element;
-			var cachedObject = cache.objects.get( object );
+		}
 
-			if ( cachedObject === undefined || cachedObject.style !== style ) {
+		function getCameraCSSMatrix( matrix ) {
+
+			const elements = matrix.elements;
+
+			return 'matrix3d(' +
+				epsilon( elements[ 0 ] ) + ',' +
+				epsilon( - elements[ 1 ] ) + ',' +
+				epsilon( elements[ 2 ] ) + ',' +
+				epsilon( elements[ 3 ] ) + ',' +
+				epsilon( elements[ 4 ] ) + ',' +
+				epsilon( - elements[ 5 ] ) + ',' +
+				epsilon( elements[ 6 ] ) + ',' +
+				epsilon( elements[ 7 ] ) + ',' +
+				epsilon( elements[ 8 ] ) + ',' +
+				epsilon( - elements[ 9 ] ) + ',' +
+				epsilon( elements[ 10 ] ) + ',' +
+				epsilon( elements[ 11 ] ) + ',' +
+				epsilon( elements[ 12 ] ) + ',' +
+				epsilon( - elements[ 13 ] ) + ',' +
+				epsilon( elements[ 14 ] ) + ',' +
+				epsilon( elements[ 15 ] ) +
+			')';
 
-				element.style.transform = style;
+		}
 
-				var objectData = { style: style };
-				cache.objects.set( object, objectData );
+		function getObjectCSSMatrix( matrix ) {
+
+			const elements = matrix.elements;
+			const matrix3d = 'matrix3d(' +
+				epsilon( elements[ 0 ] ) + ',' +
+				epsilon( elements[ 1 ] ) + ',' +
+				epsilon( elements[ 2 ] ) + ',' +
+				epsilon( elements[ 3 ] ) + ',' +
+				epsilon( - elements[ 4 ] ) + ',' +
+				epsilon( - elements[ 5 ] ) + ',' +
+				epsilon( - elements[ 6 ] ) + ',' +
+				epsilon( - elements[ 7 ] ) + ',' +
+				epsilon( elements[ 8 ] ) + ',' +
+				epsilon( elements[ 9 ] ) + ',' +
+				epsilon( elements[ 10 ] ) + ',' +
+				epsilon( elements[ 11 ] ) + ',' +
+				epsilon( elements[ 12 ] ) + ',' +
+				epsilon( elements[ 13 ] ) + ',' +
+				epsilon( elements[ 14 ] ) + ',' +
+				epsilon( elements[ 15 ] ) +
+			')';
+
+			return 'translate(-50%,-50%)' + matrix3d;
 
-			}
+		}
 
-			element.style.display = object.visible ? '' : 'none';
+		function renderObject( object, scene, camera, cameraCSSMatrix ) {
 
-			if ( element.parentNode !== cameraElement ) {
+			if ( object.isCSS3DObject ) {
 
-				cameraElement.appendChild( element );
+				object.onBeforeRender( _this, scene, camera );
 
-			}
+				let style;
 
-			object.onAfterRender( _this, scene, camera );
+				if ( object.isCSS3DSprite ) {
 
-		}
+					// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/
 
-		for ( var i = 0, l = object.children.length; i < l; i ++ ) {
+					_matrix.copy( camera.matrixWorldInverse );
+					_matrix.transpose();
+					_matrix.copyPosition( object.matrixWorld );
+					_matrix.scale( object.scale );
 
-			renderObject( object.children[ i ], scene, camera, cameraCSSMatrix );
+					_matrix.elements[ 3 ] = 0;
+					_matrix.elements[ 7 ] = 0;
+					_matrix.elements[ 11 ] = 0;
+					_matrix.elements[ 15 ] = 1;
 
-		}
+					style = getObjectCSSMatrix( _matrix );
 
-	}
+				} else {
 
-	this.render = function ( scene, camera ) {
+					style = getObjectCSSMatrix( object.matrixWorld );
 
-		var fov = camera.projectionMatrix.elements[ 5 ] * _heightHalf;
+				}
 
-		if ( cache.camera.fov !== fov ) {
+				const element = object.element;
+				const cachedObject = cache.objects.get( object );
 
-			domElement.style.perspective = camera.isPerspectiveCamera ? fov + 'px' : '';
-			cache.camera.fov = fov;
+				if ( cachedObject === undefined || cachedObject.style !== style ) {
 
-		}
+					element.style.transform = style;
 
-		if ( scene.autoUpdate === true ) scene.updateMatrixWorld();
-		if ( camera.parent === null ) camera.updateMatrixWorld();
+					const objectData = { style: style };
+					cache.objects.set( object, objectData );
 
-		if ( camera.isOrthographicCamera ) {
+				}
 
-			var tx = - ( camera.right + camera.left ) / 2;
-			var ty = ( camera.top + camera.bottom ) / 2;
+				element.style.display = object.visible ? '' : 'none';
 
-		}
+				if ( element.parentNode !== cameraElement ) {
 
-		var cameraCSSMatrix = camera.isOrthographicCamera ?
-			'scale(' + fov + ')' + 'translate(' + epsilon( tx ) + 'px,' + epsilon( ty ) + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) :
-			'translateZ(' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse );
+					cameraElement.appendChild( element );
 
-		var style = cameraCSSMatrix +
-			'translate(' + _widthHalf + 'px,' + _heightHalf + 'px)';
+				}
 
-		if ( cache.camera.style !== style ) {
+				object.onAfterRender( _this, scene, camera );
 
-			cameraElement.style.transform = style;
+			}
 
-			cache.camera.style = style;
+			for ( let i = 0, l = object.children.length; i < l; i ++ ) {
 
-		}
+				renderObject( object.children[ i ], scene, camera, cameraCSSMatrix );
 
-		renderObject( scene, scene, camera, cameraCSSMatrix );
+			}
+
+		}
 
-	};
+	}
 
-};
+}
 
 export { CSS3DObject, CSS3DSprite, CSS3DRenderer };

文件差异内容过多而无法显示
+ 533 - 505
examples/jsm/renderers/Projector.js


+ 298 - 287
examples/jsm/renderers/SVGRenderer.js

@@ -12,520 +12,533 @@ import { RenderableFace } from '../renderers/Projector.js';
 import { RenderableLine } from '../renderers/Projector.js';
 import { RenderableSprite } from '../renderers/Projector.js';
 
-var SVGObject = function ( node ) {
+class SVGObject extends Object3D {
 
-	Object3D.call( this );
+	constructor( node ) {
 
-	this.node = node;
+		super();
 
-};
+		this.node = node;
 
-SVGObject.prototype = Object.create( Object3D.prototype );
-SVGObject.prototype.constructor = SVGObject;
+	}
 
-var SVGRenderer = function () {
+}
 
-	var _this = this,
-		_renderData, _elements, _lights,
-		_projector = new Projector(),
-		_svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' ),
-		_svgWidth, _svgHeight, _svgWidthHalf, _svgHeightHalf,
+SVGObject.prototype.isSVGObject = true;
 
-		_v1, _v2, _v3,
+class SVGRenderer {
 
-		_clipBox = new Box2(),
-		_elemBox = new Box2(),
+	constructor() {
 
-		_color = new Color(),
-		_diffuseColor = new Color(),
-		_ambientLight = new Color(),
-		_directionalLights = new Color(),
-		_pointLights = new Color(),
-		_clearColor = new Color(),
+		let _renderData, _elements, _lights,
+			_svgWidth, _svgHeight, _svgWidthHalf, _svgHeightHalf,
 
-		_vector3 = new Vector3(), // Needed for PointLight
-		_centroid = new Vector3(),
-		_normal = new Vector3(),
-		_normalViewMatrix = new Matrix3(),
+			_v1, _v2, _v3,
 
-		_viewMatrix = new Matrix4(),
-		_viewProjectionMatrix = new Matrix4(),
+			_svgNode,
+			_pathCount = 0,
 
-		_svgPathPool = [],
-		_svgNode, _pathCount = 0,
+			_precision = null,
+			_quality = 1,
 
-		_currentPath, _currentStyle,
+			_currentPath, _currentStyle;
 
-		_quality = 1, _precision = null;
+		const _this = this,
+			_clipBox = new Box2(),
+			_elemBox = new Box2(),
 
-	this.domElement = _svg;
+			_color = new Color(),
+			_diffuseColor = new Color(),
+			_ambientLight = new Color(),
+			_directionalLights = new Color(),
+			_pointLights = new Color(),
+			_clearColor = new Color(),
 
-	this.autoClear = true;
-	this.sortObjects = true;
-	this.sortElements = true;
+			_vector3 = new Vector3(), // Needed for PointLight
+			_centroid = new Vector3(),
+			_normal = new Vector3(),
+			_normalViewMatrix = new Matrix3(),
 
-	this.overdraw = 0.5;
+			_viewMatrix = new Matrix4(),
+			_viewProjectionMatrix = new Matrix4(),
 
-	this.info = {
+			_svgPathPool = [],
 
-		render: {
+			_projector = new Projector(),
+			_svg = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );
 
-			vertices: 0,
-			faces: 0
+		this.domElement = _svg;
 
-		}
+		this.autoClear = true;
+		this.sortObjects = true;
+		this.sortElements = true;
 
-	};
+		this.overdraw = 0.5;
 
-	this.setQuality = function ( quality ) {
+		this.info = {
 
-		switch ( quality ) {
+			render: {
 
-			case 'high': _quality = 1; break;
-			case 'low': _quality = 0; break;
+				vertices: 0,
+				faces: 0
 
-		}
+			}
 
-	};
+		};
 
-	this.setClearColor = function ( color ) {
+		this.setQuality = function ( quality ) {
 
-		_clearColor.set( color );
+			switch ( quality ) {
 
-	};
+				case 'high': _quality = 1; break;
+				case 'low': _quality = 0; break;
 
-	this.setPixelRatio = function () {};
+			}
+
+		};
 
-	this.setSize = function ( width, height ) {
+		this.setClearColor = function ( color ) {
 
-		_svgWidth = width; _svgHeight = height;
-		_svgWidthHalf = _svgWidth / 2; _svgHeightHalf = _svgHeight / 2;
+			_clearColor.set( color );
 
-		_svg.setAttribute( 'viewBox', ( - _svgWidthHalf ) + ' ' + ( - _svgHeightHalf ) + ' ' + _svgWidth + ' ' + _svgHeight );
-		_svg.setAttribute( 'width', _svgWidth );
-		_svg.setAttribute( 'height', _svgHeight );
+		};
 
-		_clipBox.min.set( - _svgWidthHalf, - _svgHeightHalf );
-		_clipBox.max.set( _svgWidthHalf, _svgHeightHalf );
+		this.setPixelRatio = function () {};
 
-	};
+		this.setSize = function ( width, height ) {
 
-	this.getSize = function () {
+			_svgWidth = width; _svgHeight = height;
+			_svgWidthHalf = _svgWidth / 2; _svgHeightHalf = _svgHeight / 2;
+
+			_svg.setAttribute( 'viewBox', ( - _svgWidthHalf ) + ' ' + ( - _svgHeightHalf ) + ' ' + _svgWidth + ' ' + _svgHeight );
+			_svg.setAttribute( 'width', _svgWidth );
+			_svg.setAttribute( 'height', _svgHeight );
+
+			_clipBox.min.set( - _svgWidthHalf, - _svgHeightHalf );
+			_clipBox.max.set( _svgWidthHalf, _svgHeightHalf );
+
+		};
+
+		this.getSize = function () {
+
+			return {
+				width: _svgWidth,
+				height: _svgHeight
+			};
 
-		return {
-			width: _svgWidth,
-			height: _svgHeight
 		};
 
-	};
+		this.setPrecision = function ( precision ) {
 
-	this.setPrecision = function ( precision ) {
+			_precision = precision;
 
-		_precision = precision;
+		};
 
-	};
+		function removeChildNodes() {
 
-	function removeChildNodes() {
+			_pathCount = 0;
 
-		_pathCount = 0;
+			while ( _svg.childNodes.length > 0 ) {
 
-		while ( _svg.childNodes.length > 0 ) {
+				_svg.removeChild( _svg.childNodes[ 0 ] );
 
-			_svg.removeChild( _svg.childNodes[ 0 ] );
+			}
 
 		}
 
-	}
+		function convert( c ) {
 
-	function convert( c ) {
+			return _precision !== null ? c.toFixed( _precision ) : c;
 
-		return _precision !== null ? c.toFixed( _precision ) : c;
+		}
 
-	}
+		this.clear = function () {
 
-	this.clear = function () {
+			removeChildNodes();
+			_svg.style.backgroundColor = _clearColor.getStyle();
 
-		removeChildNodes();
-		_svg.style.backgroundColor = _clearColor.getStyle();
+		};
 
-	};
+		this.render = function ( scene, camera ) {
 
-	this.render = function ( scene, camera ) {
+			if ( camera instanceof Camera === false ) {
 
-		if ( camera instanceof Camera === false ) {
+				console.error( 'THREE.SVGRenderer.render: camera is not an instance of Camera.' );
+				return;
 
-			console.error( 'THREE.SVGRenderer.render: camera is not an instance of Camera.' );
-			return;
+			}
 
-		}
+			const background = scene.background;
 
-		var background = scene.background;
+			if ( background && background.isColor ) {
 
-		if ( background && background.isColor ) {
+				removeChildNodes();
+				_svg.style.backgroundColor = background.getStyle();
 
-			removeChildNodes();
-			_svg.style.backgroundColor = background.getStyle();
+			} else if ( this.autoClear === true ) {
 
-		} else if ( this.autoClear === true ) {
+				this.clear();
 
-			this.clear();
+			}
 
-		}
+			_this.info.render.vertices = 0;
+			_this.info.render.faces = 0;
 
-		_this.info.render.vertices = 0;
-		_this.info.render.faces = 0;
+			_viewMatrix.copy( camera.matrixWorldInverse );
+			_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
 
-		_viewMatrix.copy( camera.matrixWorldInverse );
-		_viewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, _viewMatrix );
+			_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
+			_elements = _renderData.elements;
+			_lights = _renderData.lights;
 
-		_renderData = _projector.projectScene( scene, camera, this.sortObjects, this.sortElements );
-		_elements = _renderData.elements;
-		_lights = _renderData.lights;
+			_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
 
-		_normalViewMatrix.getNormalMatrix( camera.matrixWorldInverse );
+			calculateLights( _lights );
 
-		calculateLights( _lights );
+			 // reset accumulated path
 
-		 // reset accumulated path
+			_currentPath = '';
+			_currentStyle = '';
 
-		_currentPath = '';
-		_currentStyle = '';
+			for ( let e = 0, el = _elements.length; e < el; e ++ ) {
 
-		for ( var e = 0, el = _elements.length; e < el; e ++ ) {
+				const element = _elements[ e ];
+				const material = element.material;
 
-			var element = _elements[ e ];
-			var material = element.material;
+				if ( material === undefined || material.opacity === 0 ) continue;
 
-			if ( material === undefined || material.opacity === 0 ) continue;
+				_elemBox.makeEmpty();
 
-			_elemBox.makeEmpty();
+				if ( element instanceof RenderableSprite ) {
 
-			if ( element instanceof RenderableSprite ) {
+					_v1 = element;
+					_v1.x *= _svgWidthHalf; _v1.y *= - _svgHeightHalf;
 
-				_v1 = element;
-				_v1.x *= _svgWidthHalf; _v1.y *= - _svgHeightHalf;
+					renderSprite( _v1, element, material );
 
-				renderSprite( _v1, element, material );
+				} else if ( element instanceof RenderableLine ) {
 
-			} else if ( element instanceof RenderableLine ) {
+					_v1 = element.v1; _v2 = element.v2;
 
-				_v1 = element.v1; _v2 = element.v2;
+					_v1.positionScreen.x *= _svgWidthHalf; _v1.positionScreen.y *= - _svgHeightHalf;
+					_v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf;
 
-				_v1.positionScreen.x *= _svgWidthHalf; _v1.positionScreen.y *= - _svgHeightHalf;
-				_v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf;
+					_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] );
 
-				_elemBox.setFromPoints( [ _v1.positionScreen, _v2.positionScreen ] );
+					if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
-				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
+						renderLine( _v1, _v2, element, material );
 
-					renderLine( _v1, _v2, element, material );
+					}
 
-				}
+				} else if ( element instanceof RenderableFace ) {
 
-			} else if ( element instanceof RenderableFace ) {
+					_v1 = element.v1; _v2 = element.v2; _v3 = element.v3;
 
-				_v1 = element.v1; _v2 = element.v2; _v3 = element.v3;
+					if ( _v1.positionScreen.z < - 1 || _v1.positionScreen.z > 1 ) continue;
+					if ( _v2.positionScreen.z < - 1 || _v2.positionScreen.z > 1 ) continue;
+					if ( _v3.positionScreen.z < - 1 || _v3.positionScreen.z > 1 ) continue;
 
-				if ( _v1.positionScreen.z < - 1 || _v1.positionScreen.z > 1 ) continue;
-				if ( _v2.positionScreen.z < - 1 || _v2.positionScreen.z > 1 ) continue;
-				if ( _v3.positionScreen.z < - 1 || _v3.positionScreen.z > 1 ) continue;
+					_v1.positionScreen.x *= _svgWidthHalf; _v1.positionScreen.y *= - _svgHeightHalf;
+					_v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf;
+					_v3.positionScreen.x *= _svgWidthHalf; _v3.positionScreen.y *= - _svgHeightHalf;
 
-				_v1.positionScreen.x *= _svgWidthHalf; _v1.positionScreen.y *= - _svgHeightHalf;
-				_v2.positionScreen.x *= _svgWidthHalf; _v2.positionScreen.y *= - _svgHeightHalf;
-				_v3.positionScreen.x *= _svgWidthHalf; _v3.positionScreen.y *= - _svgHeightHalf;
+					if ( this.overdraw > 0 ) {
 
-				if ( this.overdraw > 0 ) {
+						expand( _v1.positionScreen, _v2.positionScreen, this.overdraw );
+						expand( _v2.positionScreen, _v3.positionScreen, this.overdraw );
+						expand( _v3.positionScreen, _v1.positionScreen, this.overdraw );
 
-					expand( _v1.positionScreen, _v2.positionScreen, this.overdraw );
-					expand( _v2.positionScreen, _v3.positionScreen, this.overdraw );
-					expand( _v3.positionScreen, _v1.positionScreen, this.overdraw );
+					}
 
-				}
+					_elemBox.setFromPoints( [
+						_v1.positionScreen,
+						_v2.positionScreen,
+						_v3.positionScreen
+					] );
 
-				_elemBox.setFromPoints( [
-					_v1.positionScreen,
-					_v2.positionScreen,
-					_v3.positionScreen
-				] );
+					if ( _clipBox.intersectsBox( _elemBox ) === true ) {
 
-				if ( _clipBox.intersectsBox( _elemBox ) === true ) {
+						renderFace3( _v1, _v2, _v3, element, material );
 
-					renderFace3( _v1, _v2, _v3, element, material );
+					}
 
 				}
 
 			}
 
-		}
+			flushPath(); // just to flush last svg:path
 
-		flushPath(); // just to flush last svg:path
+			scene.traverseVisible( function ( object ) {
 
-		scene.traverseVisible( function ( object ) {
+				 if ( object.isSVGObject ) {
 
-			 if ( object instanceof SVGObject ) {
+					_vector3.setFromMatrixPosition( object.matrixWorld );
+					_vector3.applyMatrix4( _viewProjectionMatrix );
 
-				_vector3.setFromMatrixPosition( object.matrixWorld );
-				_vector3.applyMatrix4( _viewProjectionMatrix );
+					if ( _vector3.z < - 1 || _vector3.z > 1 ) return;
 
-				if ( _vector3.z < - 1 || _vector3.z > 1 ) return;
+					const x = _vector3.x * _svgWidthHalf;
+					const y = - _vector3.y * _svgHeightHalf;
 
-				var x = _vector3.x * _svgWidthHalf;
-				var y = - _vector3.y * _svgHeightHalf;
+					const node = object.node;
+					node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' );
 
-				var node = object.node;
-				node.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' );
+					_svg.appendChild( node );
 
-				_svg.appendChild( node );
+				}
 
-			}
+			} );
 
-		} );
+		};
 
-	};
+		function calculateLights( lights ) {
 
-	function calculateLights( lights ) {
+			_ambientLight.setRGB( 0, 0, 0 );
+			_directionalLights.setRGB( 0, 0, 0 );
+			_pointLights.setRGB( 0, 0, 0 );
 
-		_ambientLight.setRGB( 0, 0, 0 );
-		_directionalLights.setRGB( 0, 0, 0 );
-		_pointLights.setRGB( 0, 0, 0 );
+			for ( let l = 0, ll = lights.length; l < ll; l ++ ) {
 
-		for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
+				const light = lights[ l ];
+				const lightColor = light.color;
 
-			var light = lights[ l ];
-			var lightColor = light.color;
+				if ( light.isAmbientLight ) {
 
-			if ( light.isAmbientLight ) {
+					_ambientLight.r += lightColor.r;
+					_ambientLight.g += lightColor.g;
+					_ambientLight.b += lightColor.b;
 
-				_ambientLight.r += lightColor.r;
-				_ambientLight.g += lightColor.g;
-				_ambientLight.b += lightColor.b;
+				} else if ( light.isDirectionalLight ) {
 
-			} else if ( light.isDirectionalLight ) {
+					_directionalLights.r += lightColor.r;
+					_directionalLights.g += lightColor.g;
+					_directionalLights.b += lightColor.b;
 
-				_directionalLights.r += lightColor.r;
-				_directionalLights.g += lightColor.g;
-				_directionalLights.b += lightColor.b;
+				} else if ( light.isPointLight ) {
 
-			} else if ( light.isPointLight ) {
+					_pointLights.r += lightColor.r;
+					_pointLights.g += lightColor.g;
+					_pointLights.b += lightColor.b;
 
-				_pointLights.r += lightColor.r;
-				_pointLights.g += lightColor.g;
-				_pointLights.b += lightColor.b;
+				}
 
 			}
 
 		}
 
-	}
+		function calculateLight( lights, position, normal, color ) {
 
-	function calculateLight( lights, position, normal, color ) {
+			for ( let l = 0, ll = lights.length; l < ll; l ++ ) {
 
-		for ( var l = 0, ll = lights.length; l < ll; l ++ ) {
+				const light = lights[ l ];
+				const lightColor = light.color;
 
-			var light = lights[ l ];
-			var lightColor = light.color;
+				if ( light.isDirectionalLight ) {
 
-			if ( light.isDirectionalLight ) {
+					const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize();
 
-				var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld ).normalize();
+					let amount = normal.dot( lightPosition );
 
-				var amount = normal.dot( lightPosition );
+					if ( amount <= 0 ) continue;
 
-				if ( amount <= 0 ) continue;
+					amount *= light.intensity;
 
-				amount *= light.intensity;
+					color.r += lightColor.r * amount;
+					color.g += lightColor.g * amount;
+					color.b += lightColor.b * amount;
 
-				color.r += lightColor.r * amount;
-				color.g += lightColor.g * amount;
-				color.b += lightColor.b * amount;
+				} else if ( light.isPointLight ) {
 
-			} else if ( light.isPointLight ) {
+					const lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld );
 
-				var lightPosition = _vector3.setFromMatrixPosition( light.matrixWorld );
+					let amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
 
-				var amount = normal.dot( _vector3.subVectors( lightPosition, position ).normalize() );
+					if ( amount <= 0 ) continue;
 
-				if ( amount <= 0 ) continue;
+					amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
 
-				amount *= light.distance == 0 ? 1 : 1 - Math.min( position.distanceTo( lightPosition ) / light.distance, 1 );
+					if ( amount == 0 ) continue;
 
-				if ( amount == 0 ) continue;
+					amount *= light.intensity;
 
-				amount *= light.intensity;
+					color.r += lightColor.r * amount;
+					color.g += lightColor.g * amount;
+					color.b += lightColor.b * amount;
 
-				color.r += lightColor.r * amount;
-				color.g += lightColor.g * amount;
-				color.b += lightColor.b * amount;
+				}
 
 			}
 
 		}
 
-	}
+		function renderSprite( v1, element, material ) {
 
-	function renderSprite( v1, element, material ) {
+			let scaleX = element.scale.x * _svgWidthHalf;
+			let scaleY = element.scale.y * _svgHeightHalf;
 
-		var scaleX = element.scale.x * _svgWidthHalf;
-		var scaleY = element.scale.y * _svgHeightHalf;
+			if ( material.isPointsMaterial ) {
 
-		if ( material.isPointsMaterial ) {
+				scaleX *= material.size;
+				scaleY *= material.size;
 
-			scaleX *= material.size;
-			scaleY *= material.size;
+			}
 
-		}
+			const path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert( - scaleX ) + 'z';
+			let style = '';
 
-		var path = 'M' + convert( v1.x - scaleX * 0.5 ) + ',' + convert( v1.y - scaleY * 0.5 ) + 'h' + convert( scaleX ) + 'v' + convert( scaleY ) + 'h' + convert( - scaleX ) + 'z';
-		var style = '';
+			if ( material.isSpriteMaterial || material.isPointsMaterial ) {
 
-		if ( material.isSpriteMaterial || material.isPointsMaterial ) {
+				style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity;
 
-			style = 'fill:' + material.color.getStyle() + ';fill-opacity:' + material.opacity;
+			}
+
+			addPath( style, path );
 
 		}
 
-		addPath( style, path );
+		function renderLine( v1, v2, element, material ) {
 
-	}
+			const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y );
 
-	function renderLine( v1, v2, element, material ) {
+			if ( material.isLineBasicMaterial ) {
 
-		var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y );
+				let style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
 
-		if ( material.isLineBasicMaterial ) {
+				if ( material.isLineDashedMaterial ) {
 
-			var style = 'fill:none;stroke:' + material.color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.linewidth + ';stroke-linecap:' + material.linecap;
+					style = style + ';stroke-dasharray:' + material.dashSize + ',' + material.gapSize;
 
-			if ( material.isLineDashedMaterial ) {
+				}
 
-				style = style + ';stroke-dasharray:' + material.dashSize + ',' + material.gapSize;
+				addPath( style, path );
 
 			}
 
-			addPath( style, path );
-
 		}
 
-	}
+		function renderFace3( v1, v2, v3, element, material ) {
 
-	function renderFace3( v1, v2, v3, element, material ) {
+			_this.info.render.vertices += 3;
+			_this.info.render.faces ++;
 
-		_this.info.render.vertices += 3;
-		_this.info.render.faces ++;
+			const path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z';
+			let style = '';
 
-		var path = 'M' + convert( v1.positionScreen.x ) + ',' + convert( v1.positionScreen.y ) + 'L' + convert( v2.positionScreen.x ) + ',' + convert( v2.positionScreen.y ) + 'L' + convert( v3.positionScreen.x ) + ',' + convert( v3.positionScreen.y ) + 'z';
-		var style = '';
+			if ( material.isMeshBasicMaterial ) {
 
-		if ( material.isMeshBasicMaterial ) {
+				_color.copy( material.color );
 
-			_color.copy( material.color );
+				if ( material.vertexColors ) {
 
-			if ( material.vertexColors ) {
+					_color.multiply( element.color );
 
-				_color.multiply( element.color );
+				}
 
-			}
+			} else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial ) {
 
-		} else if ( material.isMeshLambertMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial ) {
+				_diffuseColor.copy( material.color );
 
-			_diffuseColor.copy( material.color );
+				if ( material.vertexColors ) {
 
-			if ( material.vertexColors ) {
+					_diffuseColor.multiply( element.color );
 
-				_diffuseColor.multiply( element.color );
+				}
 
-			}
+				_color.copy( _ambientLight );
 
-			_color.copy( _ambientLight );
+				_centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 );
 
-			_centroid.copy( v1.positionWorld ).add( v2.positionWorld ).add( v3.positionWorld ).divideScalar( 3 );
+				calculateLight( _lights, _centroid, element.normalModel, _color );
 
-			calculateLight( _lights, _centroid, element.normalModel, _color );
+				_color.multiply( _diffuseColor ).add( material.emissive );
 
-			_color.multiply( _diffuseColor ).add( material.emissive );
+			} else if ( material.isMeshNormalMaterial ) {
 
-		} else if ( material.isMeshNormalMaterial ) {
+				_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
 
-			_normal.copy( element.normalModel ).applyMatrix3( _normalViewMatrix ).normalize();
+				_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
 
-			_color.setRGB( _normal.x, _normal.y, _normal.z ).multiplyScalar( 0.5 ).addScalar( 0.5 );
+			}
 
-		}
+			if ( material.wireframe ) {
 
-		if ( material.wireframe ) {
+				style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
 
-			style = 'fill:none;stroke:' + _color.getStyle() + ';stroke-opacity:' + material.opacity + ';stroke-width:' + material.wireframeLinewidth + ';stroke-linecap:' + material.wireframeLinecap + ';stroke-linejoin:' + material.wireframeLinejoin;
+			} else {
 
-		} else {
+				style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity;
 
-			style = 'fill:' + _color.getStyle() + ';fill-opacity:' + material.opacity;
+			}
 
-		}
+			addPath( style, path );
 
-		addPath( style, path );
+		}
 
-	}
+		// Hide anti-alias gaps
 
-	// Hide anti-alias gaps
+		function expand( v1, v2, pixels ) {
 
-	function expand( v1, v2, pixels ) {
+			let x = v2.x - v1.x, y = v2.y - v1.y;
+			const det = x * x + y * y;
 
-		var x = v2.x - v1.x, y = v2.y - v1.y,
-			det = x * x + y * y, idet;
+			if ( det === 0 ) return;
 
-		if ( det === 0 ) return;
+			const idet = pixels / Math.sqrt( det );
 
-		idet = pixels / Math.sqrt( det );
+			x *= idet; y *= idet;
 
-		x *= idet; y *= idet;
+			v2.x += x; v2.y += y;
+			v1.x -= x; v1.y -= y;
 
-		v2.x += x; v2.y += y;
-		v1.x -= x; v1.y -= y;
+		}
 
-	}
+		function addPath( style, path ) {
 
-	function addPath( style, path ) {
+			if ( _currentStyle === style ) {
 
-		if ( _currentStyle === style ) {
+				_currentPath += path;
 
-			_currentPath += path;
+			} else {
 
-		} else {
+				flushPath();
 
-			flushPath();
+				_currentStyle = style;
+				_currentPath = path;
 
-			_currentStyle = style;
-			_currentPath = path;
+			}
 
 		}
 
-	}
+		function flushPath() {
+
+			if ( _currentPath ) {
 
-	function flushPath() {
+				_svgNode = getPathNode( _pathCount ++ );
+				_svgNode.setAttribute( 'd', _currentPath );
+				_svgNode.setAttribute( 'style', _currentStyle );
+				_svg.appendChild( _svgNode );
 
-		if ( _currentPath ) {
+			}
 
-			_svgNode = getPathNode( _pathCount ++ );
-			_svgNode.setAttribute( 'd', _currentPath );
-			_svgNode.setAttribute( 'style', _currentStyle );
-			_svg.appendChild( _svgNode );
+			_currentPath = '';
+			_currentStyle = '';
 
 		}
 
-		_currentPath = '';
-		_currentStyle = '';
+		function getPathNode( id ) {
 
-	}
+			if ( _svgPathPool[ id ] == null ) {
 
-	function getPathNode( id ) {
+				_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
 
-		if ( _svgPathPool[ id ] == null ) {
+				if ( _quality == 0 ) {
 
-			_svgPathPool[ id ] = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );
+					_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
 
-			if ( _quality == 0 ) {
+				}
 
-				_svgPathPool[ id ].setAttribute( 'shape-rendering', 'crispEdges' ); //optimizeSpeed
+				return _svgPathPool[ id ];
 
 			}
 
@@ -533,10 +546,8 @@ var SVGRenderer = function () {
 
 		}
 
-		return _svgPathPool[ id ];
-
 	}
 
-};
+}
 
 export { SVGObject, SVGRenderer };

部分文件因为文件数量过多而无法显示