initial commit
This commit is contained in:
commit
e8c3f9862a
193 files changed
+29795
No files matched your search
@@ -0,0 +1,70 @@
|
||||
import { Texture } from './Texture.js';
|
||||
|
||||
export class TextRenderer {
|
||||
constructor(gl) {
|
||||
this.gl = gl;
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this._cachedKey = null;
|
||||
this._cachedEntry = null;
|
||||
}
|
||||
|
||||
draw(renderer, text, x, y, options = {}) {
|
||||
const entry = this._resolve(text, options);
|
||||
renderer.drawTexture(entry.texture, x, y, entry.width, entry.height);
|
||||
return entry;
|
||||
}
|
||||
|
||||
measure(text, options = {}) {
|
||||
return this._resolve(text, options);
|
||||
}
|
||||
|
||||
_resolve(text, options = {}) {
|
||||
const key = this._makeKey(text, options);
|
||||
if (this._cachedKey !== key) {
|
||||
this._flushCache();
|
||||
this._cachedKey = key;
|
||||
this._cachedEntry = this._rasterize(text, options);
|
||||
}
|
||||
return this._cachedEntry;
|
||||
}
|
||||
|
||||
_makeKey(text, { size = 20, font = 'arial', fillStyle = 'black', bold = true }) {
|
||||
return `${text}|${size}|${font}|${fillStyle}|${bold}`;
|
||||
}
|
||||
|
||||
_rasterize(text, { size = 20, font = 'arial', fillStyle = 'black', bold = true }) {
|
||||
const { ctx, canvas } = this;
|
||||
const pad = 4;
|
||||
const fontString = `${bold ? 'bold ' : ''}${size}px ${font}`;
|
||||
|
||||
ctx.font = fontString;
|
||||
const textWidth = Math.ceil(ctx.measureText(text).width);
|
||||
const width = textWidth + pad * 2;
|
||||
const height = Math.ceil(size * 1.3) + pad * 2;
|
||||
const scale = Math.min(window.devicePixelRatio || 1, 2);
|
||||
|
||||
canvas.width = Math.max(1, Math.ceil(width * scale));
|
||||
canvas.height = Math.max(1, Math.ceil(height * scale));
|
||||
ctx.setTransform(scale, 0, 0, scale, 0, 0);
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
|
||||
ctx.font = fontString;
|
||||
ctx.fillStyle = fillStyle;
|
||||
ctx.textAlign = 'left';
|
||||
ctx.textBaseline = 'alphabetic';
|
||||
ctx.fillText(text, pad, pad + size);
|
||||
|
||||
const texture = new Texture(this.gl, canvas.width, canvas.height);
|
||||
texture.uploadCanvas(canvas);
|
||||
|
||||
return { texture, width, height };
|
||||
}
|
||||
|
||||
_flushCache() {
|
||||
if (this._cachedEntry) {
|
||||
this._cachedEntry.texture.dispose();
|
||||
this._cachedEntry = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user