상세 컨텐츠

본문 제목

[WebGL] Three.js, Canvas - 3DText, 2DText, Font, 텍스트 Draw, Render

WEB/WebGL

by AlrepondTech 2017. 12. 28. 17:57

본문

반응형

 

 

=================================

=================================

=================================

 

 

 

출처: http://bl.ocks.org/MAKIO135/eab7b74e85ed2be48eeb

 

index.html#

<!DOCTYPE html> <html> <head>   <meta charset="utf-8">   <title>JS Bin</title> </head> <body style="background:#fff;"> <script src="http://cdnjs.cloudflare.com/ajax/libs/three.js/r68/three.min.js"></script> <canvas id="canvas"></canvas> <script id="jsbin-javascript"> var width = window.innerWidth, height = window.innerHeight / 2; var size = 256; var canvas = document.getElementById('canvas'),     ctx = canvas.getContext('2d');  var camera, scene, renderer, geometry, texture, mesh;  function changeCanvas() {     ctx.font = '20pt Arial';     ctx.fillStyle = 'red';     ctx.fillRect(0, 0, canvas.width, canvas.height);     ctx.fillStyle = 'white';     ctx.fillRect(10, 10, canvas.width - 20, canvas.height - 20);     ctx.fillStyle = 'black';     ctx.textAlign = "center";     ctx.textBaseline = "middle";     ctx.fillText(new Date().getTime(), canvas.width / 2, canvas.height / 2); }  function init() {     renderer = new THREE.WebGLRenderer();     renderer.setSize(width, height);     document.body.appendChild(renderer.domElement);        scene = new THREE.Scene();        camera = new THREE.PerspectiveCamera(70, width / height, 1, 1000);     camera.position.z = 500;     scene.add(camera);      texture = new THREE.Texture(canvas);     var material = new THREE.MeshBasicMaterial({ map: texture });     geometry = new THREE.BoxGeometry( 200, 200, 200 );     mesh = new THREE.Mesh( geometry, material );     scene.add( mesh );      canvas.width = canvas.height = size; }  function animate() {     requestAnimationFrame(animate);        changeCanvas();     texture.needsUpdate = true;     mesh.rotation.y += 0.01;     renderer.render(scene, camera); }  init(); animate(); </script> </body> </html>

 

 

 

=================================

=================================

=================================

 

 

 

출처: https://threejs.org/docs/#manual/introduction/Creating-text

 

Creating text

There are often times when you might need to use text in your three.js application - here are a couple of ways that you can do so.

1. DOM + CSS

Using HTML is generally the easiest and fastest manner to add text. This is the method used for descriptive overlays in most three.js examples.

You can add content to a

<div id="info">Description</div>

and use CSS markup to position absolutely at a position above all others with a z-index especially if you are running three.js full screen.

#info { position: absolute; top: 10px; width: 100%; text-align: center; z-index: 100; display:block; }

2. Draw text to canvas and use as a Texture

Use this method if you wish to draw text easily on a plane in your three.js scene.

3. Create a model in your favourite 3D application and export to three.js

Use this method if you prefer working with your 3d applications and importing the models to three.js

4. Procedural Text Geometry

If you prefer to work purely in THREE.js or to create procedural and dynamic 3D text geometries, you can create a mesh whose geometry is an instance of THREE.TextGeometry:

new THREE.TextGeometry( text, parameters );

In order for this to work, however, your TextGeometry will need an instance of THREE.Font to be set on its "font" parameter. See the TextGeometrypage for more info on how this can be done, descriptions of each accepted parameter, and a list of the JSON fonts that come with the THREE.js distribution itself.

Examples

WebGL / geometry / text
canvas / geometry / text
WebGL / shadowmap

If Typeface is down, or you want to use a font that is not there, there's a tutorial with a python script for blender that allows you to export text to Three.js's JSON format: http://www.jaanga.com/2012/03/blender-to-threejs-create-3d-text-with.html

 

 

=================================

=================================

=================================

 

 

 

출처: https://github.com/mrdoob/three.js/issues/3754

 

 

