Hello everyone,
I’m working on a project in which I need to draw latex dynamically on a playcanvas client.
Before going with playcanvas, i was using MathJax to convert my data and print it on html client.
Something like :
math to be print → latex → svg → html canvas on client.
Now, the problem i’m having is playcanvas can’t print SVG directly.
So i was looking for the easiest way to do it efficiently.
Is convert SVG to PNG/JPG the best solution ? Sharp seemed to be great for that, but it’s only work with node.js. And i can’t find a client side alternative.
Or should i generate my latex to image directly (so change MathJax to something else) ?
I noted Mathjax can also convert latex to html string.
I could also do the converting on server side, but i will need to download the image to everyclient, and I just want something not too complex.
I’m trying to do thing like suggested here and I’m not succeeding so far. For now it look like :
Battle.prototype.testMathJaxAndSVGconvert = function () {
//const toPNG = new Worker('toPNG.js'); I gave up on using worker... for now
let svg = this.generateSVGFromLaTeX("\\sqrt[3]{8}=8^{\\frac{1}{3}}=2 ");
console.log(svg);
let width = 600;
let height = 600;
// creating OffscreenCanvas
const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext('2d');
// Preparing to render the SVG on blob then to canvas
var DOMURL = window.URL || window.webkitURL || window;
var img1 = new Image();
var blob = new Blob([svg], { type: 'image/svg+xml;charset=utf-8' });
//var svg = new Blob([data], { type: 'image/svg+xml' });
var url = DOMURL.createObjectURL(blob);
console.log(blob);
console.log(url);
img1.onload = function () {
ctx.drawImage(img1, 25, 70);
DOMURL.revokeObjectURL(url);
};
img1.src = url;
console.log(img1);
console.log(canvas);
// export my offscreen canvas to Png via a blob
const blobPng = canvas.convertToBlob().then(blobPng => this.nextStep(blobPng));
};
this.nextStep :
Battle.prototype.nextStep = function (blobPng) {
console.log(blobPng);
pngUrl = URL.createObjectURL(blobPng);
console.log(pngUrl);
//applying resulting image to screen entity
console.log('trying applying texture to screen entity');
var textureAsset = new pc.Asset("texture", "texture", {
url: pngUrl
});
this.app.assets.add(textureAsset);
this.app.assets.load(textureAsset);
let screen = this.app.root.findByName('imagePNG');
screen.element.texture = textureAsset.resource;
};
generateSVGFromLaTeX,
//here we convert string latex to svg with mathjax
Battle.prototype.generateSVGFromLaTeX = function (latex) {
let math = MathJax.tex2svg(latex, {
format: 'inline-TeX',
display: false
});
console.log(math);
return math;
};
But the screen imagePNG don’t show my generetad png.
I’m not sure where is problem is. With console.log i’have checked data at every step.
And even through it seem like all part to create SVG and turning it into PNG work, I’m probably doing not it efficiently, so I’m open to any recommendation.
Hi, thank you for your response.
Progress have been made since yesterday : I have threw away the whole OffScreenCanvas thing : it’s seem Canvas → Image progress rely on Blob object, so you should directly use it to convert SVG. It’s now much more simple :
Battle.prototype.generateMathImage = function (formula) {
const svgData = new XMLSerializer().serializeToString(this.generateSVGFromLaTeX(formula));
const blob = new Blob([svgData], { type: "image/svg+xml" });
const imgResult = new File([blob], "MyEquation.png", { type: "image/png" });
let urlImgResult = URL.createObjectURL(imgResult);
However, my current issue is that I am failing to use the resulting PNG file. It is throwing a DOMException: “An attempt was made to use an object that is not, or is no longer, usable.”