Change SVG texture in realtime

I know how to load SVG textures just by simply using BABYLON.Texture() but I’m wondering how I can change colour of some of the elements in the SVG in realtime? Say there is a circle in the SVG. I’d like users to be able to change colour of the circle. Does anyone know how to do this?

I know how to load the SVG into a variable using AJAX and I can change the XML contents, but not sure how to use SVG data stored in a variable as a BABYLON texture.

Unfortunately as soon as the SVG is transfered to the texture it loses all its abilities as it becomes a simple bitmap
You can perhaps dispose the previous texture and generates a new one from the updated svg?

1 Like

I don’t mind generating a new texture. It doesn’t need to be 100% realtime.
I can load the SVG in memory and change its contents. But how can I put that into a texture?

I tried BABYLON.Texture.LoadFromDataString(“texture”,svgElement, scene) but that doesn’t work.

You can use a blob and an object url I think.
example of use:
https://www.babylonjs-playground.com/#5ZCGRM#43

All good! I found a way :slight_smile:

(after loading file via Ajax into variable “xml”)
var svg = xml.documentElement;
var s = new XMLSerializer().serializeToString(svg);
var encodedData = “data:image/svg+xml;base64,”+window.btoa(s);
var texture = BABYLON.Texture.LoadFromDataString(“svg”, encodedData, scene);

even better!

@ozRocker

Any chance you can do a playground of that to help a fella out? LOL. I’ve been bashing away at this same problem for over a week. Thanks!

1 Like

Ok, So here’s where I stand:

// create a variable to the path of the .xml or .svg file
var defaultSVG = “PATH TO FILE”;

$.get(defaultSVG , function(data) {

// @ozRocker code here
var svg = data.documentElement;
var s = new XMLSerializer().serializeToString(svg);
var encodedData = ‘data:image/svg+xml;base64,’ + window.btoa(s);
var texture = BABYLON.Texture.LoadFromDataString(‘data’ , encodedData, scene);

var meshPBR = new BABYLON.PBRMaterial(“meshPBR” , scene);
mesh.material = meshPBR;
meshPBR.albedoTexture = new BABYLON.Texture(texture , scene);
});

I can verify that the SVG code is loading and converting to an image by logging the svg and texture variables in the console. But I am still getting this error:

Uncaught TypeError: Cannot read property ‘width’ of null
at O (babylon.js:16)
at e.createTexture (babylon.js:16)
at new t (babylon.js:16)
at Object.success (“PATH TO BABYLON CODE”:119)
at u (jquery.min.js:2)
at Object.fireWith [as resolveWith] (jquery.min.js:2)
at k (jquery.min.js:2)
at XMLHttpRequest. (jquery.min.js:2)

Any idea why?

@geesea Something looks weird.

You’ve already created your texture here with this:
var texture = BABYLON.Texture.LoadFromDataString(‘data’ , encodedData, scene);

You should be able to just use that like:
meshPBR.albedoTexture = texture;

or even:
meshPBR.albedoTexture = BABYLON.Texture.LoadFromDataString(‘data’ , encodedData, scene);

@ozRocker

OMG. I really hate myself right now! HAHAHA. You are correct.