revision 59

I need to add 2d text which always face to camera like Particle or Sprite. Example:


I've tried to do it like this:

    var canvas = document.createElement( 'canvas');     canvas.width = 300;     canvas.height = 90;      var context = canvas.getContext('2d');     context.font = "40pt Arial";      var x=canvas.width/2,         y=canvas.height/2;      context.textAlign = 'center';     context.fillStyle = "rgba(255,0,0,1)";     context.fillText('HELLO!!!', x, y);      var texture = new THREE.Texture(canvas);     texture.needsUpdate = true;      var material = new THREE.ParticleBasicMaterial( {map: texture, blending: THREE.AdditiveBlending } );     material.transparent = true;      var particle = new THREE.Particle(material);     scene.add(particle);

And it work's only with CanvasRenderer (IE9) and doesn't work with WebGLRenderer (Chrome 27.0). Is this bug of three.js or I do something wrong?

I saw this example:
http://stemkoski.github.io/Three.js/Texture-From-Canvas.html
but in it used Mesh.
Yes, we can use lookAt(camera.position), but I have reason to don't use this way.

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: https://stackoverflow.com/questions/41441144/adding-2d-text-on-plane-geometry-three-js

 

Adding 2D text on plane geometry three.js

 

I have created plane geometry and textured 2D text on plane geometry but I am unable to fit the text on plane geometry properly and I need to set the width and height of plane geometry according to the size of text can someone please help me how to do this. I have also uploaded code and image.

 

