### Run Example HTML Files as a Server
Source: https://github.com/brownhci/webgazer/blob/master/README.md
Steps to run the example HTML files (`calibration.html`, `collision.html`) locally. This involves cloning the repository, installing Node.js, navigating to the `www` directory, installing its dependencies, and starting the server.
```bash
# Clone the repository and download NodeJS using the steps listed above
# Move into the www directory and download the additional dependencies
cd www
npm install
# Run the webpage index.html as a server
npm run serve
```
--------------------------------
### Initialize and Start Webgazer
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
This snippet demonstrates how to initialize the webgazer library and start the eye-tracking process. It typically involves calling a setup function and then initiating the prediction loop. Ensure the necessary HTML elements for tracking are present.
```javascript
webgazer.setRegression('load');
webgazer.showPredictionPoints(true); // (Optional) show points for debugging
webgazer.begin();
// Store the prediction
var prediction = webgazer.predict();
// If you want to draw a circle on the screen
// when you get a prediction
webgazer.setCameraProperties(true);
webgazer.applyKalmanFilter(true);
// Example of how to use prediction
function drawEyeBox(e) {
var face = document.getElementById('face');
if (prediction) {
var x = prediction.x;
var y = prediction.y;
face.style.left = x + 'px';
face.style.top = y + 'px';
}
}
// Listen for events
webgazer.on('predict', drawEyeBox);
```
--------------------------------
### Initialize and Start Gaze Tracking (JavaScript)
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Initializes the Webgazer library and starts the gaze tracking process. This is a fundamental step before any tracking data can be obtained. It typically involves calling a setup function.
```javascript
webgazer.begin();
```
--------------------------------
### Initialize webgazer.js and Start Tracking
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
This snippet shows the basic initialization of webgazer.js and starts the eye tracking process. It assumes webgazer has been included in the project and is ready to be used. The `webgazer.begin()` function initiates the tracking.
```javascript
webgazer.begin();
```
--------------------------------
### Install WebGazer.js via npm
Source: https://context7.com/brownhci/webgazer/llms.txt
Install the WebGazer.js package using npm. Alternatively, clone the repository and build from source.
```bash
npm install webgazer
```
```bash
git clone https://github.com/brownhci/WebGazer.git
cd WebGazer
npm install
npm run build # outputs dist/webgazer.js
```
--------------------------------
### Build WebGazer.js from Source
Source: https://github.com/brownhci/webgazer/blob/master/README.md
Instructions for cloning the repository, installing dependencies, and building the project from source. Requires Node.js.
```bash
# Ensure Node is downloaded: https://nodejs.org/en/download/ (tested on v16 and v18)
git clone https://github.com/brownhci/WebGazer.git
cd WebGazer
#install the dependencies
npm install
#build the project
npm run build
```
--------------------------------
### Initialize and start webgazer
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
This snippet shows how to initialize the webgazer library and start the gaze tracking process. It includes basic error handling for cases where the webcam is not accessible.
```javascript
webgazer.setCameraResolution(640, 480); //width and height of the gaze path
webgazer.begin();
var prediction = document.getElementById('webgazer-nlp-error');
prediction.innerHTML = ''; // clear all previous labels
webgazer.showVideo(true); // Show the video stream
webgazer.showFaceOverlay(true); // Show the face overlay
webgazer.showEyeOverlay(true); // Show the eye overlay
webgazer.showGazeDot(true); // Show the gaze dot
webgazer.setGazeDotSize(20, 20); // Set the size of the gaze dot
webgazer.setGazeDotColor("red"); // Set the color of the gaze dot
```
--------------------------------
### Initialize Webgazer and Event Listeners (JavaScript)
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
This snippet demonstrates the initialization of Webgazer and setting up event listeners for gaze data. It covers the basic setup required to start tracking user gaze.
```JavaScript
webgazer.setGazeListener(function(data, timestamp) {
// Logic to handle gaze data and timestamp
if (data == null) {
// Handle cases where gaze data is not available
return;
}
var xpred = data.x;
var ypred = data.y;
// Further processing of xpred and ypred
// console.log("Timestamp: " + timestamp + " X: " + xpred + " Y: " + ypred);
}).begin();
```
--------------------------------
### RequireJS Optimizer Configuration
Source: https://github.com/brownhci/webgazer/blob/master/www/css/highlight/README.md
Example command for using the RequireJS optimizer to build highlight.js, specifying module name and paths.
```bash
r.js -o name=hljs paths.hljs=/path/to/highlight out=highlight.js
```
--------------------------------
### Start WebGazer eye tracking
Source: https://context7.com/brownhci/webgazer/llms.txt
Call `webgazer.begin()` to request webcam access, initialize UI elements, load calibration data, and start the prediction loop. This method must be called before any predictions are available and works only over HTTPS or localhost. It returns a Promise that resolves to the `webgazer` object.
```javascript
webgazer
.setGazeListener(function(data, elapsedTime) {
if (data === null) return; // no face detected
console.log('Gaze at', data.x, data.y, 'after', elapsedTime, 'ms');
// data.x — predicted x coordinate in viewport pixels
// data.y — predicted y coordinate in viewport pixels
})
.begin(function onFail() {
console.error('Could not access webcam.');
})
.then(function() {
console.log('WebGazer started successfully');
})
.catch(function(err) {
console.error('begin() rejected:', err);
});
```
--------------------------------
### WebGazer Initialization and Control
Source: https://github.com/brownhci/webgazer/wiki/Top-Level-API
Functions to start, pause, resume, and end WebGazer's operation.
```APIDOC
## webgazer.begin()
### Description
Begins collecting click data and activates the camera. Should be called as soon as possible to improve accuracy. Attaches window click listener, starts the clock, and appends necessary video and canvas elements to the body.
### Method
webgazer.begin()
### Returns
- webgazer object
```
```APIDOC
## webgazer.pause()
### Description
Stops all WebGazer data collection and predictions.
### Method
webgazer.pause()
### Returns
- webgazer object
```
```APIDOC
## webgazer.resume()
### Description
Resumes all WebGazer data collection and predictions after a pause.
### Method
webgazer.resume()
### Returns
- webgazer object
```
```APIDOC
## webgazer.end()
### Description
Stops all WebGazer data collection and predictions and releases all memory. It also saves global model data so that returning users will have a pre-loaded model. Accuracy may suffer if `begin()` is called afterward; consider using `pause()` and `resume()` instead.
### Method
webgazer.end()
### Returns
- webgazer object
```
--------------------------------
### Initialize webgazer
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Initializes the webgazer library. This is the first step to start eye tracking.
```javascript
function webgazerInit() {
webgazer.setRegression('weightedKnn');
webgazer.begin();
}
webgazerInit();
```
--------------------------------
### Global Event Listener Setup
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Sets up global event listeners for 'DOMContentLoaded' and 'load' events on the window and document. It also exposes various Google-related functions globally.
```javascript
zn(window.document,"DOMContentLoaded");
zn(window,"load");
_.x("gbar.ldb",_.v(_.Ng.w,_.Ng,_.Rb));
_.x("gbar.mls",function(){});
_.Fa("eq",new Dn(_.Dl()));
_.Fa("gs",(new Fn).init(_.ll(),_.I(_.M(),_.un,5)||new _.un,_.I(_.M(),_.xn,6)||new _.xn));
(function(){
for(var a=function(a){return function(){_.Gl(44,{n:a})}},c=0;c<_.Ia.length;c++){
var d="gbar."+"".Ia[c];
_.x(d,a(d))
}
var e=_.Ba.U();
_.Ca(e,"api").Sa();
Bn(_.Ca(e,"m"),function(){
_.Ca(e,"api").Sa()
})
})();
```
--------------------------------
### Start WebGazer and Set Gaze Listener
Source: https://github.com/brownhci/webgazer/wiki/Tutorial
Begin WebGazer data collection and set up a listener to receive gaze predictions. The listener callback provides gaze data and elapsed time.
```javascript
webgazer.setGazeListener(function(data, elapsedTime) {
var xprediction = data.x;
var yprediction = data.y;
}).begin();
```
--------------------------------
### User Interaction Log - Mouse Movement
Source: https://github.com/brownhci/webgazer/blob/master/www/data/index.html
User interactions during tasks are captured in JSON format. This example shows a mousemove event, detailing coordinates, window dimensions, and timing information.
```json
{"clientX": 724, "clientY": 440, "windowY": 23, "windowX": 0, "windowInnerWidth": 1440, "time": 1273.9850000000001, "sessionId": "1491423217564_2_/study/dot_test_instructions", "webpage": "/study/dot_test_instructions.htm", "epoch": 1491423558580, "windowOuterWidth": 1440, "windowInnerHeight": 679, "pageX": 724, "pageY": 440, "windowOuterHeight": 797, "screenY": 537, "screenX": 724, "type": "mousemove"}
```
--------------------------------
### Google API Loading and Initialization in JavaScript
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Initializes and loads Google APIs, configuring necessary parameters and handling callbacks. This snippet demonstrates how to set up the gapi object and manage its loading process.
```javascript
var Fn=function(){_.z.call(this);this.o=\[\];this.b=\[\]};_.y(Fn,_.z);Fn.prototype.w=function(a,c){this.o.push({xc:a,options:c})};Fn.prototype.init=function(a,c,d){window.gapi={};var e=window.___jsl={};e.h=_.K(_.F(a,1));e.ms=_.K(_.F(a,2));e.m=_.K(_.F(a,3));e.l=\[\];\_.F(c,1)&&(a=_.F(c,3))&&this.b.push(a);\_.F(d,1)&&(d=_.F(d,2))&&this.b.push(d);\_.x("gapi.load",(0,\_.v)(this.w,this));return this}
```
--------------------------------
### Get Prediction Threshold
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
This example shows how to retrieve the currently set prediction threshold for webgazer. This allows you to check the confidence level filtering currently applied to gaze predictions.
```javascript
const threshold = webgazer.getPredictionThreshold();
console.log(threshold); // e.g., 0.9
```
--------------------------------
### RPC Initialization and Setup
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Initializes and sets up Google API RPC (Remote Procedure Call) functionality. This involves loading necessary RPC scripts and configuring callback functions for event handling.
```javascript
_.Xl(_.Jh(_.Yb("//www-onepick-opensocial.googleusercontent.com/gadgets/js/rpc.js?c=1&container=onepick")));
_.Xl(_.Jh(_.Yb("//apis.google.com/js/rpc.js")));
```
--------------------------------
### Utility: Get Element Position
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Gets the top-left position of a DOM element, returning it as a `wh` object.
```JavaScript
_.fi=function(a){a=Hh(a);return new _.wh(a.left,a.top)};
```
--------------------------------
### Utility: Get Element Style Pixel Value
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Gets the pixel value of a specified CSS property for a given element, handling browser compatibility for `currentStyle` and `runtimeStyle`.
```JavaScript
$h=function(a,c){return(c=a.currentStyle?a.currentStyle[c]:null)?_.Rh(a,c):0};
```
--------------------------------
### Configure webgazer.params before begin()
Source: https://context7.com/brownhci/webgazer/llms.txt
Modify global configuration parameters directly before initializing Webgazer. Adjust settings like training sample frequency, video preview dimensions, and eye tracking mode.
```javascript
// Example: tweak params before begin()
webgazer.params.moveTickSize = 100; // ms between mousemove training samples (default 50)
webgazer.params.videoViewerWidth = 160; // preview width in px (default 320)
webgazer.params.videoViewerHeight = 120; // preview height in px (default 240)
webgazer.params.faceFeedbackBoxRatio = 0.5; // size of face-in-box guide relative to video (default 0.66)
webgazer.params.mirrorVideo = false; // mirror camera preview (default true)
webgazer.params.storingPoints = true; // record last-50 gaze points for accuracy calcs (default false)
webgazer.params.trackEye = 'left'; // 'left' | 'right' | 'both' (default 'both')
webgazer.params.faceMeshSolutionPath = '/static/mediapipe/face_mesh'; // path to WASM assets
webgazer.begin();
// Read available event types
var types = webgazer.params.getEventTypes(); // ['click', 'move']
```
--------------------------------
### getPositions
Source: https://github.com/brownhci/webgazer/wiki/Tracker-API
Gets the current gaze positions. This method returns the coordinates where the user is looking on the screen.
```APIDOC
## getPositions()
### Description
Gets the current gaze positions.
### Returns
- An array of gaze position objects, each containing x and y coordinates.
```
--------------------------------
### webgazer.begin([onFail])
Source: https://context7.com/brownhci/webgazer/llms.txt
Starts the eye tracking process. It requests webcam access, initializes necessary DOM elements, loads calibration data, and begins the prediction loop. This function must be called before any predictions can be made and works only over HTTPS or localhost. It returns a Promise that resolves to the webgazer object.
```APIDOC
## webgazer.begin([onFail]) — Start eye tracking
Requests webcam access, initializes the DOM elements (video preview, face overlay, feedback box, gaze dot), loads any previously stored calibration data, and starts the prediction loop. Must be called before any predictions are available. Works only over HTTPS or `localhost`. Returns a Promise that resolves to the `webgazer` object.
```js
webgazer
.setGazeListener(function(data, elapsedTime) {
if (data === null) return; // no face detected
console.log('Gaze at', data.x, data.y, 'after', elapsedTime, 'ms');
// data.x — predicted x coordinate in viewport pixels
// data.y — predicted y coordinate in viewport pixels
})
.begin(function onFail() {
console.error('Could not access webcam.');
})
.then(function() {
console.log('WebGazer started successfully');
})
.catch(function(err) {
console.error('begin() rejected:', err);
});
```
```
--------------------------------
### wpc_Inst Initialization
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/bing.htm
Initializes the wpc_Inst with scheduler, context, and a target identifier. This sets up event listeners for image loading and completion.
```javascript
function wpc_Inst(n,t,i){var r=sj_evt.bind,u=0,f=0;r&&n&&t&&i&&(r("RMS.ImgAOLInit",function(){n.register(i)},1),r("RMS.ImgAOLCompleted",function(){n.schedule({task:function(){n.recordTimings(i,u,f);n.complete(i)}})},1),r("RMS.ImgAOLLoaded",function(n){var i,e,r;n.length<2||(i=n[1],i&&i.state==="success")&&(e=i.image,e&&sj_we(e,t))&&(r=i.timeStamp,u===0&&(u=r),r>f&&(f=r))},1))};new wpc_Inst(_w.sched,_ge("b_context"),"TP")
```
--------------------------------
### WebGazer Core Functionality
Source: https://github.com/brownhci/webgazer/wiki/Top-Level-API
Functions for processing video frames, getting predictions, and recording user input.
```APIDOC
## webgazer.getPupilFeatures(video, canvas, width, height)
### Description
Gets the pupil features by following the pipeline which threads an eyes object through each call: curTracker gets eye patches -> blink detector -> pupil detection. NOTE: This function is not currently being used.
### Method
webgazer.getPupilFeatures(video, canvas, width, height)
### Parameters
#### Path Parameters
- **canvas** (object) - Required - The canvas element onto which the video will be drawn.
- **width** (number) - Required - The width of the canvas.
- **height** (number) - Required - The height of the canvas.
```
```APIDOC
## webgazer.paintCurrentFrame(canvas, width, height)
### Description
Gets the most current frame of video and paints it to a resized version of the canvas with the specified width and height.
### Method
webgazer.paintCurrentFrame(canvas, width, height)
### Parameters
#### Path Parameters
- **canvas** (object) - Required - The canvas element to paint the video frame onto.
- **width** (number) - Required - The desired width for the canvas.
- **height** (number) - Required - The desired height for the canvas.
```
```APIDOC
## webgazer.getPrediction(regModelIndex)
### Description
Paints the video to a canvas and runs the prediction pipeline to get a prediction.
### Method
webgazer.getPrediction(regModelIndex)
### Parameters
#### Path Parameters
- **regModelIndex** (Number|undefined) - Optional - The prediction index we're looking for.
```
```APIDOC
## webgazer.recordScreenPosition(x, y, [eventType])
### Description
Records the screen position of a user's interaction.
### Method
webgazer.recordScreenPosition(x, y, eventType)
### Parameters
#### Path Parameters
- **x** (String) - Required - Position on screen in the x-axis.
- **y** (String) - Required - Position on screen in the y-axis.
- **eventType** (String) - Optional - 'click' or 'move', defaults to 'click'.
```
--------------------------------
### Use a Pre-recorded Video for Testing
Source: https://context7.com/brownhci/webgazer/llms.txt
Allows replacing the live webcam stream with a static video file for testing purposes. Must be called before `begin()`.
```APIDOC
## `webgazer.setStaticVideo(videoLoc)` — Use a pre-recorded video for testing
Replaces the live webcam stream with a static video file. Must be called before `begin()`. Useful for automated testing or demos without a camera.
```js
webgazer
.setStaticVideo('test-recording.mp4')
.setGazeListener(function(data) {
if (data) console.log(data.x, data.y);
})
.begin();
```
```
--------------------------------
### Google Search Event Handling Setup
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Sets up event listeners and handlers for user interactions within the Google Search interface. This includes managing mouse events and keyboard input.
```javascript
'use strict';var k=this,l=Date.now||function(){return+new Date};var u=function(a,d){if(null===d)return!1;if("contains"in a&&1==d.nodeType)return a.contains(d);if("compareDocumentPosition"in a)return a==d||!!(a.compareDocumentPosition(d)&16);for(;d&&a!=d;)d=d.parentNode;return d==a};var w={};var x=function(a,d){return function(b){b||(b=window.event);return d.call(a,b)}},B=function(a){a=a.target||a.srcElement;!a.getAttribute&&a.parentNode&&(a=a.parentNode);return a},C="undefined"!=typeof navigator&&/Macintosh/.test(navigator.userAgent),D="undefined"!=typeof navigator&&!/Opera/.test(navigator.userAgent)&&/WebKit/.test(navigator.userAgent),E={A:1,INPUT:1,TEXTAREA:1,SELECT:1,BUTTON:1},F=function(){this._mouseEventsPrevented=!0},G={A:13,BUTTON:0,CHECKBOX:32,COMBOBOX:13,GRIDCELL:13,LINK:13,LISTBOX:13,MENU:0,MENUBAR:0,MENUITEM:0,MENUITEMCHECKBOX:0,MENUITEMRADIO:0,OPTION:0,RADIO:32,RADIOGROUP:32,RESET:0,SUBMIT:0,TAB:0,TREE:13,TREEITEM:13},H=function(a){return(a.getAttribute("type")||a.tagName).toUpperCase()in aa},I=function(a){return(a.getAttribute("type")||a.tagName).toUpperCase()in ba},aa={CHECKBOX:!0,OPTION:!0,RADIO:!0},ba={COLOR:!0,DATE:!0,DATETIME:!0,"DATETIME-LOCAL":!0,EMAIL:!0,MONTH:!0,NUMBER:!0,PASSWORD:!0,RANGE:!0,SEARCH:!0,TEL:!0,TEXT:!0,TEXTAREA:!0,TIME:!0,URL:!0,WEEK:!0},ca={A:!0,AREA:!0,BUTTON:!0,DIALOG:!0,IMG:!0,INPUT:!0,LINK:!0,MENU:!0,OPTGROUP:!0,OPTION:!0,PROGRESS:!0,SELECT:!0,TEXTAREA:!0};var J=function(){this.v=this.o=null},L=function(a,d){var b=K;b.o=a;b.v=d;return b};J.prototype.s=function(){var a=this.o;this.o&&this.o!=this.v?this.o=this.o._owner||this.o.parentNode:this.o=null;return a};var M=function(){this.w=\[\];this.o=0;this.v=null;this.H=!1};M.prototype.s=function(){if(this.H)return K.s();if(this.o!=this.w.length){var a=this.w\[this.o\];this.o++;a!=this.v&&a&&a._owner&&(this.H=!0,L(a._owner,this.v));return a}return null};var K=new J,O=new M;var Q=function(){this.S=\[\];this.o=\[\];this.s=\[\];this.H={};this.v=null;this.w=\[\];P(this,"\_custom")},da="undefined"!=typeof navigator&&/iPhone|iPad|iPod/.test(navigator.userAgent),R=St
```
--------------------------------
### Animation Frame Scheduler
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/google.htm
Manages scheduled animations using requestAnimationFrame. It handles starting, stopping, and ticking animations.
```javascript
var ri,ti;
_.qi={};
ri=null;
_.si=function(a){a=
_.oi(a);delete
_.qi
[a];
_.ni(
_.qi)&&ri&&ri.stop()};
_.ui=function(){ri||
_.di(function(){
ti()},20));var a=ri;0!=a.ja||
a.start()};
ti=function(){
var a=(0,
_.w)();
_.Hc(
_.qi,function(c){
_.vi(c,a)});
_.ni(
_.qi)||
_.ui()};
_.vi=function(a,c){c d ? "" : 0 == d ? ";expires=" + (new Date(1970, 1, 1)).toUTCString() : ";expires=" + (new Date((0, _.w)() + 1E3 * d)).toUTCString();
this.b.cookie = a + "=" + c + f + e + d + g
};
_.k.get = function(a, c) {
for (var d = a + "=", e = (this.b.cookie || "").split(Te), f = 0, g; g = e[f]; f++) {
if (0 == g.lastIndexOf(d, 0)) return g.substr(d.length);
if (g == a) return ""
}
return c
};
_.k.remove = function(a, c, d) {
var e = _.n(this.get(a));
this.set(a, "", 0, c, d);
return e
};
_.k.Na = function() {
return Ue(this).keys
};
_.k.Ja = function() {
return Ue(this).values
};
_.k.fc = function() {
return !this.b.cookie
};
_.k.clear = function() {
for (var a = Ue(this).keys, c = a.length - 1; 0 <= c; c--) this.remove(a[c])
};
Ue = function(a) {
a = (a.b.cookie || "").split(Te);
for (var c = [], d = [], e, f, g = 0; f = a[g]; g++) e = f.indexOf("="), -1 == e ? (c.push(""), d.push(f)) : (c.push(f.substring(0, e)), d.push(f.substring(e + 1)));
return {keys: c, values: d}
};
_.Ve = new _.Se("undefined" == typeof window.document ? null : window.document);
_.Ve.o = 3950;
```
--------------------------------
### Initialize and Configure WebGazer
Source: https://github.com/brownhci/webgazer/blob/master/www/search/examples/face_detection.htm
Sets up WebGazer with regression and tracker, and defines a listener for gaze data. It also configures the video feed and overlay canvas for visualization.
```javascript
window.onload = function() {
window.localStorage.clear();
webgazer.setRegression('ridge') /* currently must set regression and tracker */
.setTracker('clmtrackr')
.setGazeListener(function(data, clock) {
// console.log(data);
/* data is an object containing an x and y key which are the x and y prediction coordinates (no bounds limiting) */
// console.log(clock);
/* elapsed time in milliseconds since webgazer.begin() was called */
})
.begin()
.showPredictionPoints(false); /* shows a square every 100 milliseconds where current prediction is */
var width = 320;
var height = 240;
var topDist = '0px';
var leftDist = '0px';
var setup = function() {
var video = document.getElementById('webgazerVideoFeed');
video.style.display = 'block';
video.style.position = 'absolute';
video.style.top = topDist;
video.style.left = leftDist;
video.width = width;
video.height = height;
video.style.margin = '0px';
webgazer.params.imgWidth = width;
webgazer.params.imgHeight = height;
var overlay = document.createElement('canvas');
overlay.id = 'overlay';
overlay.style.position = 'absolute';
overlay.width = width;
overlay.height = height;
overlay.style.top = topDist;
overlay.style.left = leftDist;
overlay.style.margin = '0px';
document.body.appendChild(overlay);
var cl = webgazer.getTracker().clm;
function drawLoop() {
requestAnimFrame(drawLoop);
overlay.getContext('2d').clearRect(0,0,width,height);
if (cl.getCurrentPosition()) {
cl.draw(overlay);
}
}
drawLoop();
};
function checkIfReady() {
if (webgazer.isReady()) {
setup();
} else {
setTimeout(checkIfReady, 100);
}
}
setTimeout(checkIfReady,100);
window.onbeforeunload = function() {
webgazer.end();
};
};
```