remote-calibrator 0.3.0-beta.2 → 0.3.0-beta.7
Sign up to get free protection for your applications and to get access to all the features.
- package/.eslintrc.js +1 -1
- package/.husky/pre-commit +1 -1
- package/.prettierignore +4 -0
- package/CHANGELOG.md +24 -0
- package/README.md +28 -9
- package/homepage/example.css +4 -0
- package/homepage/index.html +26 -0
- package/i18n/.eslintrc.js +12 -0
- package/i18n/fetch-languages-sheets.js +71 -0
- package/lib/RemoteCalibrator.min.js +1 -1
- package/lib/RemoteCalibrator.min.js.LICENSE.txt +1 -1
- package/lib/RemoteCalibrator.min.js.map +1 -1
- package/package.json +14 -10
- package/src/components/buttons.js +4 -3
- package/src/components/language.js +31 -0
- package/src/components/swalOptions.js +4 -2
- package/src/{helpers.js → components/utils.js} +8 -2
- package/src/const.js +4 -4
- package/src/core.js +104 -2
- package/src/css/buttons.scss +18 -2
- package/src/css/distance.scss +12 -7
- package/src/css/main.css +18 -4
- package/src/css/panel.scss +1 -6
- package/src/css/screenSize.css +19 -16
- package/src/css/swal.css +0 -1
- package/src/displaySize.js +1 -1
- package/src/distance/distance.js +19 -12
- package/src/distance/distanceTrack.js +6 -6
- package/src/gaze/gaze.js +4 -4
- package/src/gaze/gazeAccuracy.js +2 -3
- package/src/gaze/gazeCalibration.js +5 -5
- package/src/gaze/gazeTracker.js +1 -1
- package/src/i18n.js +6 -0
- package/src/index.js +1 -1
- package/src/interpupillaryDistance.js +10 -5
- package/src/{panel/panel.js → panel.js} +56 -23
- package/src/screenSize.js +46 -33
- package/src/text.json +0 -34
package/.eslintrc.js
CHANGED
package/.husky/pre-commit
CHANGED
package/.prettierignore
CHANGED
package/CHANGELOG.md
CHANGED
@@ -9,14 +9,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
9
9
|
|
10
10
|
### Added
|
11
11
|
|
12
|
+
**i18n!**
|
13
|
+
|
14
|
+
- Internationalization! A full list of supported languages can be found at https://docs.google.com/spreadsheets/d/1UFfNikfLuo8bSromE34uWDuJrMPFiJG3VpoQKdCGkII/edit#gid=0.
|
15
|
+
- A few new getters related to languages:
|
16
|
+
- `.userLanguage` (as a part of `.environment()`)
|
17
|
+
- `.language` (e.g., `en-US`, `zh-CN`)
|
18
|
+
- `.languageNameEnglish` (e.g., `English`, `Chinese (Simplified)`)
|
19
|
+
- `.languageNameNative` (e.g., `简体中文`)
|
20
|
+
- `.languageDirection` (`LTR` or `RTL`)
|
21
|
+
- `.languagePhraseSource` (e.g., `Denis Pelli & Peiling Jiang 2021.10.10`)
|
22
|
+
- `.languageData` gets the whole data history of languages.
|
23
|
+
- `.supportedLanguages` gets an array of supported languages.
|
24
|
+
- `.newLanguage(lang = 'en-US')` to set a new language for the calibrator.
|
25
|
+
- Allows researchers to set language on initialization using the `language` option. Set to `AUTO` (default) will let the calibrator go with the user language.
|
12
26
|
- `.isMobile` getter.
|
13
27
|
- Call `.environment()` automatically when initializing the calibrator.
|
28
|
+
- Instructions in the viewing distance measurement (and head tracking setup) is scrollable to avoid overlapping with the canvas on small screen sizes.
|
29
|
+
- Automatically minimize the mobile address bar when a calibration task starts.
|
14
30
|
|
15
31
|
### Changed
|
16
32
|
|
17
33
|
- Improved UI and performance for small screens and mobile devices.
|
18
34
|
- Take Return instead of Space for confirming screen size measurement.
|
19
35
|
|
36
|
+
### Fixed
|
37
|
+
|
38
|
+
- Fatal error due to cannot detect device for VR headsets.
|
39
|
+
|
40
|
+
### Removed
|
41
|
+
|
42
|
+
- The responsive arrow in the screen size calibration with credit card.
|
43
|
+
|
20
44
|
## [0.2.3] - 2021-10-05
|
21
45
|
|
22
46
|
### Added
|
package/README.md
CHANGED
@@ -57,8 +57,8 @@ RemoteCalibrator.measureDistance({}, data => {
|
|
57
57
|
| [👀 Gaze](#-gaze) | [`trackGaze()`](#start-tracking) [`async getGazeNow()`](#async-get-gaze-now) [`calibrateGaze()`](#calibrate) [`getGazeAccuracy()`](#get-accuracy-) [Lifecycle](#lifecycle-1) [Others](#others-1) |
|
58
58
|
| [💻 Environment](#-environment) | [`environment()`](#-environment) |
|
59
59
|
| [💄 Customization](#-customization) | `backgroundColor()` `videoOpacity()` `showCancelButton()` |
|
60
|
-
| [📔 Other Functions](#-other-functions) | `checkInitialized()` `getFullscreen()`
|
61
|
-
| [🎣 Getters](#-getters) | [Experiment](#experiment) [Environment](#environment) [All Data](#all-data) [Others](#others-2)
|
60
|
+
| [📔 Other Functions](#-other-functions) | `checkInitialized()` `getFullscreen()` `newLanguage()` |
|
61
|
+
| [🎣 Getters](#-getters) | [Experiment](#experiment) [Environment](#environment) [i18n](#i18n) [All Data](#all-data) [Others](#others-2) |
|
62
62
|
|
63
63
|
Arguments in square brackets are optional, e.g. `init([options, [callback]])` means both `options` configuration and the `callback` function are optional, but you have to put `options`, e.g., `{}`, if you want to call the callback function. The default values of `options` are listed in each section with explanation.
|
64
64
|
|
@@ -81,8 +81,17 @@ Pass `{ value, timestamp }` (equivalent to `RemoteCalibrator.id`) to callback.
|
|
81
81
|
* A random one will be generated if no value is passed into the function
|
82
82
|
*/
|
83
83
|
id: /* Randomized value */,
|
84
|
-
|
85
|
-
|
84
|
+
/**
|
85
|
+
* Set the language, e.g., 'en-US', 'zh-CN'
|
86
|
+
* If set to 'AUTO' (default), the calibrator will try to follow the browser settings
|
87
|
+
* A full list of supported languages can be found at
|
88
|
+
* https://docs.google.com/spreadsheets/d/1UFfNikfLuo8bSromE34uWDuJrMPFiJG3VpoQKdCGkII/edit#gid=0
|
89
|
+
*/
|
90
|
+
language: 'AUTO',
|
91
|
+
/**
|
92
|
+
* Enter full screen if set to true
|
93
|
+
* Will be ignored if already in full screen mode
|
94
|
+
*/
|
86
95
|
fullscreen: false,
|
87
96
|
}
|
88
97
|
```
|
@@ -112,11 +121,9 @@ The `data` passed into the callback function is an [object](https://www.w3school
|
|
112
121
|
![Panel](./media/panel.png)
|
113
122
|
|
114
123
|
```js
|
115
|
-
.panel(tasks, parentQuery, [options, [callback, [resolveOnFinish]]])
|
124
|
+
/* async */ .panel(tasks, parentQuery, [options, [callback, [resolveOnFinish]]])
|
116
125
|
```
|
117
126
|
|
118
|
-
**Since 0.2.0:** `.panel()` is now an async function.
|
119
|
-
|
120
127
|
`.panel()` is a powerful tool to help you set up a graphical user interface for participants to go through step-by-step and calibrate or set up tracking. It is highly customizable: tasks, task order, title, description, and "Done" button can all be customized. It is appended to the parent HTML node as set by `parentQuery`, e.g., if the parent node has id `main-area`, put `#main-area` as the `parentQuery`. Can only run once. Return a JavaScript [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises) that will resolve the `resolveOnFinish` once the "Done" button is pressed.
|
121
128
|
|
122
129
|
`tasks` is an array of tasks which can be a string or an object. Valid names are `screenSize`, `displaySize`, `measureDistance`, `trackDistance`, `trackGaze`, `environment` (system information).
|
@@ -391,7 +398,7 @@ Pop an interface for participants to calibrate their gaze position on the screen
|
|
391
398
|
|
392
399
|
Get the setup information of the experiment, including browser type, device model, operating system family and version, etc. This function does not create its own timestamp, but use the one associated with `id`, i.e. the one created when `init()` is called.
|
393
400
|
|
394
|
-
Pass `{ value: { browser, browserVersion, model, manufacturer, engine, system, systemFamily, description, fullDescription }, timestamp }` to callback.
|
401
|
+
Pass `{ value: { browser, browserVersion, model, manufacturer, engine, system, systemFamily, description, fullDescription, userLanguage }, timestamp }` to callback.
|
395
402
|
|
396
403
|
### 💄 Customization
|
397
404
|
|
@@ -403,6 +410,7 @@ Pass `{ value: { browser, browserVersion, model, manufacturer, engine, system, s
|
|
403
410
|
|
404
411
|
- `.checkInitialized()` Check if the model is initialized. Return a boolean.
|
405
412
|
- `.getFullscreen()` Get fullscreen mode.
|
413
|
+
- `.newLanguage(lang = 'en-US')` Set a new language for the calibrator.
|
406
414
|
|
407
415
|
### 🎣 Getters
|
408
416
|
|
@@ -424,7 +432,7 @@ Getters will get `null` if no data can be found, i.e. the corresponding function
|
|
424
432
|
|
425
433
|
The associated timestamp of the following items is the one created at initiation, i.e. when `init()` is called.
|
426
434
|
|
427
|
-
- `.bot` If the user agent is a bot or not,
|
435
|
+
- `.bot` If the user agent is a bot or not, `null` will be returned if no bot detected, e.g., `Googlebot (Search bot) by Google Inc.`.
|
428
436
|
- `.browser` The browser type, e.g., `Safari`, `Chrome`.
|
429
437
|
- `.browserVersion` The browser version.
|
430
438
|
- `.deviceType` The type of device, e.g., `desktop`.
|
@@ -436,6 +444,16 @@ The associated timestamp of the following items is the one created at initiation
|
|
436
444
|
- `.systemFamily` The family name of the device OS, e.g., `OS X`.
|
437
445
|
- `.description` A tidy description of the current environment, e.g., `Chrome 89.0.4389.90 on OS X 11.2.1 64-bit`.
|
438
446
|
- `.fullDescription` The full description of the current environment.
|
447
|
+
- `.userLanguage` The language used in the browser, e.g., `en`.
|
448
|
+
|
449
|
+
#### i18n
|
450
|
+
|
451
|
+
- `.language` (e.g., `en-US`, `zh-CN`)
|
452
|
+
- `.languageNameEnglish` (e.g., `English`, `Chinese (Simplified)`)
|
453
|
+
- `.languageNameNative` (e.g., `简体中文`)
|
454
|
+
- `.languageDirection` (`LTR` or `RTL`)
|
455
|
+
- `.languagePhraseSource` (e.g., `Denis Pelli & Peiling Jiang 2021.10.10`)
|
456
|
+
- `.supportedLanguages` An array of all supported languages. Can be called before initialization.
|
439
457
|
|
440
458
|
#### All Data
|
441
459
|
|
@@ -449,6 +467,7 @@ Use the following keywords to retrieve the whole dataset.
|
|
449
467
|
- `.gazeData`
|
450
468
|
- `.fullScreenData`
|
451
469
|
- `.environmentData`
|
470
|
+
- `.languageData`
|
452
471
|
|
453
472
|
#### Others
|
454
473
|
|
package/homepage/example.css
CHANGED
package/homepage/index.html
CHANGED
@@ -51,6 +51,8 @@
|
|
51
51
|
>
|
52
52
|
</p>
|
53
53
|
|
54
|
+
<div id="rc-language"></div>
|
55
|
+
|
54
56
|
<h2>Functions</h2>
|
55
57
|
|
56
58
|
<div id="functions" class="flex-wrapper"></div>
|
@@ -128,6 +130,12 @@
|
|
128
130
|
'nearPointCm',
|
129
131
|
'gazePositionPx',
|
130
132
|
'isFullscreen',
|
133
|
+
'id',
|
134
|
+
'language',
|
135
|
+
'languageNameEnglish',
|
136
|
+
'languageNameNative',
|
137
|
+
'languageDirection',
|
138
|
+
'languagePhraseSource',
|
131
139
|
]
|
132
140
|
|
133
141
|
const gettersEnv = [
|
@@ -142,6 +150,7 @@
|
|
142
150
|
'systemFamily',
|
143
151
|
'description',
|
144
152
|
'fullDescription',
|
153
|
+
'userLanguage',
|
145
154
|
'version',
|
146
155
|
]
|
147
156
|
|
@@ -163,6 +172,23 @@
|
|
163
172
|
setGetters(document.getElementById('getters-exp'), gettersExp)
|
164
173
|
setGetters(document.getElementById('getters-env'), gettersEnv)
|
165
174
|
|
175
|
+
// i18n
|
176
|
+
const langPickerParent = document.getElementById('rc-language')
|
177
|
+
let langInner = '<select name="lang" id="lang-picker">'
|
178
|
+
for (let lang of RemoteCalibrator.supportedLanguages) {
|
179
|
+
langInner += `<option value="${lang.language}">${lang.languageNameNative}</option>`
|
180
|
+
}
|
181
|
+
langInner += '</select>'
|
182
|
+
langPickerParent.innerHTML = langInner
|
183
|
+
|
184
|
+
document.querySelector('#lang-picker').onchange = e => {
|
185
|
+
RemoteCalibrator.newLanguage(
|
186
|
+
document.querySelector('#lang-picker').value
|
187
|
+
)
|
188
|
+
RemoteCalibrator.resetPanel()
|
189
|
+
}
|
190
|
+
//
|
191
|
+
|
166
192
|
initialize({ target: document.getElementById('init-button') })
|
167
193
|
</script>
|
168
194
|
<!-- GitHub corner -->
|
@@ -0,0 +1,71 @@
|
|
1
|
+
const process = require('process')
|
2
|
+
const fs = require('fs')
|
3
|
+
const XLSX = require('xlsx')
|
4
|
+
const google = require('googleapis')
|
5
|
+
|
6
|
+
const auth = new google.Auth.GoogleAuth({
|
7
|
+
keyFile: `${__dirname}/credentials.json`,
|
8
|
+
scopes: 'https://www.googleapis.com/auth/spreadsheets',
|
9
|
+
})
|
10
|
+
|
11
|
+
async function processLanguageSheet() {
|
12
|
+
const spreadsheetId = '1UFfNikfLuo8bSromE34uWDuJrMPFiJG3VpoQKdCGkII'
|
13
|
+
const googleSheets = new google.sheets_v4.Sheets()
|
14
|
+
const rows = await googleSheets.spreadsheets.values.get({
|
15
|
+
auth,
|
16
|
+
spreadsheetId,
|
17
|
+
range: 'Sheet1',
|
18
|
+
})
|
19
|
+
|
20
|
+
const rowsJSON = XLSX.utils.sheet_to_json(
|
21
|
+
XLSX.utils.aoa_to_sheet(rows.data.values),
|
22
|
+
{
|
23
|
+
defval: '',
|
24
|
+
}
|
25
|
+
)
|
26
|
+
|
27
|
+
const data = {}
|
28
|
+
for (let phrase of rowsJSON) {
|
29
|
+
const { language, ...translations } = phrase
|
30
|
+
if (language.includes('RC_') || language.includes('EE_'))
|
31
|
+
data[language] = translations
|
32
|
+
}
|
33
|
+
|
34
|
+
for (let phrase in data) {
|
35
|
+
for (let lang in data[phrase]) {
|
36
|
+
if (data[phrase][lang].includes('XX'))
|
37
|
+
data[phrase][lang] = data[phrase][lang]
|
38
|
+
.replace('XXX', 'xxx')
|
39
|
+
.replace('XX', 'xx')
|
40
|
+
}
|
41
|
+
}
|
42
|
+
|
43
|
+
const exportWarning = `/*
|
44
|
+
Do not modify this file! Run npm \`npm run phrases\` at ROOT of this project to fetch from the Google Sheets.
|
45
|
+
https://docs.google.com/spreadsheets/d/1UFfNikfLuo8bSromE34uWDuJrMPFiJG3VpoQKdCGkII/edit#gid=0
|
46
|
+
*/\n\n`
|
47
|
+
const exportHandle = `export const phrases = `
|
48
|
+
|
49
|
+
fs.writeFile(
|
50
|
+
`${process.cwd()}/src/i18n.js`,
|
51
|
+
exportWarning + exportHandle + JSON.stringify(data) + '\n',
|
52
|
+
error => {
|
53
|
+
if (error) {
|
54
|
+
console.log("Error! Couldn't write to the file.", error)
|
55
|
+
} else {
|
56
|
+
console.log(
|
57
|
+
'EasyEyes International Phrases fetched and written into files successfully.'
|
58
|
+
)
|
59
|
+
}
|
60
|
+
}
|
61
|
+
)
|
62
|
+
}
|
63
|
+
|
64
|
+
require('dns').resolve('www.google.com', function (err) {
|
65
|
+
if (err) {
|
66
|
+
console.log('No internet connection. Skip fetching phrases.')
|
67
|
+
} else {
|
68
|
+
console.log('Fetching up-to-date phrases...')
|
69
|
+
processLanguageSheet()
|
70
|
+
}
|
71
|
+
})
|