jsPsych.extensions['webgazer'] = (function () { var extension = {}; // private state for the extension // extension authors can define public functions to interact // with the state. recommend not exposing state directly // so that state manipulations are checked. var state = {}; // required, will be called at jsPsych.init // should return a Promise extension.initialize = function (params) { return new Promise(function(resolve, reject){ if (typeof params.webgazer === 'undefined') { if (window.webgazer) { state.webgazer = window.webgazer; } else { reject(new Error('webgazer extension failed to initialize. webgazer.js not loaded. Load webgazer.js before calling jsPsych.init()')); } } else { state.webgazer = params.webgazer; } if (typeof params.round_predictions === 'undefined'){ state.round_predictions = true; } else { state.round_predictions = params.round_predictions; } // sets up event handler for webgazer data state.webgazer.setGazeListener(handleGazeDataUpdate); // starts webgazer, and once it initializes we stop mouseCalibration and // pause webgazer data. state.webgazer.begin().then(function () { extension.stopMouseCalibration(); extension.pause(); resolve(); }) // hide video by default extension.hideVideo(); // hide predictions by default extension.hidePredictions(); }) } // required, will be called when the trial starts (before trial loads) extension.on_start = function (params) { state.currentTrialData = []; state.currentTrialTargets = []; } // required will be called when the trial loads extension.on_load = function (params) { // set current trial start time state.currentTrialStart = performance.now(); // resume data collection state.webgazer.resume(); // set internal flag state.activeTrial = true; // record bounding box of any elements in params.targets if(typeof params !== 'undefined'){ if(typeof params.targets !== 'undefined'){ for(var i=0; i