cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Visit the PTCooler (the community lounge) to get to know your fellow community members and check out some of Dale's Friday Humor posts! X

3D-Label visibility in a certain time

DenGrz
8-Gravel

3D-Label visibility in a certain time

Hello,

 

i have button-1  to start a sequence.

Now i want to create an 3D-Label that becomes visible after click the button-1.

And the 3D-Label have to be visible as long as the sequnce is played.

 

Is there any Js-Code to do this so?

Thanks in advance.

1 ACCEPTED SOLUTION

Accepted Solutions

Hi @DenGrz ,

 

here created and tested an example which should demonstrate the suggestion. It is not perfect but should demonstrate the general approach to achieve this goal.

The table with values is a json file- in the attached example is the file steps.json in the Project upload folder. Here example of values:

 

{"1":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 1", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel1"},
"3DLabel-2":{"visible":true,"text":"text Label2 Step 1", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 1", "x":0.0,"y":0.3,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"}},
"2":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 2", "x":0.0,"y":0.1,"z":0.1,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-2":{"visible":false,"text":"text Label2 Step 2", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 2", "x":0.0,"y":0.3,"z":0.1,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"}},
"3":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 3", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":20.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"},
....
"8":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 8", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel1"},
"3DLabel-2":{"visible":true,"text":"text Label2 Step 8", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 8", "x":0.0,"y":0.3,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"}}}

 

Here the table contains the most possible value to set for 3DLabels. We can add other or omit values in the list. In generally we need only the values which should be changed but such list template which contains all values is better for editing. It should still work so far, the json syntax is correct

First point is to load the list to a global variable from the project upload folder:

 

$scope.jsonData_steps={}; //global $scope variable
//==================================
readSteps=function (jsonFile){
  console.warn("**=>readSteps :: "+jsonFile);
fetch(jsonFile)
  .then(response=>response.text())
  .then(data=>{$scope.jsonData_steps=JSON.parse(data);
                             console.warn(  JSON.stringify($scope.jsonData_steps))})
  .catch((wrong) => {console.log("problem in fetch: "); console.warn(wrong)})
}
//==================================

$scope.Init=function() {
$timeout(readSteps('app/resources/Uploaded/'+stepsjson),200);
}
//=================================================================================================
//   $ionicView.afterEnter -> this event fires when 2d view was entered
//=================================================================================================
$scope.$on('$ionicView.afterEnter',function(){
  console.log("$ionicView.afterEnter was called");
$scope.Init();}) //event: when 2d View loaded
//=================================================================================================

 

further in the "stepstarted" event the code will set the  values of the widget properties which are contained by the json object  with the same number as the started step number:

 

//=================================================================================================
$scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { 
 var parsedArg3 = JSON.parse(arg3);
console.log("stepstarted stepNumber="+parsedArg3.stepNumber + "  nextStep="+parsedArg3.nextStep);
$timeout(()=>{ $scope.setMutipleProps($scope.jsonData_steps[parsedArg3.stepNumber.toString()])},10)
$scope.setWidgetProp('label-1', 'text',"STEP: "+ parsedArg3.stepNumber) 
  $scope.$applyAsync();
 
}); 
//=================================================================================================
//this function set multiply properties from a list
//=================================================================================================
$scope.setMutipleProps  = function(obj){

 Object.keys(obj).forEach(function (item)  {
                for(var prop in obj[item])    {
                           $scope.view.wdg[item][prop]=obj[item][prop];  
                           //print the setting for debugging                 
							console.log("==>$scope.view.wdg["+item+"]["+prop+"]="+obj[item][prop] )
                                              } 
                							})
                  $scope.$applyAsync();  };
                  
 
///=================================================================================================

 

Finally, I tested it and was working as expected:  

 

2020-05-19_9-59-43.jpg

I attached the project where I tested the functionality and hope it is helpful for you! Thanks

View solution in original post

7 REPLIES 7

Hi @DenGrz ,

 

so far, I know it is not possible (using the supported functionality) to create widget on the fly - means create a new feature on run time where the widget was not defined in the design time. Theoretical with some more intensive work – it will be possible – we simple need to check what the UI is doing when you copy and paste widget  (but it is not easy ☹-  and it is not sure if this solution will be stable(if you will be able to implement 1:1 UI) and if it will work in later version -because PTC dev team could change some functionality – but will not change your code.
For the most tasks it enough to use few 3d widgets (3Dlabels) the most are invisible and then switch the visibility on runtime and move them on the desired location.
I checked also in internal chat what the dev team states and found in 2 different chats the following stemmers:

 

 

 

1.) Question: “Vuforia Studio 8.5.3.Is it possible to create 2D and 3D widgets from Java Script?
Answer: If you mean to dynamically create/instatiate a widget and set its properties at runtime, no we have no such capability today.

The simplest workaround is to pre-generate the widgets and manage their visibility at runtime.
2.) Question: Is it possible to create 2D widget dynamically by Java Script?
Answer: Its fairly easy to have a couple of hidden widgets that are displayed and moved with a tap event.

It might be possible to create some 2d widgets on the fly, but 3d widgets would be a bit harder as more of the unsupported api under the hood would be needed.

 

 

I think , it will be better to try to use the workarond with some template / precreated widgets  and then  make them visible and move them on the correct postion. You can then for different steps use the same 3DLabel and simple change the widget text according to the step name, number ... or description . Following evens could be used   newStep ,stepstarted or stepcompleted to set visibility and text of the widget. Also you can set different postion - move the widget

Hi @RolandRaytchev ,

 

