I would like to create a “wall of text” which is just a plane with some lines of text on it. I have been successful in doing this in the html canvas however when applied as a texture it gets somehow messed up. The text only appears in the upper left hand corner (not clamping?) and the first half of each line is being cut off. It also appears slightly grainy to me.
While I have you, do you have any suggestions for how to make a marquee for scrolling text? My first thought is to just create new texture and upload it every frame. That seems a little sluggish but it doesn’t seem like CSS would apply here.
https://playcanvas.com/project/677177/overview/text
https://www.w3schools.com/code/tryit.asp?filename=GDO27CGFPUFP
Text.attributes.add('text', { type: 'string', default: 'Hello World'});
Text.prototype.initialize = function () {
// Create a canvas to do the text rendering
this.canvas = document.createElement('canvas');
this.canvas.height = 512;
this.canvas.width = 512;
this.context = this.canvas.getContext('2d');
this.texture = new pc.Texture(this.app.graphicsDevice, {
format: pc.PIXELFORMAT_R8_G8_B8,
autoMipmap: true
});
this.texture.setSource(this.canvas);
this.texture.minFilter = pc.FILTER_LINEAR_MIPMAP_LINEAR;
this.texture.magFilter = pc.FILTER_LINEAR;
this.texture.addressU = pc.ADDRESS_CLAMP_TO_EDGE;
this.texture.addressV = pc.ADDRESS_CLAMP_TO_EDGE;
this.updateText();
var material = this.entity.model.material;
material.emissiveMap = this.texture;
material.opacityMap = this.texture;
material.blendType = pc.BLEND_NORMAL;
material.update();
this.on('attr', function (name, value, prev) {
this.updateText();
});
};
Text.prototype.updateText = function () {
var ctx = this.context;
var w = ctx.canvas.width;
var h = ctx.canvas.height;
// Clear the context to transparent
ctx.fillStyle = 'black';
ctx.fillRect(0, 0, w, h);
// Write white text
ctx.fillStyle = 'white';
ctx.font = 'bold 24px Verdana';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var textRemaining = this.text.toString();
var i = 1;
while (textRemaining.length > 0) {
var textLine;
if (textRemaining.length < 50) {
textLine = textRemaining;
textRemaining = "";
} else {
textLine = textRemaining.slice(0, 50);
textRemaining = textRemaining.slice(50);
}
ctx.fillText(textLine, 10, 32 * i, w - 20);
if (32 * i > w) break; // too many lines, omit the rest
i++;
}
// Copy the canvas into the texture
this.texture.upload();
};