examples/website/plot/plot-layer/utils.js (45 lines of code) (raw):

/* global document */ import GL from '@luma.gl/constants'; import {Texture2D} from '@luma.gl/core'; // helper for textMatrixToTexture function setTextStyle(ctx, fontSize) { ctx.font = `${fontSize}px Helvetica,Arial,sans-serif`; ctx.fillStyle = '#000'; ctx.textBaseline = 'top'; ctx.textAlign = 'center'; } /* * renders a matrix of text labels to texture2D. * @param {WebGLRenderingContext} glContext * @param {[[String]]} data: text to render, in array of columns (array of strings) * @param {Number} fontSize: size to render with * @returns {object} {texture, columnWidths} */ export function textMatrixToTexture(glContext, data, fontSize = 48) { const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d'); setTextStyle(ctx, fontSize); // measure texts const columnWidths = data.map(column => { return column.reduce((acc, obj) => { const w = ctx.measureText(obj.text).width; return Math.max(acc, Math.ceil(w)); }, 0); }); const canvasWidth = columnWidths.reduce((x, w) => x + w, 0); const canvasHeight = data.reduce( (h, column) => Math.max(h, Math.ceil(column.length * fontSize)), 0 ); if (canvasWidth === 0 || canvasHeight === 0) { // empty canvas willl cause error in Texture2D return null; } canvas.width = canvasWidth; canvas.height = canvasHeight; // changing canvas size will reset context setTextStyle(ctx, fontSize); /* * +----------+----------+----------+ * | col0:0 | col1:0 | col2:0 | * +----------+----------+----------+ * | col0:1 | col1:1 | col2:1 | * +----------+----------+----------+ * | ... | ... | ... | */ let x = 0; data.forEach((column, colIndex) => { x += columnWidths[colIndex] / 2; column.forEach((obj, i) => { ctx.fillText(obj.text, x, i * fontSize); }); x += columnWidths[colIndex] / 2; }); return { columnWidths, texture: new Texture2D(glContext, { pixels: canvas, [GL.TEXTURE_MAG_FILTER]: GL.LINEAR }) }; }