Sfoglia il codice sorgente

TTFLoader: Refactoring

Mugen87 8 anni fa
parent
commit
95c1a08ae9
2 ha cambiato i file con 126 aggiunte e 234 eliminazioni
  1. 109 110
      examples/js/loaders/TTFLoader.js
  2. 17 124
      examples/webgl_loader_ttf.html

+ 109 - 110
examples/js/loaders/TTFLoader.js

@@ -1,13 +1,12 @@
 /**
  * @author gero3 / https://github.com/gero3
  * @author tentone / https://github.com/tentone
- * Requires opentype.js to be included in the project
+ *
+ * Requires opentype.js to be included in the project.
  * Loads TTF files and converts them into typeface JSON that can be used directly
- * to create THREE.Font objects
+ * to create THREE.Font objects.
  */
 
-'use strict';
-
 THREE.TTFLoader = function ( manager ) {
 
 	this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
@@ -15,179 +14,179 @@ THREE.TTFLoader = function ( manager ) {
 
 };
 
-THREE.TTFLoader.prototype.load = function ( url, onLoad, onProgress, onError ) {
-
-	var scope = this;
+THREE.TTFLoader.prototype = {
 
-	var loader = new THREE.FileLoader( this.manager );
-	loader.setResponseType( 'arraybuffer' );
-	loader.load( url, function ( buffer ) {
+	constructor: THREE.TTFLoader,
 
-		if ( onLoad !== undefined ) {
+	load: function ( url, onLoad, onProgress, onError ) {
 
-			onLoad( scope.parse( buffer ) );
-
-		}
+		var scope = this;
 
-	}, onProgress, onError );
+		var loader = new THREE.FileLoader( this.manager );
+		loader.setResponseType( 'arraybuffer' );
+		loader.load( url, function ( buffer ) {
 
-};
+			onLoad( scope.parse( buffer ) );
 
-THREE.TTFLoader.prototype.parse = function ( arraybuffer ) {
+		}, onProgress, onError );
 
-	if ( typeof opentype === 'undefined' ) {
+	},
 
-		console.warn( 'TTFLoader requires opentype.js Make sure it\'s included before using the loader' );
-		return null;
+	parse: function ( arraybuffer ) {
 
-	}
+		function convert( font, reversed ) {
 
-	function convert( font, reversed ) {
+			var round = Math.round;
 
-		var round = Math.round;
+			var glyphs = {};
+			var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
 
-		var glyphs = {};
-		var scale = ( 100000 ) / ( ( font.unitsPerEm || 2048 ) * 72 );
+			for ( var i = 0; i < font.glyphs.length; i ++ ) {
 
-		for ( var i = 0; i < font.glyphs.length; i ++ ) {
+				var glyph = font.glyphs.glyphs[ i ];
 
-			var glyph = font.glyphs.glyphs[ i ];
+				if ( glyph.unicode !== undefined ) {
 
-			if ( glyph.unicode !== undefined ) {
+					var token = {
+						ha: round( glyph.advanceWidth * scale ),
+						x_min: round( glyph.xMin * scale ),
+						x_max: round( glyph.xMax * scale ),
+						o: ''
+					};
 
-				var token = {
-					ha: round( glyph.advanceWidth * scale ),
-					x_min: round( glyph.xMin * scale ),
-					x_max: round( glyph.xMax * scale ),
-					o: ''
-				};
+					if ( reversed ) {
 
-				if ( reversed ) {
+						glyph.path.commands = reverseCommands( glyph.path.commands );
 
-					glyph.path.commands = reverseCommands( glyph.path.commands );
+					}
 
-				}
+					glyph.path.commands.forEach( function ( command, i ) {
 
-				glyph.path.commands.forEach( function ( command, i ) {
+						if ( command.type.toLowerCase() === 'c' ) {
 
-					if ( command.type.toLowerCase() === 'c' ) {
+							command.type = 'b';
 
-						command.type = 'b';
+						}
 
-					}
+						token.o += command.type.toLowerCase() + ' ';
 
-					token.o += command.type.toLowerCase() + ' ';
+						if ( command.x !== undefined && command.y !== undefined ) {
 
-					if ( command.x !== undefined && command.y !== undefined ) {
+							token.o += round( command.x * scale ) + ' ' + round( command.y * scale ) + ' ';
 
-						token.o += round( command.x * scale ) + ' ' + round( command.y * scale ) + ' ';
+						}
 
-					}
+						if ( command.x1 !== undefined && command.y1 !== undefined ) {
 
-					if ( command.x1 !== undefined && command.y1 !== undefined ) {
+							token.o += round( command.x1 * scale ) + ' ' + round( command.y1 * scale ) + ' ';
 
-						token.o += round( command.x1 * scale ) + ' ' + round( command.y1 * scale ) + ' ';
+						}
 
-					}
+						if ( command.x2 !== undefined && command.y2 !== undefined ) {
 
-					if ( command.x2 !== undefined && command.y2 !== undefined ) {
+							token.o += round( command.x2 * scale ) + ' ' + round( command.y2 * scale ) + ' ';
 
-						token.o += round( command.x2 * scale ) + ' ' + round( command.y2 * scale ) + ' ';
+						}
 
-					}
+					} );
 
-				} );
+					glyphs[ String.fromCharCode( glyph.unicode ) ] = token;
 
-				glyphs[ String.fromCharCode( glyph.unicode ) ] = token;
+				}
 
 			}
 
+			return {
+				glyphs: glyphs,
+				familyName: font.familyName,
+				ascender: round( font.ascender * scale ),
+				descender: round( font.descender * scale ),
+				underlinePosition: font.tables.post.underlinePosition,
+				underlineThickness: font.tables.post.underlineThickness,
+				boundingBox: {
+					xMin: font.tables.head.xMin,
+					xMax: font.tables.head.xMax,
+					yMin: font.tables.head.yMin,
+					yMax: font.tables.head.yMax
+				},
+				resolution: 1000,
+				original_font_information: font.tables.name
+			};
+
 		}
 
-		return {
-			glyphs: glyphs,
-
-			familyName: font.familyName,
-			ascender: round( font.ascender * scale ),
-			descender: round( font.descender * scale ),
-			underlinePosition: font.tables.post.underlinePosition,
-			underlineThickness: font.tables.post.underlineThickness,
-			boundingBox: {
-				xMin: font.tables.head.xMin,
-				xMax: font.tables.head.xMax,
-				yMin: font.tables.head.yMin,
-				yMax: font.tables.head.yMax
-			},
-
-			resolution: 1000,
-			original_font_information: font.tables.name
-		};
+		function reverseCommands( commands ) {
 
-	}
+			var paths = [];
+			var path;
 
-	function reverseCommands( commands ) {
+			commands.forEach( function ( c ) {
 
-		var paths = [];
-		var path;
+				if ( c.type.toLowerCase() === 'm' ) {
 
-		commands.forEach( function ( c ) {
+					path = [ c ];
+					paths.push( path );
 
-			if ( c.type.toLowerCase() === 'm' ) {
+				} else if ( c.type.toLowerCase() !== 'z' ) {
 
-				path = [ c ];
-				paths.push( path );
+					path.push( c );
 
-			} else if ( c.type.toLowerCase() !== 'z' ) {
+				}
 
-				path.push( c );
+			} );
 
-			}
+			var reversed = [];
 
-		} );
+			paths.forEach( function ( p ) {
 
-		var reversed = [];
+				var result = {
+					type: 'm',
+					x: p[ p.length - 1 ].x,
+					y: p[ p.length - 1 ].y
+				};
 
-		paths.forEach( function ( p ) {
+				reversed.push( result );
 
-			var result = {
-				type: 'm',
-				x: p[ p.length - 1 ].x,
-				y: p[ p.length - 1 ].y
-			};
+				for ( var i = p.length - 1; i > 0; i -- ) {
 
-			reversed.push( result );
+					var command = p[ i ];
+					var result = { type: command.type };
 
-			for ( var i = p.length - 1; i > 0; i -- ) {
+					if ( command.x2 !== undefined && command.y2 !== undefined ) {
 
-				var command = p[ i ];
-				var result = { type: command.type };
+						result.x1 = command.x2;
+						result.y1 = command.y2;
+						result.x2 = command.x1;
+						result.y2 = command.y1;
 
-				if ( command.x2 !== undefined && command.y2 !== undefined ) {
+					} else if ( command.x1 !== undefined && command.y1 !== undefined ) {
 
-					result.x1 = command.x2;
-					result.y1 = command.y2;
-					result.x2 = command.x1;
-					result.y2 = command.y1;
+						result.x1 = command.x1;
+						result.y1 = command.y1;
 
-				} else if ( command.x1 !== undefined && command.y1 !== undefined ) {
+					}
 
-					result.x1 = command.x1;
-					result.y1 = command.y1;
+					result.x = p[ i - 1 ].x;
+					result.y = p[ i - 1 ].y;
+					reversed.push( result );
 
 				}
 
-				result.x = p[ i - 1 ].x;
-				result.y = p[ i - 1 ].y;
-				reversed.push( result );
+			} );
 
-			}
+			return reversed;
 
-		} );
+		}
 
-		return reversed;
+		if ( typeof opentype === 'undefined' ) {
 
-	}
+			console.warn( 'THREE.TTFLoader: The loader requires opentype.js. Make sure it\'s included before using the loader.' );
+			return null;
 
-	return convert( opentype.parse( arraybuffer ), this.reversed );
+		}
+
+		return convert( opentype.parse( arraybuffer ), this.reversed );
+
+	}
 
 };

+ 17 - 124
examples/webgl_loader_ttf.html

@@ -5,16 +5,14 @@
 		<meta charset="utf-8">
 		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
 		<style>
-			body
-			{
+			body {
 				font-family: Monospace;
 				background-color: #000;
 				color: #fff;
 				margin: 0px;
 				overflow: hidden;
 			}
-			#info
-			{
+			#info {
 				position: absolute;
 				top: 10px;
 				width: 100%;
@@ -22,8 +20,7 @@
 				z-index: 100;
 				display:block;
 			}
-			#info a, .button
-			{
+			#info a {
 				color: #f00;
 				font-weight: bold;
 				text-decoration: underline;
@@ -33,15 +30,12 @@
 	</head>
 	<body>
 		<script src="../build/three.js"></script>
-		<script src="js/utils/GeometryUtils.js"></script>
 		<script src="js/Detector.js"></script>
 		<script src="js/loaders/TTFLoader.js"></script>
 		<script src="js/libs/opentype.min.js"></script>
 		<div id="info">
-			<a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - TTFLoader using opentype by gero3
+			<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> - TTFLoader using opentype by gero3
 			<br/>type to enter new text, drag to spin the text
-			<br/><span class="button" id="color">change color</span>,
-			<span class="button" id="bevel">change bevel</span>
 		</div>
 
 
@@ -49,28 +43,21 @@
 
 			if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
 
-			THREE.Cache.enabled = true;
-
-			var container, hex, color;
-
+			var container, color;
 			var camera, cameraTarget, scene, renderer;
-
 			var group, textMesh1, textMesh2, textGeo, material;
-
 			var firstLetter = true;
 
-			var text = "three.js",
+			var text = 'three.js',
 				height = 20,
 				size = 70,
 				hover = 30,
 				curveSegments = 4,
 				bevelThickness = 2,
 				bevelSize = 1.5,
-				bevelSegments = 3,
-				bevelEnabled = true;
+				bevelSegments = 3;
 
 			var font = null;
-
 			var mirror = true;
 
 			var targetRotation = 0;
@@ -85,14 +72,6 @@
 			init();
 			animate();
 
-			function decimalToHex( d ) {
-
-				var hex = Number( d ).toString( 16 );
-				hex = "000000".substr( 0, 6 - hex.length ) + hex;
-				return hex.toUpperCase();
-
-			}
-
 			function init() {
 
 				container = document.createElement( 'div' );
@@ -118,37 +97,9 @@
 
 				var pointLight = new THREE.PointLight( 0xffffff, 1.5 );
 				pointLight.position.set( 0, 100, 90 );
+				pointLight.color.setHSL( Math.random(), 1, 0.5 );
 				scene.add( pointLight );
 
-				// Get text from hash
-
-				var hash = document.location.hash.substr( 1 );
-
-				if ( hash.length !== 0 ) {
-
-					var colorhash  = hash.substring( 0, 6 );
-					var fonthash   = hash.substring( 6, 7 );
-					var weighthash = hash.substring( 7, 8 );
-					var bevelhash  = hash.substring( 8, 9 );
-					var texthash   = hash.substring( 10 );
-
-					hex = colorhash;
-					pointLight.color.setHex( parseInt( colorhash, 16 ) );
-
-					fontName = reverseFontMap[ parseInt( fonthash ) ];
-					fontWeight = reverseWeightMap[ parseInt( weighthash ) ];
-
-					bevelEnabled = parseInt( bevelhash );
-
-					text = decodeURI( texthash );
-
-				} else {
-
-					pointLight.color.setHSL( Math.random(), 1, 0.5 );
-					hex = decimalToHex( pointLight.color.getHex() );
-
-				}
-
 				material = new THREE.MeshPhongMaterial( { color: 0xffffff, shading: THREE.FlatShading } );
 
 				group = new THREE.Group();
@@ -159,8 +110,7 @@
 				var loader = new THREE.TTFLoader();
 
 				loader.load( 'fonts/ttf/kenpixel.ttf', function ( json ) {
-					font = new THREE.Font(json);
-					//scene.add( font );
+					font = new THREE.Font( json );
 					createText();
 				} );
 
@@ -188,23 +138,8 @@
 				document.addEventListener( 'keypress', onDocumentKeyPress, false );
 				document.addEventListener( 'keydown', onDocumentKeyDown, false );
 
-				document.getElementById( "color" ).addEventListener( 'click', function() {
-
-					pointLight.color.setHSL( Math.random(), 1, 0.5 );
-					hex = decimalToHex( pointLight.color.getHex() );
-
-				}, false );
-
-				document.getElementById( "bevel" ).addEventListener( 'click', function(){
-
-					bevelEnabled = !bevelEnabled;
-
-					refreshText();
-
-				}, false );
-
-
 				window.addEventListener( 'resize', onWindowResize, false );
+
 			}
 
 			function onWindowResize() {
@@ -224,7 +159,7 @@
 				if ( firstLetter ) {
 
 					firstLetter = false;
-					text = "";
+					text = '';
 
 				}
 
@@ -232,7 +167,7 @@
 
 				// backspace
 
-				if ( keyCode == 8 ) {
+				if ( keyCode === 8 ) {
 
 					event.preventDefault();
 
@@ -251,7 +186,7 @@
 
 				// backspace
 
-				if ( keyCode == 8 ) {
+				if ( keyCode === 8 ) {
 
 					event.preventDefault();
 
@@ -278,7 +213,7 @@
 
 					bevelThickness: bevelThickness,
 					bevelSize: bevelSize,
-					bevelEnabled: bevelEnabled,
+					bevelEnabled: true,
 
 					material: 0,
 					extrudeMaterial: 1
@@ -288,49 +223,7 @@
 				textGeo.computeBoundingBox();
 				textGeo.computeVertexNormals();
 
-				// "fix" side normals by removing z-component of normals for side faces
-				// (this doesn't work well for beveled geometry as then we lose nice curvature around z-axis)
-
-				if ( ! bevelEnabled ) {
-
-					var triangleAreaHeuristics = 0.1 * ( height * size );
-
-					for ( var i = 0; i < textGeo.faces.length; i ++ ) {
-
-						var face = textGeo.faces[ i ];
-
-						if ( face.materialIndex == 1 ) {
-
-							for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
-
-								face.vertexNormals[ j ].z = 0;
-								face.vertexNormals[ j ].normalize();
-
-							}
-
-							var va = textGeo.vertices[ face.a ];
-							var vb = textGeo.vertices[ face.b ];
-							var vc = textGeo.vertices[ face.c ];
-
-							var s = THREE.GeometryUtils.triangleArea( va, vb, vc );
-
-							if ( s > triangleAreaHeuristics ) {
-
-								for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
-
-									face.vertexNormals[ j ].copy( face.normal );
-
-								}
-
-							}
-
-						}
-
-					}
-
-				}
-
-				var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
+				var centerOffset = - 0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
 
 				textMesh1 = new THREE.Mesh( textGeo, material );
 
@@ -410,7 +303,7 @@
 
 			function onDocumentTouchStart( event ) {
 
-				if ( event.touches.length == 1 ) {
+				if ( event.touches.length === 1 ) {
 
 					event.preventDefault();
 
@@ -423,7 +316,7 @@
 
 			function onDocumentTouchMove( event ) {
 
-				if ( event.touches.length == 1 ) {
+				if ( event.touches.length === 1 ) {
 
 					event.preventDefault();