remote-calibrator 0.3.0-rc.3 → 0.5.0-beta.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. package/CHANGELOG.md +35 -3
  2. package/README.md +34 -49
  3. package/homepage/example.css +4 -3
  4. package/homepage/example.js +42 -22
  5. package/homepage/index.html +19 -4
  6. package/i18n/fetch-languages-sheets.js +11 -1
  7. package/lib/RemoteCalibrator.min.js +1 -1
  8. package/lib/RemoteCalibrator.min.js.LICENSE.txt +19 -2
  9. package/lib/RemoteCalibrator.min.js.map +1 -1
  10. package/netlify.toml +1 -1
  11. package/package.json +25 -24
  12. package/src/WebGazer4RC/package-lock.json +198 -143
  13. package/src/WebGazer4RC/package.json +2 -2
  14. package/src/WebGazer4RC/src/index.mjs +161 -52
  15. package/src/WebGazer4RC/test/webgazer_test.js +1 -1
  16. package/src/check/checkScreenSize.js +84 -0
  17. package/src/components/buttons.js +21 -4
  18. package/src/components/input.js +82 -0
  19. package/src/components/keyBinder.js +5 -6
  20. package/src/components/language.js +5 -0
  21. package/src/components/mediaPermission.js +21 -0
  22. package/src/components/onCanvas.js +2 -2
  23. package/src/components/sound.js +30 -2
  24. package/src/components/swalOptions.js +6 -3
  25. package/src/components/utils.js +27 -1
  26. package/src/components/video.js +9 -6
  27. package/src/const.js +15 -0
  28. package/src/core.js +103 -48
  29. package/src/css/buttons.scss +34 -7
  30. package/src/css/components.scss +57 -0
  31. package/src/css/distance.scss +71 -1
  32. package/src/css/gaze.css +9 -5
  33. package/src/css/main.css +22 -6
  34. package/src/css/panel.scss +33 -3
  35. package/src/css/screenSize.css +6 -5
  36. package/src/css/swal.css +1 -1
  37. package/src/css/video.scss +19 -0
  38. package/src/distance/distance.js +194 -41
  39. package/src/distance/distanceCheck.js +241 -0
  40. package/src/distance/distanceTrack.js +165 -68
  41. package/src/{interpupillaryDistance.js → distance/interPupillaryDistance.js} +27 -19
  42. package/src/gaze/gaze.js +4 -7
  43. package/src/gaze/gazeAccuracy.js +9 -4
  44. package/src/gaze/gazeCalibration.js +14 -4
  45. package/src/gaze/gazeTracker.js +40 -9
  46. package/src/i18n.js +1 -1
  47. package/src/index.js +7 -2
  48. package/src/media/two-side-arrow.svg +1 -0
  49. package/src/media/two-sided-horizontal.svg +1 -0
  50. package/src/media/two-sided-vertical.svg +3 -0
  51. package/src/panel.js +130 -65
  52. package/src/screenSize.js +38 -5
  53. package/webpack.config.js +7 -4
  54. package/media/measureDistance.png +0 -0
  55. package/media/panel.png +0 -0
  56. package/media/screenSize.png +0 -0
  57. package/media/trackGaze.png +0 -0
  58. package/src/displaySize.js +0 -28
@@ -1,6 +1,11 @@
1
1
  import RemoteCalibrator from '../core'
2
2
 
3
- import { constructInstructions, shuffle, blurAll } from '../components/utils'
3
+ import {
4
+ constructInstructions,
5
+ shuffle,
6
+ blurAll,
7
+ safeExecuteFunc,
8
+ } from '../components/utils'
4
9
  import { debug } from '../debug'
5
10
  import { bindKeys, unbindKeys } from '../components/keyBinder'
6
11
  import { phrases } from '../i18n'
@@ -60,8 +65,7 @@ RemoteCalibrator.prototype.calibrateGaze = function (options = {}, callback) {
60
65
  this._removeBackground() // Remove calibration background when the calibration finished
61
66
  unbindKeys(bindKeysFunction)
62
67
 
63
- // TODO Pass timestamp into callback
64
- if (callback && typeof callback === 'function') callback()
68
+ safeExecuteFunc(callback, { timestamp: new Date() })
65
69
  })
66
70
 
67
71
  const breakFunction = () => {
@@ -73,6 +77,11 @@ RemoteCalibrator.prototype.calibrateGaze = function (options = {}, callback) {
73
77
  originalStyles.video = false
74
78
  originalStyles.gazer = false
75
79
 
80
+ if (!this._trackingSetupFinishedStatus.gaze) {
81
+ this._trackingSetupFinishedStatus.gaze = true
82
+ this.endGaze()
83
+ }
84
+
76
85
  unbindKeys(bindKeysFunction)
77
86
  }
78
87
 
@@ -206,7 +215,8 @@ class GazeCalibrationDot {
206
215
  originalStyles.video = false
207
216
  originalStyles.gazer = false
208
217
 
209
- this.endCalibrationCallback()
218
+ safeExecuteFunc(this.endCalibrationCallback)
219
+ this.RC._trackingSetupFinishedStatus.gaze = true
210
220
  }
211
221
  }
212
222
 
@@ -1,7 +1,10 @@
1
1
  import webgazer from '../WebGazer4RC/src/index.mjs'
2
2
 
3
- import { toFixedNumber } from '../components/utils'
3
+ import { safeExecuteFunc, toFixedNumber } from '../components/utils'
4
4
  import { checkWebgazerReady } from '../components/video'