for(var i=0; i<spriteResponse.length; i++) {          var canvas = document.createElement('canvas');     var context = canvas.getContext('2d');     metrics = null,     textHeight = 100,     textWidth = 0,     actualFontSize = 2;     context.font = "normal " + textHeight + "px Arial";     metrics = context.measureText(cardinal.name);     var textWidth = metrics.width;     canvas.width = textWidth;     canvas.height = textHeight;     context.font = "normal " + textHeight + "px Arial";     context.textAlign = "center";     context.textBaseline = "middle";     context.fillStyle = "#ff0000";     context.fillText(cardinal.name, textWidth / 2, textHeight / 2);       var texture = new THREE.Texture(canvas) ;     texture.needsUpdate = true;     //var spriteAlignment = new THREE.Vector2(0,0) ;     var material = new THREE.MeshBasicMaterial( {color: 0xffffff, side: THREE.DoubleSide ,map : texture} );     var geometry = new THREE.PlaneGeometry( 0.5, 0.3);     plane = new THREE.Mesh( geometry, material );     plane.position.set(X_value,0,Z_value);      scene.add(plane);     var direction = camera.getWorldDirection();     plane.lookAt(direction); }
 

 

 

 

=================================

=================================

=================================

 

 

 

 

출처: https://questionfocus.com/three-js-2d-text-sprite-labels.html

 

 

Questions:

I’m new to three.js and have some issues belonging 2D Text:

What I want:
I want some Labels for eg. the x,y and z-axis. The labels should always look to the camera. Maybe later they should only be shown, if their hovered but that’s another topic.

What are my issues
I found this tutorial (which is excatly the effect I want to achieve | http://stemkoski.github.io/Three.js/Sprite-Text-Labels.html), but it’s for an old version of three.js using methods like var spriteAlignment = THREE.SpriteAlignment.topLeft;. I found this workaround (THREE.SpriteAlignment showing up as undefined) but it’s not clear for me how I could use the new approach for my needs.

What I’m looking for
Maybe you could help me name that thing I was searching for or come up with a short approach.

Answers:

Text Sprites are nice, but if you use more then thousand of it it can slow down everything because of the GPU.

There is a “better” way, create the Sprite as Canvas, here is a function that I use too for it:

    function makeTextSprite( message, parameters )     {         if ( parameters === undefined ) parameters = {};         var fontface = parameters.hasOwnProperty("fontface") ? parameters["fontface"] : "Arial";         var fontsize = parameters.hasOwnProperty("fontsize") ? parameters["fontsize"] : 18;         var borderThickness = parameters.hasOwnProperty("borderThickness") ? parameters["borderThickness"] : 4;         var borderColor = parameters.hasOwnProperty("borderColor") ?parameters["borderColor"] : { r:0, g:0, b:0, a:1.0 };         var backgroundColor = parameters.hasOwnProperty("backgroundColor") ?parameters["backgroundColor"] : { r:255, g:255, b:255, a:1.0 };         var textColor = parameters.hasOwnProperty("textColor") ?parameters["textColor"] : { r:0, g:0, b:0, a:1.0 };          var canvas = document.createElement('canvas');         var context = canvas.getContext('2d');         context.font = "Bold " + fontsize + "px " + fontface;         var metrics = context.measureText( message );         var textWidth = metrics.width;          context.fillStyle   = "rgba(" + backgroundColor.r + "," + backgroundColor.g + "," + backgroundColor.b + "," + backgroundColor.a + ")";         context.strokeStyle = "rgba(" + borderColor.r + "," + borderColor.g + "," + borderColor.b + "," + borderColor.a + ")";          context.lineWidth = borderThickness;         roundRect(context, borderThickness/2, borderThickness/2, (textWidth + borderThickness) * 1.1, fontsize * 1.4 + borderThickness, 8);          context.fillStyle = "rgba("+textColor.r+", "+textColor.g+", "+textColor.b+", 1.0)";         context.fillText( message, borderThickness, fontsize + borderThickness);          var texture = new THREE.Texture(canvas)          texture.needsUpdate = true;          var spriteMaterial = new THREE.SpriteMaterial( { map: texture, useScreenCoordinates: false } );         var sprite = new THREE.Sprite( spriteMaterial );         sprite.scale.set(0.5 * fontsize, 0.25 * fontsize, 0.75 * fontsize);         return sprite;       } 

 

Answers:

I’ve published a module on NPM that does that for you: https://github.com/gamestdio/three-text2d

It allows you to have an Object3D with rendered text without dealing with canvas manually.

Example:

var Text2D = require('three-text2d').Text2D  var text = new Text2D("Hello world!", { align: textAlign.right, font: '30px Arial', fillStyle: '#000000', antialias: true }) scene.add(text)  

 

 

 

=================================

=================================

=================================

 

 

 

출처: https://stackoverflow.com/questions/25850654/draw-text-from-canvas-into-three-js-as-a-sprite

 

 

long story short, I'm making a live line chart and I'm using three.js due to the high number of lines per second that needs to be pushed inside this thing, so, now I'd need to draw the text values for the x and y axis, after a pretty long struggle ( because I'm a total noob @ threejs ) I figured out the wonderful technique of using the canvas as a sprite ( which is darn rad ). This is the code that I use
/// 2D REALM var canvas = document.createElement('canvas'), context = canvas.getContext('2d'), metrics = null, textHeight = 100, textWidth = 0, actualFontSize = 2; context.fillStyle = '#FF0000'; var size = 250; canvas.width = size; canvas.height = size; function addText(position, text) { context.textAlign = 'center'; context.font = '24px Arial'; context.fillText("Game Over", size/2, size/2); var texture = new THREE.Texture(canvas); texture.needsUpdate = true; var material = new THREE.SpriteMaterial( { map: texture, color: 0x333333, fog: false } ); var sprite = new THREE.Sprite( material ); sprite.position.set(0,100,0); return sprite; } . . . $(document).ready(function() { h = $(window).height() - $('.speed-graph').outerHeight() - $('.speed-toolbar').outerHeight() - $('.channel-toolbar').outerHeight() - $('.status_bar').outerHeight() + 1; w = $(window).width() - $('.palette').outerWidth(); camera = new THREE.PerspectiveCamera( 75, parseFloat(w) / parseFloat(h), 0.1, 5000 ); //renderer.setSize( window.innerWidth, window.innerHeight ); console.log("w: " + w + " | h: " + h); renderer.setSize(w, h); $('body').append( renderer.domElement ); var material = new THREE.LineBasicMaterial({ color: 0x000000, linewidth: 1 }); var geometry = new THREE.Geometry(); geometry.vertices.push( new THREE.Vector3(-10 , 0, 0 ) ); geometry.vertices.push( new THREE.Vector3(8 , 0, 0 ) ); lines['line'].push( new THREE.Line( geometry, material )) text = addText(new Array(0, 9), "lorem ipsum"); //lines['label'].push( addText(new Array(0, 9), "0") ); scene.add( lines['line'][0] ); scene.add( text ); camera.position.z = 5; render(); });
now, the lines get drawn as they should, but I had no luck at all with the text. I can't understand the reason why I can't see the text, because I don't get any compiler error.
shareimprove this question
 
in the end, I figured it out by myself, problem was that the canvas didn't had a proper size, plus a bunch of other stuff.
for the sake of the solution, and hoping to help others in the future, here's the working code along with a codepen to see it live in action.
/// 2D REALM //var canvas = document.createElement('canvas'), var canvas, context, metrics = null, textHeight = 10, textWidth = 0, actualFontSize = 0.12; canvas = document.createElement('canvas'), context = canvas.getContext('2d'); context.fillStyle = '#FF0000'; function addText(position, text) { // 2d duty metrics = context.measureText(text); var textWidth = metrics.width; canvas.width = textWidth; canvas.height = textHeight; context.font = "normal " + textHeight + "px Arial"; context.textAlign = "center"; context.textBaseline = "middle"; context.fillStyle = "#ff0000"; context.fillText(text, textWidth / 2, textHeight / 2); var texture = new THREE.Texture(canvas); texture.needsUpdate = true; var material = new THREE.SpriteMaterial({ map: texture, useScreenCoordinates: false }); var sprite = new THREE.Sprite( material ); var textObject = new THREE.Object3D(); // var sprite = new THREE.Sprite(texture); textObject.textHeight = actualFontSize; textObject.textWidth = (textWidth / textHeight) * textObject.textHeight; sprite.scale.set(textWidth / textHeight * actualFontSize, actualFontSize, 1); // sprite.position.set(10,10,0); textObject.add(sprite); return textObject; } var scene = new THREE.Scene(); var camera; var renderer = new THREE.WebGLRenderer({ alpha: 1, antialias: true, clearColor: 0xffffff }); $(document).ready(function() { h = $(window).height() - $('.speed-graph').outerHeight() - $('.speed-toolbar').outerHeight() - $('.channel-toolbar').outerHeight() - $('.status_bar').outerHeight() + 1; w = $(window).width() - $('.palette').outerWidth(); camera = new THREE.PerspectiveCamera( 75, parseFloat(w) / parseFloat(h), 0.1, 5000 ); console.log("w: " + w + " | h: " + h); renderer.setSize(w, h); $('body').append( renderer.domElement ); text = addText(new Array(0, 9), "it works!!"); scene.add( text ); console.log(text.position); // text.position.x = 3.0; camera.position.z = 5; render(); }); // render the whole things up function render() { requestAnimationFrame(render); renderer.render(scene, camera); }
shareimprove this answer

 

 

=================================

=================================

=================================

 

 

 

출처: https://www.html5canvastutorials.com/tutorials/html5-canvas-wrap-text-tutorial/

 

 

HTML5 Canvas Text Wrap Tutorial

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
    <script>
      function wrapText(context, text, x, y, maxWidth, lineHeight) {
        var words = text.split(' ');
        var line = '';
 
        for(var n = 0; n < words.length; n++) {
          var testLine = line + words[n] + ' ';
          var metrics = context.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > maxWidth && n > 0) {
            context.fillText(line, x, y);
            line = words[n] + ' ';
            y += lineHeight;
          }
          else {
            line = testLine;
          }
        }
        context.fillText(line, x, y);
      }
      
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var maxWidth = 400;
      var lineHeight = 25;
      var x = (canvas.width - maxWidth) / 2;
      var y = 60;
      var text = 'All the world \'s a stage, and all the men and women merely players. They have their exits and their entrances; And one man in his time plays many parts.';
 
      context.font = '16pt Calibri';
      context.fillStyle = '#333';
 
      wrapText(context, text, x, y, maxWidth, lineHeight);
    </script>
  </body>