that´s a really good idea.

 " You can then for different steps use the same 3DLabel and simple change the widget text according to the step name, number ... or description . Following evens could be used   newStep ,stepstarted or stepcompleted to set visibility and text of the widget. Also you can set different postion - move the widget "

 

How would be looks like the JS-Code ?

And how it´s possible to change positions for each steps of the same label?

 

Hi @DenGrz ,

np, is OK. I could prepare a simple example.

To let check what are the basic / general requirements - so far

-changing the visibility form js code

-moving to specific location. - which location? How is the target location defined? e.g.  - > here what is possible – is  to move - manually the item to a location in UI - and check the values for x,y,z , rx, ry, rz and scale then write them to a table - json file- this will be the easy way to do this - Another way- more difficult is to find a value based on other widget - but this require further considerations and will make it more difficult

- use only one or 2 3DLabel widget and change it for each step

-when we need to display the 3DLabels widget?- and what we need to display  on it? e.g. the current step , the next step ... etc.?

 

Hi @RolandRaytchev ,

 

ok so i have two Sequences with each one Step.

When the sequence 1 is played the labels 1, 2 and 3 have to be visible.

When the sequence 2 is played the labels 4, 5 and 6 have to be visible.

In all of this labels are only one word in it, so not a step description or something like this.

 

I create a table with coordinates for a better overview:

 

Labels_Koord.PNG

 

I hope that this information are enough.

OK , thanks but according to the statement:

"

When the sequence 1 is played the labels 1, 2 and 3 have to be visible.

When the sequence 2 is played the labels 4, 5 and 6 have to be visible.

"

My question is: if there  a reals reason to have 4,5,6 here

Why not to use 1,2,3 again - also for step 2 but we could here change the position and will change the text content. In this case we need to have to define number of 3DLabel widgets which is equal to the maximum of used notes per step - and display and update only the necessary  number of widget in particular step

Yes sure if it works so, will be perfect.

Hi @DenGrz ,

 

here created and tested an example which should demonstrate the suggestion. It is not perfect but should demonstrate the general approach to achieve this goal.

The table with values is a json file- in the attached example is the file steps.json in the Project upload folder. Here example of values:

 

{"1":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 1", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel1"},
"3DLabel-2":{"visible":true,"text":"text Label2 Step 1", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 1", "x":0.0,"y":0.3,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"}},
"2":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 2", "x":0.0,"y":0.1,"z":0.1,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-2":{"visible":false,"text":"text Label2 Step 2", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 2", "x":0.0,"y":0.3,"z":0.1,"rx":0.0,"ry":10.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"}},
"3":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 3", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":20.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"},
....
"8":{"3DLabel-1":{"visible":true,"text":"text Label1 Step 8", "x":0.0,"y":0.1,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel1"},
"3DLabel-2":{"visible":true,"text":"text Label2 Step 8", "x":0.0,"y":0.2,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel2"},
"3DLabel-3":{"visible":true,"text":"text Label3 Step 8", "x":0.0,"y":0.3,"z":0.0,"rx":0.0,"ry":0.0,"rz":0.0,"scale":1.0,"class":"ptc-3DLabel3"}}}

 

Here the table contains the most possible value to set for 3DLabels. We can add other or omit values in the list. In generally we need only the values which should be changed but such list template which contains all values is better for editing. It should still work so far, the json syntax is correct

First point is to load the list to a global variable from the project upload folder:

 

$scope.jsonData_steps={}; //global $scope variable
//==================================
readSteps=function (jsonFile){
  console.warn("**=>readSteps :: "+jsonFile);
fetch(jsonFile)
  .then(response=>response.text())
  .then(data=>{$scope.jsonData_steps=JSON.parse(data);
                             console.warn(  JSON.stringify($scope.jsonData_steps))})
  .catch((wrong) => {console.log("problem in fetch: "); console.warn(wrong)})
}
//==================================

$scope.Init=function() {
$timeout(readSteps('app/resources/Uploaded/'+stepsjson),200);
}
//=================================================================================================
//   $ionicView.afterEnter -> this event fires when 2d view was entered
//=================================================================================================
$scope.$on('$ionicView.afterEnter',function(){
  console.log("$ionicView.afterEnter was called");
$scope.Init();}) //event: when 2d View loaded
//=================================================================================================

 

further in the "stepstarted" event the code will set the  values of the widget properties which are contained by the json object  with the same number as the started step number:

 

//=================================================================================================
$scope.$on('stepstarted', function(evt, arg1, arg2, arg3) { 
 var parsedArg3 = JSON.parse(arg3);
console.log("stepstarted stepNumber="+parsedArg3.stepNumber + "  nextStep="+parsedArg3.nextStep);
$timeout(()=>{ $scope.setMutipleProps($scope.jsonData_steps[parsedArg3.stepNumber.toString()])},10)
$scope.setWidgetProp('label-1', 'text',"STEP: "+ parsedArg3.stepNumber) 
  $scope.$applyAsync();
 
}); 
//=================================================================================================
//this function set multiply properties from a list
//=================================================================================================
$scope.setMutipleProps  = function(obj){

 Object.keys(obj).forEach(function (item)  {
                for(var prop in obj[item])    {
                           $scope.view.wdg[item][prop]=obj[item][prop];  
                           //print the setting for debugging                 
							console.log("==>$scope.view.wdg["+item+"]["+prop+"]="+obj[item][prop] )
                                              } 
                							})
                  $scope.$applyAsync();  };
                  
 
///=================================================================================================

 

Finally, I tested it and was working as expected:  

 

2020-05-19_9-59-43.jpg

I attached the project where I tested the functionality and hope it is helpful for you! Thanks

Top Tags