5
+ import Swal from 'sweetalert2'
6
+ import { swalInfoOptions } from '../components/swalOptions'
7
+ import { phrases } from '../i18n'
5
8
 
6
9
  /**
7
10
  * The gaze tracker object to wrap all gaze-related functions
@@ -32,7 +35,7 @@ export default class GazeTracker {
32
35
  begin({ pipWidthPx }, callback) {
33
36
  if (this.checkInitialized('gaze', true)) {
34
37
  if (!this._running.gaze) {
35
- this.webgazer.begin()
38
+ this.webgazer.begin(this.videoFailed.bind(this))
36
39
  this._running.gaze = true
37
40
  this._runningVideo = true
38
41
  }
@@ -51,7 +54,7 @@ export default class GazeTracker {
51
54
  // Begin video only
52
55
  if (this.checkInitialized('distance', true)) {
53
56
  if (!this._runningVideo) {
54
- this.webgazer.beginVideo()
57
+ this.webgazer.beginVideo(this.videoFailed.bind(this))
55
58
  this._runningVideo = true
56
59
  }
57
60
 
@@ -65,12 +68,24 @@ export default class GazeTracker {
65
68
  }
66
69
  }
67
70
 
71
+ videoFailed(videoInputs) {
72
+ Swal.fire({
73
+ ...swalInfoOptions(this.calibrator, { showIcon: true }),
74
+ icon: 'error',
75
+ iconColor: this.calibrator._CONST.COLOR.DARK_RED,
76
+ showConfirmButton: false,
77
+ html: videoInputs.length
78
+ ? phrases.RC_errorCameraUseDenied[this.calibrator.L]
79
+ : phrases.RC_errorNoCamera[this.calibrator.L],
80
+ })
81
+ }
82
+
68
83
  attachNewCallback(callback) {
69
84
  if (this.checkInitialized('gaze', true)) {
70
85
  this.webgazer.setGazeListener(d => {
71
86
  if (d) {
72
87
  const data = (this.calibrator.newGazePositionData = this.getData(d))
73
- if (callback) callback(data)
88
+ safeExecuteFunc(callback, data)
74
89
  }
75
90
  })
76
91
  }
@@ -80,7 +95,7 @@ export default class GazeTracker {
80
95
  let data = (this.calibrator.newGazePositionData = this.getData(
81
96
  await this.webgazer.getCurrentPrediction()
82
97
  ))
83
- if (callback) callback(data)
98
+ safeExecuteFunc(callback, data)
84
99
  return data
85
100
  }
86
101
 
@@ -95,10 +110,13 @@ GazeTracker.prototype._init = function (
95
110
  ) {
96
111
  if (!this.checkInitialized(task)) {
97
112
  if (task === 'gaze') {
98
- this.webgazer.clearData()
99
- this.webgazer.saveDataAcrossSessions(false)
113
+ // TODO Manually clear data
114
+ // this.webgazer.clearData()
115
+ // this.webgazer.saveDataAcrossSessions(false)
100
116
  this.webgazer.params.greedyLearner = greedyLearner
101
117
  this.webgazer.params.framerate = framerate
118
+ this.webgazer.params.getLatestVideoFrameTimestamp =
119
+ this._getLatestVideoTimestamp.bind(this)
102
120
  this.showGazer(showGazer)
103
121
  }
104
122
 
@@ -126,12 +144,15 @@ GazeTracker.prototype.checkInitialized = function (task, warning = false) {
126
144
  }
127
145
 
128
146
  GazeTracker.prototype.getData = function (d) {
147
+ let t = new Date()
129
148
  return {
130
149
  value: {
131
150
  x: toFixedNumber(d.x, this._toFixedN),
132
151
  y: toFixedNumber(d.y, this._toFixedN),
152
+ latencyMs:
153
+ t.getTime() - this.calibrator._tackingVideoFrameTimestamps.gaze, // latency
133
154
  },
134
- timestamp: new Date(),
155
+ timestamp: t,
135
156
  }
136
157
  }
137
158
 
@@ -155,6 +176,8 @@ GazeTracker.prototype.end = function (type, endAll = false) {
155
176
  this._endGaze()
156
177
  if (endEverything && this.checkInitialized('distance'))
157
178
  this.calibrator.endDistance(false, false)
179
+
180
+ this.calibrator._tackingVideoFrameTimestamps.gaze = 0
158
181
  } else {
159
182
  // Distance
160
183
  this.defaultDistanceTrackCallback = null
@@ -187,8 +210,16 @@ GazeTracker.prototype._endGaze = function () {
187
210
 
188
211
  this.webgazer.params.greedyLearner = false
189
212
  this.webgazer.params.framerate = 60
213
+
214
+ this.webgazer.params.getLatestVideoFrameTimestamp = () => {}
190
215
  }
191
216
 
217
+ GazeTracker.prototype._getLatestVideoTimestamp = function (t) {
218
+ this.calibrator._tackingVideoFrameTimestamps.gaze = t.getTime()
219
+ }
220
+
221
+ /* -------------------------------------------------------------------------- */
222
+
192
223
  GazeTracker.prototype.startStoringPoints = function () {
193
224
  this.webgazer.params.storingPoints = true
194
225
  }
@@ -218,7 +249,7 @@ GazeTracker.prototype.showGazer = function (show) {
218
249
  }
219
250
 
220
251
  GazeTracker.prototype.showVideo = function (show) {
221
- this.webgazer.showVideo(show)
252
+ this.webgazer.showVideo(show, this.calibrator._params.videoOpacity)
222
253
  }
223
254
 
224
255
  GazeTracker.prototype.showFaceOverlay = function (show) {