Sketchfab Forum

sketchfabAPIUtility.js - how can I load multiple models on one page?


(Empe2301) #1

Hi,

I'm using sketchfabAPIUtility.js.
Now I want load 6 models on one page.

My code looks like:

    $scope.bttfModels = [ 
        {
        	urlid: "",
        	id: 'api-frame'
        }
        {
        	urlid: "f",
        	id: 'api-frame1'
        },
        {
        	urlid: "",
        	id: 'api-frame2'
        },
        {
        	urlid: "",
        	id: 'api-frame3'
        },
        {
        	urlid: "",
        	id: 'api-frame4'
        },
        {
        	urlid: "f",
        	id: 'api-frame5'
        }
    ]

    angular.forEach($scope.bttfModels, function(item) {
    	$scope.test1 = item.urlid;
    	$scope.test2 = item.id

    	sketchfabAPIUtility = new SketchfabAPIUtility($scope.test1, document.getElementById($scope.test2), onSketchfabUtilityReady, {camera: 0});
    
    });


    var cameraPos = $('#camera'),
        targetPos = $('#target'),
        urlid,
        version = '1.0.0',
        iframe = $('#api-frame')[0],
        api

        pollCamera = function() {
            setInterval(function() {
                api.getCameraLookAt(function(err, camera) {

                  var currentPos = camera.position;
                  var currentTarg = camera.target;
                  posx = currentPos[0];
                  posy = currentPos[1];
                  posz = currentPos[2];

                  tarx = currentTarg[0];
                  tary = currentTarg[1];
                  tarz = currentTarg[2];


                  if (posz < -0.5) {

                      api.lookat(
                          [posx, posy, -0.5], [tarx, tary, tarz],
                          0
                        );
                  } else if (posz >= -0.5 && ((posx * posx + posy * posy + posz * posz) >= 100)) {
                        api.lookat(
                          [posx / 2, posy / 2, posz / 2], [tarx / 2, tary / 2, tarz / 2],
                          0
     
                       );
                  } else if (posz >= -0.5 && ((posx * posx + posy * posy + posz * posz) < 10)) {
                        api.lookat(

                          [posx * 1.01, posy * 1.01, posz * 1.01], [tarx, tary, tarz],
                          0
                       );

                  }
              });
          }, 0);
      };

  function onSketchfabUtilityReady() {
    
      api = sketchfabAPIUtility.api
      pollCamera();

}

and HTML:

<div class="bttf-area">

    <iframe src="" id="api-frame" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
    <iframe src="" id="api-frame1" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
    <iframe src="" id="api-frame2" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
    <iframe src="" id="api-frame3" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
    <iframe src="" id="api-frame4" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
    <iframe src="" id="api-frame5" allowfullscreen mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

</div>

Objects are loaded correctly, but I can't use the rest of the functionality (the script for limiting camera movement) and I'm getting a console error:

"Uncaught DOMException: Failed to execute 'postMessage' on 'Window': An object could not be cloned.(…)n @ embed-7703567….js:1
embed-7703567….js:1 {"0":{"isTrusted":true}}"

so I think that the problem is that I use sketchfabAPIUtility several times, because when I have only one model, everything looks good. But how else can I load several models on one page?


#2

For starters, you have some bad syntax you need to fix - missing semicolons, commas, etc. I recommend http://jshint.com/

@shaderbytes would know best, as I don't use his utility, but I suspect you need to create a different api object for each frame. It looks like you either defined the same object 6 times or the scope is wrong.

For example, the compare too models sample has 2 api objects:
https://sketchfab.com/developers/viewer/compare


(Shaderbytes) #3

As James hints you need to create an instance for each viewer you embed , here is a very quick and dirty example I whipped up :

http://www.shaderbytes.co.za/sketchfab/development/api/examples/example_7.html


(Empe2301) #4

Thanks for the answers.
I was inspired by the code @shaderbytes, but I still have a problem with api object. I don't know how can I use poolCamera function. Below is my code, objects are load properly but if I want to call function poolCamera(), I'm getting an error that: "Uncaught TypeError: Cannot read property 'getCameraLookAt' of undefined(…)"

  var api;
  var sketchfabAPIUtilityCollection = [];
  var sketchfabUrlidCollection = ["6c45630c96d54563919de274ff169ac5", "fd8617118f554a559406552e4cb6ce3d", "ae912a7bf7394b499b361904130d3f33", "ae912a7bf7394b499b361904130d3f33", "d2170f77d3dc436e8c031c7b3ce70a7a", "2b80a6f23fb44973a2258d407548b52f" ]
    for (var i = 0; i < sketchfabUrlidCollection.length; i++) {
        var id1 = "api-frame-" + (i + 1);
        var urlid = sketchfabUrlidCollection[i];

        var ob = sketchfabAPIUtilityCollection[i] = {};
        ob.onSketchfabUtilityReady = function (api) {  
         	pollCamera()
       }
       ob.sketchfabAPIUtility = new SketchfabAPIUtility(urlid, document.getElementById(id1), ob.onSketchfabUtilityReady,{camera: 0});
    }


        pollCamera = function() {
            setInterval(function() {
             
                api.getCameraLookAt(function(err, camera) {

                  var currentPos = camera.position;
                  var currentTarg = camera.target;
                  posx = currentPos[0];
                  posy = currentPos[1];
                  posz = currentPos[2];

                  tarx = currentTarg[0];
                  tary = currentTarg[1];
                  tarz = currentTarg[2];


                  if (posz < -0.5) {

                      api_1.lookat(
                          [posx, posy, -0.5], [tarx, tary, tarz],
                          0
                        );
                  } else if (posz >= -0.5 && ((posx * posx + posy * posy + posz * posz) >= 100)) {
                        api_1.lookat(
                          [posx / 2, posy / 2, posz / 2], [tarx / 2, tary / 2, tarz / 2],
                          0
     
                       );
                  } else if (posz >= -0.5 && ((posx * posx + posy * posy + posz * posz) < 10)) {
                       api_1.lookat(

                          [posx * 1.01, posy * 1.01, posz * 1.01], [tarx, tary, tarz],
                          0
                       );

                  }
              });
          }, 0);
      };

(Shaderbytes) #5

You dont seem to have a very good understanding of variable declarations , function arguments and scope. You really should go read up on those principles to lay a good foundation understanding of Javascript.

There is no argument passed into the callback from my Utility, yet you declared an argument : "api" you also have the same variable outside this function scope and at no point are you giving it a value. Even if you did you would be overwriting the previous value , one variable is not enough.

Go back to my code and notice I was logging to the console in the viewer ready callback, the value of "this". Each instance of the utility created calls its own callback and the value of "this" points to itself. You can use "this.api" to reference the api object for each instance. But understand you can only use in like that within that code block. When you want to use it in another code block pass it as an argument eg :

 ob.onSketchfabUtilityReady = function () {  
         	pollCamera(this.api)
       }