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);

1 Like

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.

Hi guys I just need to know if understood what you just discussed here, so you telling me that if I have lets say this tool :

which is just a SVG that you can configure to set different colors to the shown pattern, and lets say I want this tool to have that pattern displayed on a 3D sofa fabric. so I could do that by getting the document element info like here :

and then use this lines of code like this (having my DOM tree example in mind):
var svg = document.getElementById(“customizer-design”).children[0].children[0];
var s = new XMLSerializer().serializeToString(svg);
var encodedData = “data:image/svg+xml;base64,”+window.btoa(s);
var texture = BABYLON.Texture.LoadFromDataString(“svg”, encodedData, scene);

and I would have the live version (at the moment of running those lines of code of course) of that pattern configured by the user as a texture ready to be used on any mesh I want in my scene ?
I hope it is that simple cuz its exactly what I need to do with it , if not could you tell me what im missing guys ? would be of great help !!!

I guess it should be fine :slight_smile:

Great , thanks @sebavan , I ll let you guys know if anything comes up