THREEJS sprite label text is hiding

I am using two different Three.js sprites to render an image and a label, but I am not able to display the full text at the top, bottom, left, and right positions.

please check the below link
link


Text should display in top position.

Hi!
Could you provide a picture of how the desired result has to look like?

I could make it to look like this, but I don’t know the goal.

Well …
at least a tiny bit of explanatory text would have been helpful …

Hello @prisoner849 i have uploaded the image, please have a look.

My comment was directed @Chaser_Code

Why not generate a whole texture procedurally? :thinking:

Demo: https://codepen.io/prisoner849/full/XJWYgOX

PS Not the ultimate solution, just an example.

4 Likes
  1. The arrow provided in the example, can be an image (user-profile picture or it can be an small icon or a 3D model)
  2. Billboard :Add text to the model at the top or bottom.
    Please have a look on above points @prisoner849

You can modify sprite’s geometry, to have a text at the place you want :thinking:


Demo: https://codepen.io/prisoner849/full/dPyKqVe

2 Likes

In my use case not using the threejs mesh, please check the below code. @prisoner849
Thanks.

        const root = new THREE.Object3D();
		root.position.x = 2;

		const imageCanvas = document.createElement('canvas');

		const imageContext = imageCanvas.getContext('2d');
		let url = 'https://devum-client-public-bucket.s3.amazonaws.com/winterdev/images/images/Arrow'

		const image = new Image();
		image.crossOrigin = "*";
		image.src = url;

		image.onload = function () {

			imageCanvas.width = image.width;
			imageCanvas.height = image.height;
			imageContext.drawImage(image, 0, 0, imageCanvas.width, imageCanvas.height);

			const imageTexture = new THREE.CanvasTexture(imageCanvas);
			const imageSpriteMaterial = new THREE.SpriteMaterial({
				map: imageTexture,
				alphaTest: 0.8,
				color: 'rgb(165, 42, 42)'
			});
			const imageSprite = new THREE.Sprite(imageSpriteMaterial);
			const imageSize = 2;
			imageSprite.scale.set(imageSize, imageSize, 0);
			root.add(imageSprite);


			// Create a canvas and set up the context
			const labelCanvas = document.createElement('canvas');
			const labelContext = labelCanvas.getContext('2d');

			// Measure text height to position correctly
			const text = 'Hello World';
			const textWidth = labelContext.measureText(text).width;

			// Set canvas size
			labelCanvas.width = textWidth + 500;  // Adjust size as needed
			labelCanvas.height = 256;

			// Set the font properties
			labelContext.font = '40px Arial';
			labelContext.fillStyle = 'black';
			labelContext.textAlign = 'center';

			// Set textBaseline to 'top' to prevent cutting off at the top
			labelContext.textBaseline = 'top';


			labelContext.fillText(text, 25, 24);  // Draw the text

			// Create a texture from the canvas
			const labelTexture = new THREE.CanvasTexture(labelCanvas);

			// Create a sprite material using the texture
			const labelMaterial = new THREE.SpriteMaterial({ map: labelTexture });

			// Create the sprite and add it to the scene
			const labelSprite = new THREE.Sprite(labelMaterial);
			root.add(labelSprite);

			scene.add(root);
		}
	
	}

I use THREE.Sprite :thinking:

You are adding the text to obj2 which is THREE.Mesh instance. In my case text is adding to imageSprite THREE.sprite
@prisoner849

let obj2 = new THREE.Mesh(
  new THREE.IcosahedronGeometry(1.5, 1),
  new THREE.MeshLambertMaterial({color: "magenta"})
);
obj2.geometry.computeVertexNormals();
obj2.position.x = 4;
let textSprite2 = new TextSprite(obj2, "Cool Stuff", "navy", "bottom")

It can be Object3D or Group or Mesh.

All, what TextSprite does, is adding itself to the object, passed in the parameter.
Try to pass Sprite instead of Mesh.
Feel free to modify my code to your needs. :thinking:

Okay @prisoner849.
Thank you.

@prisoner849 i have added my code with your example, can you please help where i am missing in below code.

		let imageCanvas = document.createElement('canvas');

		let imageContext = imageCanvas.getContext('2d');
		let url = 'https://devum-client-public-bucket.s3.amazonaws.com/winterdev/images/images/Arrow'

		let image = new Image();
		image.crossOrigin = "*";
		image.src = url;



		image.onload = function () {

			imageCanvas.width = image.width;
			imageCanvas.height = image.height;
			imageContext.drawImage(image, 0, 0, imageCanvas.width, imageCanvas.height);

			const imageTexture = new THREE.CanvasTexture(imageCanvas);
			const imageSpriteMaterial = new THREE.SpriteMaterial({
				map: imageTexture,
				alphaTest: 0.8,
				color: 'rgb(165, 42, 42)'
			});
			const imageSprite = new THREE.Sprite(imageSpriteMaterial);
			const imageSize = 2;
			imageSprite.scale.set(imageSize, imageSize, 0);
			imageSprite.position.x = -2;
let textSprite = new TextSprite(imageSprite, "Three.js", "maroon", "top");
scene.add(imageSprite);
    }
    

its working fine @prisoner849,Thank you so much.

1 Like