Question:
I’m trying to create a ring of text that rotates around a box in the middle like how gyroscope ring rotates around the middle, or that gyroscopic bbq grill. It’s sort of like the picture provided, but with thin text that rotates along its x y and z.
I want it to be pure text and not just text wrapped around a torus, because then the text isn’t readable, and is oddly streched.
What I tried:
Using a torus:
i made a canvas that renders the text (it’s a foreign language), creates a texture from the canvas, apply that texture onto torus, and then try and adjust the wrapping to make it look clean.
code:
// Create the canvas and render the Urdu text
const canvas = document.createElement('canvas');
canvas.width = 1024;
canvas.height = 512;
const context = canvas.getContext('2d');
context.fillStyle = '#000000'; // Black background
context.fillRect(0, 0, canvas.width, canvas.height);
// Set text properties
context.fillStyle = '#ffffff'; // White
context.font = '48px "Noto Nastaliq Urdu", "Arial", sans-serif';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.direction = 'rtl';
const urduText = 'کبھی کبھی مرے دل میں خیال آتا ہے کہ زندگی تری زلفوں کی نرم چھاؤں میں گزرنے پاتی تو شاداب ہو بھی سکتی تھی';
// Function to wrap the Urdu text
function wrapText(context, text, maxWidth) {
const words = text.split(' ').reverse();
let lines = [];
let line = '';
for (let n = 0; n < words.length; n++) {
const testLine = words[n] + ' ' + line;
const metrics = context.measureText(testLine);
const testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
lines.push(line.trim());
line = words[n] + ' ';
} else {
line = testLine;
}
}
lines.push(line.trim());
return lines;
}
const lines = wrapText(context, urduText, canvas.width - 50);
const lineHeight = 60;
let y = canvas.height / 2 - ((lines.length - 1) / 2) * lineHeight;
for (const line of lines) {
context.fillText(line, canvas.width / 2, y);
y += lineHeight;
}
const torusTexture = new THREE.CanvasTexture(canvas);
// Adjust texture wrapping
torusTexture.wrapS = THREE.RepeatWrapping;
torusTexture.wrapT = THREE.ClampToEdgeWrapping;
torusTexture.repeat.set(1, 1);
// the torus
const torusMaterial = new THREE.MeshBasicMaterial({ map: torusTexture });
const geometry = new THREE.TorusGeometry(10, 0.5, 16, 100);
const torus = new THREE.Mesh(geometry, torusMaterial);
torus.rotation.x = Math.PI / 2;
scene.add(torus);
but this gives me a very ugly torus with stretched text inside
how can I possibly not use torus at all and instead create a ring of text that acts like torus.
thanks




