Community Tip - Stay updated on what is happening on the PTC Community by subscribing to PTC Community Announcements. X
Hi,
I'm interested in changing a 3D image widget based on a property. I see that it's possible to dynamically bind the Resource property of the 3D image, but simply writing the string literal of the image resource doesn't work.
Can anyone help me with this? Thank you.
Solved! Go to Solution.
my second example/ code is the more complicated version and not the simplest way - that what I meant in the previous post saying (actually the best way is to use the URL of the picture directly ) . In same cases you can try to load an url which is not directly visible for you widget and you need to load it e.g. via $http or fetch services first to memory and then set to the source prop
In your case you can use the simple way (which do the same but internally for the widget implemented)
In your case you can use some code like this:
$scope.setWidgetProp("3DImage-1","src", "app/resources/Uploaded/pinger_tap.png");
or
var global_count_int1=0;
//----- HERE IS THE ANIMATION from Server
$interval( function(){
{
if( global_count_int1 > 9) global_count_int1=0;
global_count_int1++;
var url_source= "app/resources/Uploaded/pic_0"+global_count_int1+".gif";
$scope.$applyAsync(function() {
//$scope.view.wdg['3DImage-3']['source'] =url_source; //direct assigment to the prop
$scope.app.params['image_url']=url_source;//assignee to app par + binding
}
); //end applyAsync
}
} , 500);
The second function will show in loop every 0.5 seconds a other picture - from pic_01.gif to pic_09.gif and again....
In this case the function will change a value of a parameter which has binding to the resource property of the 3DImage (src). Using a application parameter in same case will update the display more stable as the direct assignment of the property.
Hi @Radu ,
depending on the way how you want to create the string.
So for example if you want to generate a svg format you can do something like this:
$scope.svg_ret = function(txt,imgWidget) {
var txtL=""
var xmlsrc='<?xml version="1.0" encoding="UTF-8" standalone="no"?>\n'
xmlsrc=xmlsrc+'<svg xmlns="http://www.w3.org/2000/svg" height="1000" width="600">\n'
xmlsrc=xmlsrc+'<rect x="50" y="300" width="200" height="100" style="fill:red"/>\n'
// xmlsrc=xmlsrc+'<image width="700" height="400" href="'+txtL+'"/>'
xmlsrc=xmlsrc+'<circle cx="350" cy="300" r="40" stroke="black" stroke-width="3" fill="red" margin-top="300px" />\n'
xmlsrc=xmlsrc+'<text x="10" y="20" style="fill:red;">Several lines:\n'
xmlsrc=xmlsrc+'<tspan x="10" y="45">First line.</tspan>\n'
xmlsrc=xmlsrc+'<tspan x="10" y="70">Second line.</tspan>\n'
xmlsrc=xmlsrc+'</text>\n'
xmlsrc=xmlsrc+'</svg>'
console.log('here $scope.view.wdg['+imgWidget+'].src=')
console.warn('data:image/svg+xml;base64,'+xmlsrc)
$scope.view.wdg[imgWidget].src='data:image/svg+xml;base64,'+btoa(xmlsrc);
}
If you want to read a picture from a URL - (actually the best way is to use the URL of the picture directly ) but you can read the content of the picture to a string and then assignee it to the src or imgsrc property (depending if 3D or 2D image):
$http({
method: 'GET',
url: 'app/resources/Uploaded/' + img_str,
responseType: 'arraybuffer'
}).then(function(response) {
//---------------
img_data = _arrayBufferToBase64(response.data);
//----------------
//console.log( img_data);
var ret_str='data:image/jpeg;base64,'+img_data;
$scope.view.wdg['image-2']['imgsrc']=ret_str;
}
Where the function "_arrayBufferToBase64" is defined as :
///////////////////////////////////////////////////
function _arrayBufferToBase64(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[i]);
}
return window.btoa(binary);
}
Hi.
Thank you for your quick response! I'm a bit confused to how to interpret what you sent me, so I will rephrase to make sure we're both on the same page, first:
I have two images that I uploaded, img1.png and img2.png. They appead in the Uploaded/ directory. I want to have a single 3D image that either shows img1.png or img2.png, based on the value of a property. This was done simply in Thingworx through an expression. What you suggested should be written in the Home.js file, right?
If you agree with what I said before, could you please go a bit over the solution you provided, because I don't quite understand what it does. I appreciate it!
Best regards,
Radu
my second example/ code is the more complicated version and not the simplest way - that what I meant in the previous post saying (actually the best way is to use the URL of the picture directly ) . In same cases you can try to load an url which is not directly visible for you widget and you need to load it e.g. via $http or fetch services first to memory and then set to the source prop
In your case you can use the simple way (which do the same but internally for the widget implemented)
In your case you can use some code like this:
$scope.setWidgetProp("3DImage-1","src", "app/resources/Uploaded/pinger_tap.png");
or
var global_count_int1=0;
//----- HERE IS THE ANIMATION from Server
$interval( function(){
{
if( global_count_int1 > 9) global_count_int1=0;
global_count_int1++;
var url_source= "app/resources/Uploaded/pic_0"+global_count_int1+".gif";
$scope.$applyAsync(function() {
//$scope.view.wdg['3DImage-3']['source'] =url_source; //direct assigment to the prop
$scope.app.params['image_url']=url_source;//assignee to app par + binding
}
); //end applyAsync
}
} , 500);
The second function will show in loop every 0.5 seconds a other picture - from pic_01.gif to pic_09.gif and again....
In this case the function will change a value of a parameter which has binding to the resource property of the 3DImage (src). Using a application parameter in same case will update the display more stable as the direct assignment of the property.
Thank you for the great tips!