Community Tip - Need to share some code when posting a question or reply? Make sure to use the "Insert code sample" menu option. Learn more! X
Hi,
I created a 3 figures in creo illustrator and imported into Vuforia studio. In 2D canvas drag and drop the select widget for creating a list of figures. Below i have attached the code which i used to create a list. List and 3D images are working fine. But I'm unable to play the animation of the sequences.
How to add the buttons to play the animation?. kindly guide me.
// create a list of identifiers and descriptions for the 'select list' widget
var stepListJSON;
PopulateStepList = function() {
stepListJSON=[
{
stepID: "Mesh panel removal",
stepTitle: "Mesh panel removal",
stepNum: 1
},
{
stepID: "Mesh panel assembly",
stepTitle: "Mesh panel assembly",
stepNum: 2
},
{
stepID: "Lubrication",
stepTitle: "Lubrication",
stepNum: 3
},
];
console.log(stepListJSON);
$scope.view.wdg.stepList.list= stepListJSON;
}
//when the model is loaded, execute the following function(s) - view action binding in the 'Model Loaded' JS property window of the 'model-1' widget
$scope.startup = function () {
PopulateStepList();
}
GetStepNumberID = function (stepID) {
var numberID = "UNKNOWN_ID";
Object.keys(stepListJSON).forEach(function(item){
if (stepListJSON[item].stepID == stepID) {
numberID = stepListJSON[item].stepNum;
}
});
return numberID;
}
//evaluate selected step to determine image visibility
$scope.evaluateStep = function () {
var selectedValue = $scope.view.wdg["stepList"]['value'];
var stepNumber = GetStepNumberID(selectedValue);
if (stepNumber == 3){
$scope.view.wdg['3DImage-1']['visible']=true;
} else {
$scope.view.wdg['3DImage-1']['visible']=false;
}
}
Solved! Go to Solution.
Hi Both, Successfully i got an output as per my expectation. Small update is required. The 3D label is appearing when model is loaded. which means, when sequence is empty, 3D image is appearing. how to avoid that?.
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model-1']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.setWidgetProp("3DImage-1", 'visible', true);
else
$scope.setWidgetProp("3DImage-1", 'visible', false);
$scope.$applyAsync();
},50);
}
Hi @TM_9260611 ,
without looking more deeply in your code I think that what you want is a functionality calling playing a step for pvz name a step number. I used in the past the following function which was working fine on android and IOS (there I tested it):
//////////////
//definition of the function HOLO
$scope.app.playModelStepPvz = function (pvz,sequence,modelName,step_number,play) {
//pvz file
//sequnece -sequnece name e.g. TestFigure1 - as shown in UI;
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', '');});
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', 'resources/Uploaded/'+pvz);});
},50);
$scope.setWidgetProp('spinner-1', 'visible', true);$scope.$applyAsync();
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},50);
$scope.setWidgetProp('spinner-1', 'visible', true);$scope.$applyAsync();
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}
, 500);
};
So for example you can use some property to save the current pvz (selected pvz) if you have many - then the current figure /sequence and the current step number and call the function:
$scope.app.playModelStepPvz = function (pvz,sequence,modelName,step_number,play) ;
//pvz file
//sequnece -sequnece name e.g. TestFigure1 - as shown in UI;
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
or you can omit the pvz argument and use it without the pvz something like:
...
$scope.app.playModelStep($scope.view.wdg['select-1']['value'],modelWdgName,data.stepNumber,true);
...
//where
//definition of the function
$scope.app.playModelStepPvz = function (pvz,sequence,modelName,step_number,play) {
//pvz file
//sequnece -sequnece name e.g. TestFigure1 - as shown in UI;
//modelName - model name e.g. model-1 widget
//step_number - set this number to current step
//play true/false execute play for the model
$scope.setWidgetProp('spinner-1', 'visible', true);$scope.$applyAsync();
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', '');});
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'src', 'resources/Uploaded/'+pvz);});
},50);
$scope.setWidgetProp('spinner-1', 'visible', true);$scope.$applyAsync();
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', '');});
},50);
$scope.setWidgetProp('spinner-1', 'visible', true);$scope.$applyAsync();
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'sequence', 'app/resources/Uploaded/l-Creo 3D - '+sequence +'.pvi');});
},50);
$timeout(function () {
$scope.$applyAsync(()=>{$scope.setWidgetProp(modelName, 'currentStep', parseInt(step_number));});
if(play) //check if play should be applyed
$timeout(function () {angular.element(document.getElementById(modelName)).scope().play(); }, 100)
//angular.element(document.getElementById(modelName)).scope().play(); }, 100);
}
, 500);
};
here I want to provide a demo project which is similar to this what you obviosly want to achieve but with some differences:
So here we can play for the selected figure (1 or 2) the specific step number by clicking of the step number field - item s of list widget:
Here also attached the demo project.
Hi,
It looks like the value of the model's sequence property is never set.
But if I understand you right, you only want to select a sequence from your list and play the sequence.
I think you can simplify this by doing the following:
Now you only need a function to show and hide the 3DImage if the Lubrication is the current sequence for example like this:
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.view.wdg["3DImage-1"].visible = true;
else
$scope.view.wdg["3DImage-1"].visible = false;
},50);
}
You can call this in the value changed event of the select widget.
Hi @sebben
Thanks for the exact understanding of my requirement. I tried , the animation is working fine but the 3D-image still appearing to all the sequences. Below screenshot for your reference. I used same script for this model.
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.view.wdg["3DImage-1"].visible = true;
else
$scope.view.wdg["3DImage-1"].visible = false;
},50);
}
add
$scope.$applyAsync();
after setting the property e.g.
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model-1']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.view.wdg["3DImage-1"].visible = true;
else
$scope.view.wdg["3DImage-1"].visible = false;
$scope.$applyAsync();
},50);
}
optionally you can use instead of
$scope.view.wdg["3DImage-1"].visible = false;
//or
$scope.view.wdg["3DImage-1"].visible = true;
you can use
$scope.setWidgetProp("3DImage-1", 'visible', false);
//or
$scope.setWidgetProp("3DImage-1", 'visible', true);
so the code could be something like this:
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model-1']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.setWidgetProp("3DImage-1", 'visible', true);
else
$scope.setWidgetProp("3DImage-1", 'visible', false);
$scope.$applyAsync();
},50);
another point is this - you need to ensure if:
if( $scope.view.wdg['model-1']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
is a correct check. For example you can check addtionally in the console window ( Shift+Strg +I)
console.warn($scope.view.wdg['model-1']['sequence'] )
to check what is the content of the property , so to be sure to what value you need to compare it
Hi,
I think your model has a different name.
Rename it in model or change the name in the if statement to model-1.
I hope that helps. If not, can you check the console for errors?
Hi Both, Successfully i got an output as per my expectation. Small update is required. The 3D label is appearing when model is loaded. which means, when sequence is empty, 3D image is appearing. how to avoid that?.
$scope.checkSequence = function(){
$timeout(function () {
if( $scope.view.wdg['model-1']['sequence'] == 'l-Creo 3D - Lubrication.pvi')
$scope.setWidgetProp("3DImage-1", 'visible', true);
else
$scope.setWidgetProp("3DImage-1", 'visible', false);
$scope.$applyAsync();
},50);
}
To avoid this problem : means to try to set propperty of model whidget which is not loaded yet you have e.g. 2 options:
- the one - to call you javaScript code when you use some delay msecs // mostly using the $timeout service
$timeout(function() { ...}, delay);
you will here the probelm that when the model is more complex - high model size or device is busy or server busy so the modelLoading could take more time - and your call will als fail to set property.
-other option is to use the modelLoad event where you can check if the model is loaded yet and then set the properties. In generally when a model is loaded all other 3d Widget are also completed:
///////////////////////
$rootScope.$on('modelLoaded', function() {
const args = Array.from(arguments);
console.log("args["+1+"]="+args[1]);
if(args[1]=="model-1") { //model-1 widget was loaded
//start here the new function for Sequnece Figure 1 for model-1 widget with step 3
$scope.sequenceList=$scope.getWidgetProp(args[1], 'sequenceList' )//args[1] contains the model which is used
$scope.setWidgetProp('select-1', 'list', $scope.sequenceList )
}
})