</html>      

Discussion

To wrap text with HTML5 Canvas, we can create a custom function that requires the canvas context, a text string, a position, a max width, and a line height. The function should use the measureText() method of the canvas context to calculate when the next line should wrap.

 

=================================

=================================

=================================

 

 

 

출처: https://www.html5canvastutorials.com/tutorials/html5-canvas-text-font-size/

 

 

HTML5 Canvas Text Font, Size, and Style Tutorial

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
    <script>
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
 
      context.font = 'italic 40pt Calibri';
      context.fillText('Hello World!', 150, 100);
    </script>
  </body>
</html>      

Discussion

To draw text using HTML5 Canvas, we can use the font property and the fillText() method of the canvas context.

To set the font, size, and style of HTML5 Canvas text, we can set the font property of the canvas context to a string containing the font style, size, and family, delimited by spaces.  The style can be normalitalic, or bold.  unless otherwise specified, the font style is defaulted to normal.

Once the font property has been set, we can draw the text with the fillText() method, which requires a string and an x and y position.

 

 

=================================

=================================

=================================

 

 

 

출처: http://delphic.me.uk/webgltext.html

 

 

WebGL text using a Canvas Texture

Text (and numbers) is something that is very useful to render, it's very often both the easiest and best way of conveying information. WebGL does not have any in-build text rendering functions, based as it is on the OpenGL ES 2.0 specification. There are two options available to us when we wish to render text, using HTML and overlaying it on top of the canvas or rendering the text as a texture within WebGL (technically it's probably possible to render it using a shader too).

