Drawing SVG content (text) into DynamicTexture doesn't work in Safari < v15

We’re drawing SVGs to meshes using DynamicTexture which is working fine in most browser except Safari <= v14 (neither on MacOS, nor on iOS). The code shown is working in Safari v15.

What we’re doing is basically the following:

  • Convert SVG (from source text) to an HTML image
  • Create a DynamicTexture
  • Draw the image to its canvas context
  • Apply the texture to a given mesh’s material

Whilst the SVG is correctly shown on the given mesh in most browsers it is simply not shown in Safari <= v14. There are no exceptions shown in the browser console.

image

Here are the most important parts of the code:

/**
 * Convert SVG text to HTML image which can be drawn to canvas
 */
const getImageFromSvg = async function(svgSrc) {
    const svgBlob = new Blob([svgSrc], { type: 'image/svg+xml;charset=utf-8' });
    const svgBase64 = URL.createObjectURL(svgBlob);
    let img = new Image();
    return new Promise(resolve => {
        img.onload = () => resolve(img);
        img.src = svgBase64;
    });
}

/**
 * - Create DynamicTexture for given mesh
 * - Draw SVG onto the texure's canvas context
 */
const drawSvgToMesh = async function(mesh, svgSrc) {
    // Create texture & draw image to its canvas ctx
    const img = await getImageFromSvg(svgSrc);
    const textureOptions = { width: 2048, height: 2048 };
    const texture = new BABYLON.DynamicTexture('svgTexture', textureOptions, scene, false);
    texture.getContext().drawImage(img, 0, 0);
    texture.update(false);

    // Apply texture to mesh material
    mesh.material.transparencyMode = BABYLON.Material.MATERIAL_ALPHATESTANDBLEND;
    mesh.material.albedoTexture = texture;
}

Also here’s a runnable version showing the issue in the playground:
https://playground.babylonjs.com/#3FS0P3#9

Is this a bug or are we doing something wrong? I also tried drawing text directly to the canvas context using fillText without the SVG which is working fine in Safari as well but that’s unfortunately no option, as our source images always come in form of SVG text.

1 Like

It looks like a Safari bug which is unfortunately out of our hands :frowning: you could try reporting it on their bug tracker but as it is fixed in 15 they ll probably tell you to upgrade.

Hi @sebevan, thank you for your fast response!

That is very unfortunate to hear. We’re running a SAAS platform (www.combeenation.com), helping our business customers sell customizable products to their end users whom we obviously can’t really tell to update their browser.

Is there maybe some other way to achieve what we’re looking for (which is drawing SVG to a 3d model) somehow circumventing the issue at hand?

Maybe you could try smthg like this Change SVG texture in realtime - #8 by geesea ?

Thank you @sebevan, what you posted looks very promising so far!
I guess this can be closed now & I’ll simply get back to you here in case we encounter further issues with this.

Thank you again for your fast & friendly help :muscle:

1 Like

FYI, there is also a way to make it work with DynamicTextures.
The source of the image must be provided as data string and not as object URL.
const svgEncoded = 'data:image/svg+xml,' + encodeURIComponent(svgSrc);
=> see adapted Playground example (line 30)

This does not make any sense but this is so cool you found a workaround !!! I ll bookmark it :slight_smile: