I need to show some text in Persian/Arabic language. I loaded a font including characters and I used TextGeometry to create a text on the scene:
var loader = new THREE.FontLoader();
loader.load('B Zar_Regular.js', function (font) {
var textGeo = new THREE.TextGeometry('سلام!', {
font: font,
size: 1,
height: 0.05,
curveSegments: 12,
});
var material = new THREE.MeshNormalMaterial();
var textMesh = new THREE.Mesh(textGeo, material);
textMesh.position.x = 15;
scene.add(textMesh);
});
I was expecting to see سلام!
but the output was:
letters are separated and order of characters is reversed mistakenly. After all it seems threejs do not support rtl languages. Am I right or I missed something? Is there any workaround as a quick solution? Thanks.
First of all I found very useful blog post here by Chris Loer. He has written a plugin (mapbox-gl-rtl-text.js) that solves the problem.
Usage example:
var rtlText = require('mapbox-gl-rtl-text');
var arabicString = "سلام";
var shapedArabicText = rtlText.applyArabicShaping(arabicString);
var readyForDisplay = rtlText.processBidirectionalText(shapedArabicText, []);
RtlTextHelper.farsify("سلام");
Usage example:
private createTextMesh(font, text) {
var shapedText = RtlTextHelper.farsify(text);
var fontSize = 0.3;
var textHieght = 0.2;
var material = new THREE.MeshBasicMaterial({
color: this.colors.label.normal,
side: THREE.DoubleSide
});
var textGeo = new THREE.TextGeometry(shapedText, {
font: font,
size: fontSize,
height: 0.05,
curveSegments: 12
});
var textMesh = new THREE.Mesh(textGeo, material);
textGeo.computeBoundingBox();
var box = new THREE.Box3().setFromObject(textMesh);
var textLength = box.max.x;
return {
mesh: textMesh,
hieght: textHieght,
font: {
size: fontSize
},
length: textLength
};
}