If you're making a UI / menu system, it would be fairly crazy not use the HTML method as coupled with CSS that's one of it's main strengths. However if you want to have the text in the game world, a HUD or an interface that isn't going to take the user's full attention you will probably want to render the text in WebGL. (Note: If you try overlaying a HUD written in HTML you will encounter issues when trying to click and drag on the canvas element, you will get the text cursor even if you've overridden it as described in my controlling the cursor articleand as far as I can tell there is no way around this).

For the purposes of this article I will assume you are familiar with the basics of WebGL, up to and including the creation of textures from files. I am going to use a modified version of learningWebGL's lesson 7, if you are not familiar with the basics required to render textured 3D shapes you should review the lessons at learningWebGL site.

There are three main (fairly small) hurdles to rendering your text as a texture.

  • Drawing text with the canvas element
  • Sizing the canvas/texture appropriately
  • Binding the canvas to a WebGL texture

I'll go through each of these and then at the bottom will have a texture generator and a WebGL display of this texture.

Drawing text using the canvas element

There are plenty of tutorials on how to render text using the canvas element, and you can figure out most of it from the MDN's drawing text using a canvas reference page. I'm going to repeat the basics of what we need here for completeness, first we need a canvas element and to get it's 2D context.

<canvas id="textureCanvas">I'm sorry your browser does not support the HTML5 canvas element.</canvas> <script> 	var canvas  document.getElementById('textureCanvas'); 	var ctx = canvas.getContext('2d'); 	 	// More code to go here! </script> 

When it comes time to combine this with WebGL this should be a separate canvas to the one we are using for WebGL as it will be using a different context, but don't worry you can "display: none;" the canvas you are using for the texture with CSS and the method will still work.

Next we need to set up the properties of the text we wish to render, these include colour, size, font, alignment and vertical alignment, see the MDN reference for a full list of options and their descriptions, we'll stick the simple ones for now.

var canvas  document.getElementById('textureCanvas'); var ctx = canvas.getContext('2d');  ctx.fillStyle = "#333333"; 	// This determines the text colour, it can take a hex value or rgba value (e.g. rgba(255,0,0,0.5)) ctx.textAlign = "center";	// This determines the alignment of text, e.g. left, center, right ctx.textBaseline = "middle";	// This determines the baseline of the text, e.g. top, middle, bottom ctx.font = "12px monospace";	// This determines the size of the text and the font family used

