Community Tip - Did you get an answer that solved your problem? Please mark it as an Accepted Solution so others with the same problem can find the answer easily. X
Solved! Go to Solution.
Hello @Ace_Rothstein ,
you can achieve this effect also with javascript. Here is an sample code which will work generally for widget which supports the opacity property e.g. 3D widgets modelItem, model or 3DImage etc. :
$scope.fadeOut = function(widget, time, interval) {
let w = (widget.opacity !== undefined ? widget : $scope.view.wdg[widget]); //wiget name or widget it self
if (time <= 0 || interval <= 0 || w.opacity === undefined) { throw "Cannot fade this widget"; }
let steps = Math.floor(time / interval);
let opDelta = w.opacity / steps;
return $interval(() => w.opacity = (opDelta < w.opacity) ? (w.opacity - opDelta) : 0, interval, steps);
}
$scope.fadeIn = function(widget, targetOpacity,time, interval) {
let w = (widget.opacity !== undefined ? widget : $scope.view.wdg[widget]);
if (time <= 0 || interval <= 0 || w.opacity === undefined) { throw "Cannot fade this widget"; }
let steps = Math.floor(time / interval);
let opDelta = targetOpacity / steps;
return $interval(() => w.opacity = (targetOpacity > w.opacity) ? (w.opacity + opDelta) : targetOpacity, interval, steps);
}
//call of the fadeOut for different widget with different time
$scope.testFadeOut= function()
{
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-1'],2000,200) } ,500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-2'],4000,200) } ,1500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-3'],6000,200) } ,2500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['model-1'] ,5000,200) } ,3500)
}
/call of the fadeIn for different widget with different time
$scope.testFadeIn= function()
{
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-1'],0.8,2000,200) } ,500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-2'],0.9,4000,200) } ,1500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-3'],1.0,6000,200) } ,2500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['model-1'] ,1.0,5000,200) } ,3500)
}
So this example will work where it will fade In or fade out different widgets (here modelItems and model) with different speed/time.
Here the arguments are
-the widget
-the time where the fade in/out should be completed,
-the interval step
-for fade in function the target opacity
Here when I tested it in a project:
You can test it as mentioned for widget which supports the opacity property. The $timeout service was used to call the functions with some delay.
You mentioned "to trigger" in your question. I think one possible way to trigger a function call depending on value change is to use $watch construct. Example:
:
$scope.$watch('view.wdg["model-1"].currentStep', function(val) {
//will call this function when the currentStep will chnage
if(val==2) $scope.testFadeOut();
if(val==4) $scope.testFadeIn();
$scope.$applyAsync();
});
Here we will call the function when the value of a widget property e.g. here currentStep (widget 'model-1') will change. We can also here via the function argument also the step value
We can watch also an application parameter – example app parameter renderLevel:
//=============================================================
$scope.$watch('app.params.renderLevel', function (newValue, oldValue, scope) {
// console.warn("called watch function with newValue=" +newValue+ " <=> oldValue was="+oldValue+ " <=> scope.renderLevel="+scope.renderLevel);
//pay attention here is scope without $ !
if(scope.renderLevel!= undefined) {
//console.log('new value of renderLevel = '+newValue);
scope.shaderUpdate(scope.renderLevel)
$scope.$applyAsync();
}
});
Hello ES_9419715,
The solution might be to use CSS stylesheet to do fade in and fade out.
Please have a look to this post :
https://stackoverflow.com/questions/30125705/css-how-to-make-an-element-fade-in-and-then-fade-out
About the event, I would recommend to look in these posts in PTC Community :
Best regards,
Samuel
Hello @Ace_Rothstein ,
you can achieve this effect also with javascript. Here is an sample code which will work generally for widget which supports the opacity property e.g. 3D widgets modelItem, model or 3DImage etc. :
$scope.fadeOut = function(widget, time, interval) {
let w = (widget.opacity !== undefined ? widget : $scope.view.wdg[widget]); //wiget name or widget it self
if (time <= 0 || interval <= 0 || w.opacity === undefined) { throw "Cannot fade this widget"; }
let steps = Math.floor(time / interval);
let opDelta = w.opacity / steps;
return $interval(() => w.opacity = (opDelta < w.opacity) ? (w.opacity - opDelta) : 0, interval, steps);
}
$scope.fadeIn = function(widget, targetOpacity,time, interval) {
let w = (widget.opacity !== undefined ? widget : $scope.view.wdg[widget]);
if (time <= 0 || interval <= 0 || w.opacity === undefined) { throw "Cannot fade this widget"; }
let steps = Math.floor(time / interval);
let opDelta = targetOpacity / steps;
return $interval(() => w.opacity = (targetOpacity > w.opacity) ? (w.opacity + opDelta) : targetOpacity, interval, steps);
}
//call of the fadeOut for different widget with different time
$scope.testFadeOut= function()
{
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-1'],2000,200) } ,500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-2'],4000,200) } ,1500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['modelItem-3'],6000,200) } ,2500)
$timeout( ()=>{$scope.fadeOut($scope.view.wdg['model-1'] ,5000,200) } ,3500)
}
/call of the fadeIn for different widget with different time
$scope.testFadeIn= function()
{
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-1'],0.8,2000,200) } ,500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-2'],0.9,4000,200) } ,1500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['modelItem-3'],1.0,6000,200) } ,2500)
$timeout( ()=>{$scope.fadeIn($scope.view.wdg['model-1'] ,1.0,5000,200) } ,3500)
}
So this example will work where it will fade In or fade out different widgets (here modelItems and model) with different speed/time.
Here the arguments are
-the widget
-the time where the fade in/out should be completed,
-the interval step
-for fade in function the target opacity
Here when I tested it in a project:
You can test it as mentioned for widget which supports the opacity property. The $timeout service was used to call the functions with some delay.
You mentioned "to trigger" in your question. I think one possible way to trigger a function call depending on value change is to use $watch construct. Example:
:
$scope.$watch('view.wdg["model-1"].currentStep', function(val) {
//will call this function when the currentStep will chnage
if(val==2) $scope.testFadeOut();
if(val==4) $scope.testFadeIn();
$scope.$applyAsync();
});
Here we will call the function when the value of a widget property e.g. here currentStep (widget 'model-1') will change. We can also here via the function argument also the step value
We can watch also an application parameter – example app parameter renderLevel:
//=============================================================
$scope.$watch('app.params.renderLevel', function (newValue, oldValue, scope) {
// console.warn("called watch function with newValue=" +newValue+ " <=> oldValue was="+oldValue+ " <=> scope.renderLevel="+scope.renderLevel);
//pay attention here is scope without $ !
if(scope.renderLevel!= undefined) {
//console.log('new value of renderLevel = '+newValue);
scope.shaderUpdate(scope.renderLevel)
$scope.$applyAsync();
}
});
Thanks a lot @RolandRaytchev ! Also is there a way to change the color of the font in a 3D Gauge after it achieves a certain value or after a particular time delay? Is there any Font attributes to change the font outline also.
Yes this is possible.
To change the text you can use e.g. watch and some code like :
$scope.$watch('view.wdg["3DGauge-1"].text', function(val) {
//will call this function when the currentStep will chnage
if(parseFloat(val)>=50) { // suposing that the text contains a float value
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(255, 0, 0,1);textbaseline:top;textalign:left");
$scope.setWidgetProp("3DGauge-1","font","Courier");
$scope.setWidgetProp("3DGauge-1","fontsize","60px");}
else {
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(0, 255, 255, 1);textbaseline:middle;textalign:center");
$scope.setWidgetProp("3DGauge-1","font","Arial");
$scope.setWidgetProp("3DGauge-1","fontsize","30px");
};
$scope.$applyAsync();
});
Antoher option is to use a style definition from Thingworx , so far I know it should work for 3DGauge
To change the values and to change back after some delays - the simple way is to use some construct like this:
$scope.myFunction= function()
{
var delay1=3000;// 3 secs
var delay2= 60000;// 6seconds
$timeout(()=>{
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(0, 255, 255, 1);textbaseline:middle;textalign:center");
$scope.setWidgetProp("3DGauge-1","font","Arial");
$scope.setWidgetProp("3DGauge-1","fontsize","30px");
$scope.$applyAsync();
},delay1); // this will call the first setting after delay1-> here 3 sec
$timeout(()=>{
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(255, 0, 0, 1);textbaseline:top;textalign:left");
$scope.setWidgetProp("3DGauge-1","font","Courier");
$scope.setWidgetProp("3DGauge-1","fontsize","60px");
$scope.$applyAsync();
},delay2); // this will call the second setting after delay2 -delay1
//after first call 3 sec and 6 sec after call of myFunction
};
Any idea about changing the font outline too? It appears that the font outline of the text in 3D gauges is white by default. It doesn't give a smooth transition effect unless the font outline changes too.
to have an apperance of the text outline like in this picture:
some code like this:
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(0, 0, 255, 1);textbaseline:top;textalign:left;font-size: 40px;stroke:green;colostroke-width: 3px;");
$scope.setWidgetProp("3DGauge-1","font","Arial");
$scope.setWidgetProp("3DGauge-1","fontsize","30px");
and to have an apperance of the text outline like in the second picture:
some code like this:
$scope.setWidgetProp("3DGauge-1","textattrs","fill:rgba(255, 0, 0, 1);textbaseline:top;textalign:left;font-size: 40px;stroke:black;colostroke-width: 3px");
$scope.setWidgetProp("3DGauge-1","font","Courier");
$scope.setWidgetProp("3DGauge-1","fontsize","60px");
Thanks for the tips!
But still I have a question.
3D Gauge Widget Text properties could be controlled by textattrs.
But how to proceed the same modification to a 3D Label Widget?
let theColor = 'rgba(' + R + ',' + G + ',' + B + ',1);';
$scope.setWidgetProp("3DLabel-1", "fontColor", theColor)
$scope.setWidgetProp("3DGauge-1","textattrs","fill:" + theColor + "textbaseline:middle;textalign:center;font-size: 40px;stroke:white;colostroke-width: 3px;");
The code above modify the Text Color of 3D Gauge Widget Text, but does nothing to 3D Label Widget Text.
What to resolve the issue?
Thanks in advance.
Hi @dsgnrClarK ,
yes , this is a good question. In fact I needed some tests to find out the difference here. I think this is a point what depends on the internal implementation of the widget.
So , what I believe (not 100% but seem to work) is that the Text appearance attribute on the toggle does not follow a CSS definition (also there is not explicit class attribute for this widget) but it use the SVG attributes according to the SVG attribute reference
https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute
e.g.
https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Fills_and_Strokes
The 3D label widget seem not to use the SVG attributes but it could be driven by the properties (Font Family Font Color, Font Outline Color and scale ) dr Also for the 3d Label you can use css style definition according to the Vuforia Studio Help : http://support.ptc.com/help/vuforia/studio/en/#page/Studio_Help_Center%2FWidget3DLabel.html
So for example the class defintion in the STYLES >Applicaiton :
.ptc-3DLabel {
font-family: Century Gothic;
color: black;
--text-stroke-color: yellow;
--text-stroke-width: 3px; /*csslint ignore*/
font-weight: normal;
font-style: italic;
background-color: grey;
}
will change the apperance of the 3DLabel to :