OSDN Git Service

three.jsをThirdPartyに追加
[webglgame/webgl_framework.git] / webglFramework / Thirdparty / three.js-master / examples / webgl_geometry_text_pnltri.html
1 <!DOCTYPE html>
2 <html lang="en">
3         <head>
4                 <title>three.js webgl - geometry - text</title>
5                 <meta charset="utf-8">
6                 <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
7                 <style>
8                         body {
9                                 font-family: Monospace;
10                                 background-color: #000;
11                                 color: #fff;
12                                 margin: 0px;
13                                 overflow: hidden;
14                         }
15                         #info {
16                                 position: absolute;
17                                 top: 10px;
18                                 width: 100%;
19                                 text-align: center;
20                                 z-index: 100;
21                                 display:block;
22                         }
23                         #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
24                 </style>
25         </head>
26         <body>
27
28                 <div id="info">
29                 <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a> - procedural 3D text by <a href="http://www.lab4games.net/zz85/blog" target="_blank" rel="noopener">zz85</a> &amp; alteredq
30                 <br/>built-in shape triangulation has been replaced with <a href="https://github.com/jahting/pnltri.js">PnlTri.js</a> by <a href="https://github.com/jahting" target="_blank" rel="noopener">j ahting</a>
31                 <br/>type to enter new text, drag to spin the text
32                 <br/><span class="button" id="color">change color</span>,
33                         <span class="button" id="font">change font</span>,
34                         <span class="button" id="weight">change weight</span>,
35                         <span class="button" id="bevel">change bevel</span>
36                         <a id="permalink" href="#">permalink</a>
37                 </div>
38
39
40                 <script src="../build/three.js"></script>
41                 <script src="js/utils/GeometryUtils.js"></script>
42
43                 <script src="js/Detector.js"></script>
44                 <script src="js/libs/stats.min.js"></script>
45
46
47                 <!-- replace built-in triangulation with PnlTri.js -->
48                 <script src="js/libs/pnltri.min.js"></script>
49                 <script>
50                         THREE.ShapeUtils.triangulateShape = ( function () {
51                                 var pnlTriangulator = new PNLTRI.Triangulator();
52                                 function removeDupEndPts(points) {
53
54                                         var l = points.length;
55
56                                         if ( l > 2 && points[ l - 1 ].equals( points[ 0 ] ) ) {
57
58                                                 points.pop();
59
60                                         }
61
62                                 }
63
64                                 return function triangulateShape( contour, holes ) {
65                                         // console.log("new Triangulation: PnlTri.js " + PNLTRI.REVISION );
66
67                                         removeDupEndPts( contour );
68                                         holes.forEach( removeDupEndPts );
69
70                                         return pnlTriangulator.triangulate_polygon( [ contour ].concat(holes) );
71                                 };
72                         } )();
73                 </script>
74
75                 <script>
76
77                         if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
78
79                         THREE.Cache.enabled = true;
80
81                         var container, stats, permalink, hex, color;
82
83                         var camera, cameraTarget, scene, renderer;
84
85                         var group, textMesh1, textMesh2, textGeo, materials;
86
87                         var firstLetter = true;
88
89                         var text = "PnlTri",
90
91                                 height = 20,
92                                 size = 70,
93                                 hover = 30,
94
95                                 curveSegments = 4,
96
97                                 bevelThickness = 2,
98                                 bevelSize = 1.5,
99                                 bevelSegments = 3,
100                                 bevelEnabled = true,
101
102                                 font = undefined,
103
104                                 fontName = "optimer", // helvetiker, optimer, gentilis, droid sans, droid serif
105                                 fontWeight = "bold"; // normal bold
106
107                         var mirror = true;
108
109                         var fontMap = {
110
111                                 "helvetiker": 0,
112                                 "optimer": 1,
113                                 "gentilis": 2,
114                                 "droid/droid_sans": 3,
115                                 "droid/droid_serif": 4
116
117                         };
118
119                         var weightMap = {
120
121                                 "regular": 0,
122                                 "bold": 1
123
124                         };
125
126                         var reverseFontMap = [];
127                         var reverseWeightMap = [];
128
129                         for ( var i in fontMap ) reverseFontMap[ fontMap[i] ] = i;
130                         for ( var i in weightMap ) reverseWeightMap[ weightMap[i] ] = i;
131
132                         var targetRotation = 0;
133                         var targetRotationOnMouseDown = 0;
134
135                         var mouseX = 0;
136                         var mouseXOnMouseDown = 0;
137
138                         var windowHalfX = window.innerWidth / 2;
139                         var windowHalfY = window.innerHeight / 2;
140
141                         var fontIndex = 1;
142
143                         init();
144                         animate();
145
146                         function decimalToHex( d ) {
147
148                                 var hex = Number( d ).toString( 16 );
149                                 hex = "000000".substr( 0, 6 - hex.length ) + hex;
150                                 return hex.toUpperCase();
151
152                         }
153
154                         function init() {
155
156                                 container = document.createElement( 'div' );
157                                 document.body.appendChild( container );
158
159                                 permalink = document.getElementById( "permalink" );
160
161                                 // CAMERA
162
163                                 camera = new THREE.PerspectiveCamera( 30, window.innerWidth / window.innerHeight, 1, 1500 );
164                                 camera.position.set( 0, 400, 700 );
165
166                                 cameraTarget = new THREE.Vector3( 0, 150, 0 );
167
168                                 // SCENE
169
170                                 scene = new THREE.Scene();
171                                 scene.background = new THREE.Color( 0x000000 );
172                                 scene.fog = new THREE.Fog( 0x000000, 250, 1400 );
173
174                                 // LIGHTS
175
176                                 var dirLight = new THREE.DirectionalLight( 0xffffff, 0.125 );
177                                 dirLight.position.set( 0, 0, 1 ).normalize();
178                                 scene.add( dirLight );
179
180                                 var pointLight = new THREE.PointLight( 0xffffff, 1.5 );
181                                 pointLight.position.set( 0, 100, 90 );
182                                 scene.add( pointLight );
183
184                                 // Get text from hash
185
186                                 var hash = document.location.hash.substr( 1 );
187
188                                 if ( hash.length !== 0 ) {
189
190                                         var colorhash  = hash.substring( 0, 6 );
191                                         var fonthash   = hash.substring( 6, 7 );
192                                         var weighthash = hash.substring( 7, 8 );
193                                         var bevelhash  = hash.substring( 8, 9 );
194                                         var texthash   = hash.substring( 10 );
195
196                                         hex = colorhash;
197                                         pointLight.color.setHex( parseInt( colorhash, 16 ) );
198
199                                         fontName = reverseFontMap[ parseInt( fonthash ) ];
200                                         fontWeight = reverseWeightMap[ parseInt( weighthash ) ];
201
202                                         bevelEnabled = parseInt( bevelhash );
203
204                                         text = decodeURI( texthash );
205
206                                         updatePermalink();
207
208                                 } else {
209
210                                         pointLight.color.setHSL( Math.random(), 1, 0.5 );
211                                         hex = decimalToHex( pointLight.color.getHex() );
212
213                                 }
214
215                                 materials = [
216                                         new THREE.MeshPhongMaterial( { color: 0xffffff, flatShading: true } ), // front
217                                         new THREE.MeshPhongMaterial( { color: 0xffffff } ) // side
218                                 ];
219
220                                 group = new THREE.Group();
221                                 group.position.y = 100;
222
223                                 scene.add( group );
224
225                                 loadFont();
226
227                                 var plane = new THREE.Mesh(
228                                         new THREE.PlaneBufferGeometry( 10000, 10000 ),
229                                         new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 0.5, transparent: true } )
230                                 );
231                                 plane.position.y = 100;
232                                 plane.rotation.x = - Math.PI / 2;
233                                 scene.add( plane );
234
235                                 // RENDERER
236
237                                 renderer = new THREE.WebGLRenderer( { antialias: true } );
238                                 renderer.setPixelRatio( window.devicePixelRatio );
239                                 renderer.setSize( window.innerWidth, window.innerHeight );
240                                 container.appendChild( renderer.domElement );
241
242                                 // STATS
243
244                                 stats = new Stats();
245                                 //container.appendChild( stats.dom );
246
247                                 // EVENTS
248
249                                 document.addEventListener( 'mousedown', onDocumentMouseDown, false );
250                                 document.addEventListener( 'touchstart', onDocumentTouchStart, false );
251                                 document.addEventListener( 'touchmove', onDocumentTouchMove, false );
252                                 document.addEventListener( 'keypress', onDocumentKeyPress, false );
253                                 document.addEventListener( 'keydown', onDocumentKeyDown, false );
254
255                                 document.getElementById( "color" ).addEventListener( 'click', function() {
256
257                                         pointLight.color.setHSL( Math.random(), 1, 0.5 );
258                                         hex = decimalToHex( pointLight.color.getHex() );
259
260                                         updatePermalink();
261
262                                 }, false );
263
264                                 document.getElementById( "font" ).addEventListener( 'click', function() {
265
266                                         fontIndex ++;
267
268                                         fontName = reverseFontMap[ fontIndex % reverseFontMap.length ];
269
270                                         loadFont();
271
272                                 }, false );
273
274
275                                 document.getElementById( "weight" ).addEventListener( 'click', function() {
276
277                                         if ( fontWeight === "bold" ) {
278
279                                                 fontWeight = "regular";
280
281                                         } else {
282
283                                                 fontWeight = "bold";
284
285                                         }
286
287                                         loadFont();
288
289                                 }, false );
290
291                                 document.getElementById( "bevel" ).addEventListener( 'click', function() {
292
293                                         bevelEnabled = !bevelEnabled;
294
295                                         refreshText();
296
297                                 }, false );
298
299                                 //
300
301                                 window.addEventListener( 'resize', onWindowResize, false );
302
303                         }
304
305                         function onWindowResize() {
306
307                                 windowHalfX = window.innerWidth / 2;
308                                 windowHalfY = window.innerHeight / 2;
309
310                                 camera.aspect = window.innerWidth / window.innerHeight;
311                                 camera.updateProjectionMatrix();
312
313                                 renderer.setSize( window.innerWidth, window.innerHeight );
314
315                         }
316
317                         //
318
319                         function boolToNum( b ) {
320
321                                 return b ? 1 : 0;
322
323                         }
324
325                         function updatePermalink() {
326
327                                 var link = hex + fontMap[ fontName ] + weightMap[ fontWeight ] + boolToNum( bevelEnabled ) + "#" + encodeURI( text );
328
329                                 permalink.href = "#" + link;
330                                 window.location.hash = link;
331
332                         }
333
334                         function onDocumentKeyDown( event ) {
335
336                                 if ( firstLetter ) {
337
338                                         firstLetter = false;
339                                         text = "";
340
341                                 }
342
343                                 var keyCode = event.keyCode;
344
345                                 // backspace
346
347                                 if ( keyCode == 8 ) {
348
349                                         event.preventDefault();
350
351                                         text = text.substring( 0, text.length - 1 );
352                                         refreshText();
353
354                                         return false;
355
356                                 }
357
358                         }
359
360                         function onDocumentKeyPress( event ) {
361
362                                 var keyCode = event.which;
363
364                                 // backspace
365
366                                 if ( keyCode == 8 ) {
367
368                                         event.preventDefault();
369
370                                 } else {
371
372                                         var ch = String.fromCharCode( keyCode );
373                                         text += ch;
374
375                                         refreshText();
376
377                                 }
378
379                         }
380
381                         function loadFont() {
382
383                                 var loader = new THREE.FontLoader();
384                                 loader.load( 'fonts/' + fontName + '_' + fontWeight + '.typeface.json', function ( response ) {
385
386                                         font = response;
387
388                                         refreshText();
389
390                                 } );
391
392                         }
393
394                         function createText() {
395
396                                 textGeo = new THREE.TextBufferGeometry( text, {
397
398                                         font: font,
399
400                                         size: size,
401                                         height: height,
402                                         curveSegments: curveSegments,
403
404                                         bevelThickness: bevelThickness,
405                                         bevelSize: bevelSize,
406                                         bevelEnabled: bevelEnabled,
407
408                                         material: 0,
409                                         extrudeMaterial: 1
410
411                                 });
412
413                                 textGeo.computeBoundingBox();
414                                 textGeo.computeVertexNormals();
415
416                                 // "fix" side normals by removing z-component of normals for side faces
417                                 // (this doesn't work well for beveled geometry as then we lose nice curvature around z-axis)
418
419                                 if ( ! bevelEnabled ) {
420
421                                         var triangleAreaHeuristics = 0.1 * ( height * size );
422
423                                         for ( var i = 0; i < textGeo.faces.length; i ++ ) {
424
425                                                 var face = textGeo.faces[ i ];
426
427                                                 if ( face.materialIndex == 1 ) {
428
429                                                         for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
430
431                                                                 face.vertexNormals[ j ].z = 0;
432                                                                 face.vertexNormals[ j ].normalize();
433
434                                                         }
435
436                                                         var va = textGeo.vertices[ face.a ];
437                                                         var vb = textGeo.vertices[ face.b ];
438                                                         var vc = textGeo.vertices[ face.c ];
439
440                                                         var s = THREE.GeometryUtils.triangleArea( va, vb, vc );
441
442                                                         if ( s > triangleAreaHeuristics ) {
443
444                                                                 for ( var j = 0; j < face.vertexNormals.length; j ++ ) {
445
446                                                                         face.vertexNormals[ j ].copy( face.normal );
447
448                                                                 }
449
450                                                         }
451
452                                                 }
453
454                                         }
455
456                                 }
457
458                                 var centerOffset = -0.5 * ( textGeo.boundingBox.max.x - textGeo.boundingBox.min.x );
459
460                                 textMesh1 = new THREE.Mesh( textGeo, materials );
461
462                                 textMesh1.position.x = centerOffset;
463                                 textMesh1.position.y = hover;
464                                 textMesh1.position.z = 0;
465
466                                 textMesh1.rotation.x = 0;
467                                 textMesh1.rotation.y = Math.PI * 2;
468
469                                 group.add( textMesh1 );
470
471                                 if ( mirror ) {
472
473                                         textMesh2 = new THREE.Mesh( textGeo, materials );
474
475                                         textMesh2.position.x = centerOffset;
476                                         textMesh2.position.y = -hover;
477                                         textMesh2.position.z = height;
478
479                                         textMesh2.rotation.x = Math.PI;
480                                         textMesh2.rotation.y = Math.PI * 2;
481
482                                         group.add( textMesh2 );
483
484                                 }
485
486                         }
487
488                         function refreshText() {
489
490                                 updatePermalink();
491
492                                 group.remove( textMesh1 );
493                                 if ( mirror ) group.remove( textMesh2 );
494
495                                 if ( !text ) return;
496
497                                 createText();
498
499                         }
500
501                         function onDocumentMouseDown( event ) {
502
503                                 event.preventDefault();
504
505                                 document.addEventListener( 'mousemove', onDocumentMouseMove, false );
506                                 document.addEventListener( 'mouseup', onDocumentMouseUp, false );
507                                 document.addEventListener( 'mouseout', onDocumentMouseOut, false );
508
509                                 mouseXOnMouseDown = event.clientX - windowHalfX;
510                                 targetRotationOnMouseDown = targetRotation;
511
512                         }
513
514                         function onDocumentMouseMove( event ) {
515
516                                 mouseX = event.clientX - windowHalfX;
517
518                                 targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
519
520                         }
521
522                         function onDocumentMouseUp( event ) {
523
524                                 document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
525                                 document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
526                                 document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
527
528                         }
529
530                         function onDocumentMouseOut( event ) {
531
532                                 document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
533                                 document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
534                                 document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
535
536                         }
537
538                         function onDocumentTouchStart( event ) {
539
540                                 if ( event.touches.length == 1 ) {
541
542                                         event.preventDefault();
543
544                                         mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
545                                         targetRotationOnMouseDown = targetRotation;
546
547                                 }
548
549                         }
550
551                         function onDocumentTouchMove( event ) {
552
553                                 if ( event.touches.length == 1 ) {
554
555                                         event.preventDefault();
556
557                                         mouseX = event.touches[ 0 ].pageX - windowHalfX;
558                                         targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
559
560                                 }
561
562                         }
563
564                         //
565
566                         function animate() {
567
568                                 requestAnimationFrame( animate );
569
570                                 render();
571                                 stats.update();
572
573                         }
574
575                         function render() {
576
577                                 group.rotation.y += ( targetRotation - group.rotation.y ) * 0.05;
578
579                                 camera.lookAt( cameraTarget );
580
581                                 renderer.clear();
582                                 renderer.render( scene, camera );
583
584                         }
585
586                 </script>
587
588         </body>
589 </html>