Finally we render our text to the canvas, we provide an x and y coordinate (this is in pixels relative to the top-left of the canvas) at which to render the text. Where the text then appears relative to these coordinates is determined by the textAlign and textBaseline we specified. Baseline works as you expect and the baseline as specified is rendered at the y-coordinate. However textAlign is slightly more complex:

  • "left" or equivalent will cause the text to appear to the right of the specified x-coordinate
  • "center" will cause the text to appear centered on the specified x-coordinate
  • "right" or equivalent will cause the text to appear to the left of the specified x-coordinate

So for left aligned text we would probably specify 0 as the x-coordinate, and the full canvas width as the x-coordinate for right aligned text. As we have chosen center aligned we will specify the middle of the canvas.

ctx.fillText("HTML5 Rocks!", canvas.width/2, canvas.height/2);

You can also give the text an outline using ctx.strokeStylectx.strokeText, but we are not going to cover that for our texture generator.

Sizing the canvas and multi-line text

We need to ensure that the canvas is larger than the text we are rendering and for some implementations of WebGL textures are required to be a power of two. We'll start by automatically working out the size we need the for text rendered as a single line, then we will look at specifying a maximum width and spliting the text into multiple lines to be rendered. To do this we'll use the measureText function, this returns an object who's width property is the width in pixels of the text specified if drawn with the current settings. We also need a function to get the first power of 2 greater than or equal to this value.

function getPowerOfTwo(value, pow) { 	var pow = pow || 1; 	while(pow<value) { 		pow *= 2; 	} 	return pow; }  var canvas = document.getElementById('textureCanvas'); var ctx = canvas.getContext('2d'); var textToWrite = "HTML5 Rocks!"; var textSize = 12; ctx.font = textSize+"px monospace"; 	// Set the font of the text before measuring the width! var canvas.width = getPowerOfTwo(ctx.measureText(textToWrite).width); var canvas.height = getPowerOfTwo(2*textSize);  // Omitted: Set all properties of the text again (including font)  // Omitted: Draw the text

I've omitted the code for setting the properties and drawing the text as it won't have *really* changed. As well as setting the width of the canvas to the first power of two greater than the width of the text, we've also set the height to the first power of two greater than twice the height of the text we'll be drawing (to allow space for larger characters and to ensure a bit of padding). Note that you must set the font property of the context a second time after measuring the text or you'll get the default font and size rendering our calculation inaccurate!

Now for the possiblity of splitting up long text into multiple lines. We'll do this by specifying a maximum width, and breaking the text into an array of words and compare the specified width to text constructed from a decreasing number of words from that array of words, then from that we can build up an array of text lines which are smaller than the maximum width. The function below does this, the array to write the lines of text to is passed as an argument so that the maximum width of the calculated lines can be returned, it also replaces any newline characters with a space, this is because the drawText function ignores them and we are using the position of spaces to create our array of words.

function createMultilineText(ctx, textToWrite, maxWidth, text) { 	textToWrite = textToWrite.replace("\n"," "); 	var currentText = textToWrite; 	var futureText; 	var subWidth = 0; 	var maxLineWidth = 0; 	 	var wordArray = textToWrite.split(" "); 	var wordsInCurrent, wordArrayLength; 	wordsInCurrent = wordArrayLength = wordArray.length; 	 	// Reduce currentText until it is less than maxWidth or is a single word 	// futureText var keeps track of text not yet written to a text line 	while (measureText(ctx, currentText) > maxWidth && wordsInCurrent > 1) { 		wordsInCurrent--; 		var linebreak = false; 		 		currentText = futureText = ""; 		for(var i = 0; i < wordArrayLength; i++) { 			if (i < wordsInCurrent) { 				currentText += wordArray[i]; 				if (i+1 < wordsInCurrent) { currentText += " "; } 			} 			else { 				futureText += wordArray[i]; 				if(i+1 < wordArrayLength) { futureText += " "; } 			} 		} 	} 	text.push(currentText); // Write this line of text to the array 	maxLineWidth = measureText(ctx, currentText); 	 	// If there is any text left to be written call the function again 	if(futureText) { 		subWidth = createMultilineText(ctx, futureText, maxWidth, text); 		if (subWidth > maxLineWidth) {  			maxLineWidth = subWidth; 		} 	} 	 	// Return the maximum line width 	return maxLineWidth; }

The eagle eyed amoung you will have noticed that the maximum width can be greater than the maximum width specified, this will happen if a single word is greater than the maximum width (e.g. supercalifragilistic...), if you want to make sure that the maximum width specified truly is you'll have to further split words into characters. For now we'll just feed the maximum line width returned by the function into the calculation of the required canvas width.

Now we'll loop over the array to draw our text, splitting the text does complicate choosing the y-coordinate to draw each line at slightly. The code below is again omitts some of the code that we've already covered (setting up the canvas, the functions we just went over, setting the property of the text to draw).

// Omitted: helper functions 			 var text = []; var textX, textY; var textToWrite = "HTML5 Rocks! HTML5 Rocks! HTML5 Rocks!";  var textHeight = 32; var maxWidth = 128;  // Omitted: Set up the canvas and get the context  ctx.font = textHeight+"px monospace"; maxWidth = createMultilineText(ctx, textToWrite, maxWidth, text); canvasX = nextPowerOfTwo(maxWidth); canvasY = nextPowerOfTwo(textHeight*(text.length+1));  // Omitted: Set canvas width / height  // Omitted: Set text properties  textX = canvasX/2; var offset = (canvasY - textHeight*(text.length+1)) * 0.5;  for(var i = 0; i < text.length; i++) { 	textY = (i+1)*textHeight + offset; 	ctx.fillText(text[i], textX,  textY); }

Creating the WebGL texture

After all that creating the WebGL texture is relatively straight forward! When loading the texture one must simply pass the DOM object of the canvas where before one would pass the DOM object for the image. Then bind the created texture before rendering our object as normal using gl.bindTexture(gl.TEXTURE_2D, canvasTexture);where gl is the WebGL context.

gl = canvas.getContext("experimental-webgl"); var canvasTexture;  function initTexture() {     canvasTexture = gl.createTexture();     handleLoadedTexture(canvasTexture, document.getElementById('textureCanvas')); }  function handleLoadedTexture(texture, textureCanvas) {     gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);      gl.bindTexture(gl.TEXTURE_2D, texture);     gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureCanvas); // This is the important line!     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);     gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);     gl.generateMipmap(gl.TEXTURE_2D);      gl.bindTexture(gl.TEXTURE_2D, null); }

I have combined the above techniques with a quick web form to generate canvas textures and then display them on an altered version of learingWebGL's lesson 7. There is also an option to enforce a square texture (as we're placing it on a cube). You can play around with it below, all the JavaScript is inline so if you view source you can see how it works, it still needs a bit of work to be able to be used in full project but it's a reasonable proof of concept. I hope this article was helpful, if you have any comments or feedback you can contact me via twitter @_delph.

 

 

=================================

=================================

=================================

 

 

 

출처: https://www.w3schools.com/tags/canvas_measuretext.asp

 

현재텍스트의 실제 가로,세로 크기

 

 

ctx.measureText(txt).width

 

HTML canvas measureText() Method

❮ HTML Canvas Reference

Example

JavaScript:

var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
var txt="Hello World"
ctx.fillText("width:" + ctx.measureText(txt).width,10,50)
ctx.fillText(txt,10,100);

 

출처: https://stackoverflow.com/questions/31305071/measuring-text-width-height-without-rendering

accepted
문자열 가로크기

this.context.measureText(txt).width;

문자열 세로크기

parseInt(this.context.font);

 

Please check this. is a solution using canvas

function get_tex_width(txt, font) {         this.element = document.createElement('canvas');         this.context = this.element.getContext("2d");         this.context.font = font;         return this.context.measureText(txt).width;     }     alert('Calculated width ' + get_tex_width("Hello World", "30px Arial"));     alert("Span text width "+$("span").width());

Demo using

EDIT

The solution using canvas is not the best, each browser deal different canvas size.

Here is a nice solution to get size of text using a temporary element. Demo

EDIT

The canvas spec doesn't give us a method for measuring the height of a string, so for this we can use parseInt(context.font). TO get width and height. This trick work only with px size.

function get_tex_size(txt, font) {     this.element = document.createElement('canvas');     this.context = this.element.getContext("2d");     this.context.font = font;     var tsize = {'width':this.context.measureText(txt).width, 'height':parseInt(this.context.font)};     return tsize; } var tsize = get_tex_size("Hello World", "30px Arial");  alert('Calculated width ' + tsize['width'] + '; Calculated height ' + tsize['height']);
shareimprove this answer
    
will fail with em, don't know why though since it does work with % and viewport units. Also be carefull, in this context this is the window object, so you are actually creating global variables element and context. – Kaiido Jul 9 '15 at 3:03 
    
@Kaiido Thank you for comment. Yes, canvas deals different the % and em size. So this will work only with px dimensions. So the only way to get the width as will be in DOM is to create e temporary element, add-it to DOM, apply styles and the get size. – vasilenicusor Jul 9 '15 at 6:06
    
no actually it does work with % and viewport units (vh, vw...) but it doesn't with em, which is strange – Kaiido Jul 9 '15 at 6:08
    
but the main issue is still that you do play with globals – Kaiido Jul 9 '15 at 6:13
2  
Temporary elements don't really work due to performance requirements. The canvas thingy is my top candidate atm though. I think of making some zero size canvas with position:fixed and x-index:-1000 and then reusing the context for measureText. – Seppo420 Jul 9 '15 at 8:48

 

 

=================================

=================================

=================================

 

 

 

기타관련링크:

 

Three Canvas 2D Text:

https://stemkoski.github.io/Three.js/Texture-From-Canvas.html

 

Three Canvas 2D Text:

http://bl.ocks.org/phil-pedruco/9852362 

 

Three Canvas 2D Text:

https://gist.github.com/ekeneijeoma/1186920/14a33b795f5cb9fa175ea2bc333d6ed3bb488bc0

 

Three Canvas 2D Text:

https://www.evermade.fi/pure-three-js-hud/

 

Three Canvas 2D Text:

http://graphic-sim.com/21_HUD.php

 

Three Canvas 2D Text:

http://collaboradev.com/tag/threejs/

 

Three 2D Text:

https://github.com/gamestdio/three-text2d

 

Three 2D Text:

http://learningthreejs.com/blog/2014/05/02/easy-to-use-dynamic-texture-to-write-text-in-your-3d-object-with-threex-dot-dynamictexture-game-extensions-for-three-dot-js/

 

 

Canvas Text:

https://www.w3schools.com/tags/canvas_filltext.asp

 

Canvas Text:

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_text

 

Canvas Text:

https://japhr.blogspot.kr/2012/09/positioning-canvas-text-on-threejs.html

 

Canvas Text:

https://codepen.io/issyoni7/pen/wJojVY

 

Canvas Text:

http://chimera.labs.oreilly.com/books/1234000001654/ch03.html#filltext_and_stroketext

 

Canvas Text 속성:

https://www.w3schools.com/tags/canvas_font.asp

 

Canvas Input:

https://goldfirestudios.com/blog/108/CanvasInput-HTML5-Canvas-Text-Input

 

Canvas Input:

https://github.com/goldfire/CanvasInput

 

Canvas Input:

https://jsfiddle.net/AbdiasSoftware/VWzTL/

 

캔버스 텍스트 입력기:

https://codepen.io/jdnichollsc/pen/waVMdB?editors=001

 

Three 텍스트:

https://threejs.org/docs/#api/geometries/TextGeometry

 

Three 벡터 텍스트:

https://github.com/mrdoob/three.js/issues/4746

 

 

Three Canvas 텍스쳐 폰트

http://jsfiddle.net/sSD65/28/

 

 

 

=================================

=================================

=================================

 

 

반응형


관련글 더보기

댓글 영역