remote-calibrator 0.3.0-beta.0 → 0.3.0-beta.4
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 +38 -1
- package/README.md +33 -13
- package/homepage/example.css +4 -0
- package/homepage/example.js +1 -0
- package/homepage/index.html +26 -0
- package/i18n/.eslintrc.js +12 -0
- package/i18n/fetch-languages-sheets.js +62 -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 +12 -8
- package/src/components/buttons.js +4 -3
- package/src/components/language.js +31 -0
- package/src/components/onCanvas.js +4 -8
- package/src/components/swalOptions.js +25 -23
- package/src/{helpers.js → components/utils.js} +8 -2
- package/src/{video.js → components/video.js} +23 -4
- package/src/const.js +23 -3
- package/src/core.js +106 -6
- package/src/css/distance.scss +12 -7
- package/src/css/main.css +65 -10
- package/src/css/panel.scss +1 -1
- package/src/css/screenSize.css +28 -14
- package/src/debug.js +2 -0
- package/src/displaySize.js +1 -1
- package/src/distance/distance.js +20 -13
- package/src/distance/distanceTrack.js +9 -8
- package/src/gaze/gaze.js +22 -20
- package/src/gaze/gazeAccuracy.js +3 -4
- package/src/gaze/gazeCalibration.js +30 -22
- package/src/gaze/gazeTracker.js +4 -2
- package/src/i18n.js +6 -0
- package/src/index.js +1 -1
- package/src/interpupillaryDistance.js +34 -18
- package/src/{panel/panel.js → panel.js} +57 -21
- package/src/screenSize.js +72 -35
- package/src/constants.js +0 -11
- package/src/text.json +0 -34
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "remote-calibrator",
|
3
|
-
"version": "0.3.0-beta.
|
3
|
+
"version": "0.3.0-beta.4",
|
4
4
|
"description": "A toolbox for remote testing calibration and tracking.",
|
5
5
|
"main": "lib/RemoteCalibrator.min.js",
|
6
6
|
"directories": {
|
@@ -15,7 +15,8 @@
|
|
15
15
|
"build": "webpack --env=production",
|
16
16
|
"serve": "node server.js",
|
17
17
|
"prepare": "husky install",
|
18
|
-
"netlify": "cp -r ./lib ./homepage"
|
18
|
+
"netlify": "cp -r ./lib ./homepage",
|
19
|
+
"phrases": "node i18n/fetch-languages-sheets.js && git add src/i18n.js"
|
19
20
|
},
|
20
21
|
"repository": {
|
21
22
|
"type": "git",
|
@@ -28,17 +29,19 @@
|
|
28
29
|
},
|
29
30
|
"homepage": "https://github.com/EasyEyes/remote-calibrator#readme",
|
30
31
|
"devDependencies": {
|
31
|
-
"@babel/core": "^7.15.
|
32
|
+
"@babel/core": "^7.15.8",
|
32
33
|
"autoprefixer": "^10.3.7",
|
33
34
|
"babel-loader": "^8.2.2",
|
34
35
|
"clean-webpack-plugin": "^4.0.0",
|
35
|
-
"css-loader": "^6.
|
36
|
+
"css-loader": "^6.4.0",
|
36
37
|
"cssnano": "^5.0.8",
|
37
38
|
"eslint": "^7.32.0",
|
38
39
|
"eslint-webpack-plugin": "^3.0.1",
|
39
40
|
"express": "^4.17.1",
|
41
|
+
"googleapis": "^88.2.0",
|
40
42
|
"husky": "^7.0.2",
|
41
|
-
"lint-staged": "^11.2.
|
43
|
+
"lint-staged": "^11.2.3",
|
44
|
+
"nodemon": "^2.0.13",
|
42
45
|
"postcss-loader": "^6.1.1",
|
43
46
|
"prettier": "^2.4.1",
|
44
47
|
"sass": "^1.42.1",
|
@@ -47,9 +50,10 @@
|
|
47
50
|
"svg-inline-loader": "^0.8.2",
|
48
51
|
"terser-webpack-plugin": "^5.2.4",
|
49
52
|
"url-loader": "^4.1.1",
|
50
|
-
"webpack": "^5.
|
51
|
-
"webpack-cli": "^4.
|
52
|
-
"webpack-modules": "^1.0.0"
|
53
|
+
"webpack": "^5.58.1",
|
54
|
+
"webpack-cli": "^4.9.0",
|
55
|
+
"webpack-modules": "^1.0.0",
|
56
|
+
"xlsx": "^0.17.2"
|
53
57
|
},
|
54
58
|
"lint-staged": {
|
55
59
|
"*.js": "eslint --cache --fix",
|
@@ -1,6 +1,7 @@
|
|
1
|
+
import { phrases } from '../i18n'
|
1
2
|
import '../css/buttons.scss'
|
2
3
|
|
3
|
-
export const addButtons = (parent, { go, cancel }, showCancelButton) => {
|
4
|
+
export const addButtons = (RCL, parent, { go, cancel }, showCancelButton) => {
|
4
5
|
const buttons = document.createElement('div')
|
5
6
|
buttons.className = 'rc-buttons'
|
6
7
|
buttons.id = 'rc-buttons'
|
@@ -11,7 +12,7 @@ export const addButtons = (parent, { go, cancel }, showCancelButton) => {
|
|
11
12
|
goButton = document.createElement('button')
|
12
13
|
goButton.className = 'rc-button rc-go-button'
|
13
14
|
goButton.onclick = go
|
14
|
-
goButton.innerHTML =
|
15
|
+
goButton.innerHTML = phrases.RC_ok[RCL]
|
15
16
|
buttons.appendChild(goButton)
|
16
17
|
}
|
17
18
|
|
@@ -19,7 +20,7 @@ export const addButtons = (parent, { go, cancel }, showCancelButton) => {
|
|
19
20
|
cancelButton = document.createElement('button')
|
20
21
|
cancelButton.className = 'rc-button rc-cancel-button'
|
21
22
|
cancelButton.onclick = cancel
|
22
|
-
cancelButton.innerHTML =
|
23
|
+
cancelButton.innerHTML = phrases.RC_cancel[RCL]
|
23
24
|
buttons.appendChild(cancelButton)
|
24
25
|
}
|
25
26
|
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { phrases } from '../i18n'
|
2
|
+
|
3
|
+
export function looseSetLanguage(lang) {
|
4
|
+
const originalKeys = Object.keys(phrases.EE_languageNameNative)
|
5
|
+
if (originalKeys.includes(lang)) return constructLangData(lang)
|
6
|
+
|
7
|
+
const shortKeys = []
|
8
|
+
originalKeys.forEach(l => {
|
9
|
+
shortKeys.push(l.split('-')[0])
|
10
|
+
})
|
11
|
+
|
12
|
+
const shortLang = lang.split('-')[0].toLowerCase()
|
13
|
+
|
14
|
+
if (shortKeys.includes(shortLang))
|
15
|
+
return constructLangData(originalKeys[shortKeys.indexOf(shortLang)])
|
16
|
+
|
17
|
+
return constructLangData('en-US')
|
18
|
+
}
|
19
|
+
|
20
|
+
function constructLangData(lang) {
|
21
|
+
return {
|
22
|
+
value: {
|
23
|
+
language: lang,
|
24
|
+
languageNameEnglish: phrases.EE_languageNameEnglish[lang],
|
25
|
+
languageNameNative: phrases.EE_languageNameNative[lang],
|
26
|
+
languageDirection: phrases.EE_languageDirection[lang],
|
27
|
+
languagePhraseSource: phrases.EE_phraseSource[lang],
|
28
|
+
},
|
29
|
+
timestamp: new Date(),
|
30
|
+
}
|
31
|
+
}
|
@@ -1,8 +1,6 @@
|
|
1
1
|
// Draw cross and circle on the canvas
|
2
2
|
// For blind spot test and more
|
3
3
|
|
4
|
-
import { colorDarkRed } from '../constants'
|
5
|
-
|
6
4
|
// CROSS
|
7
5
|
const crossLW = 32 // Width of a line of the middle cross
|
8
6
|
const crossLH = 3
|
@@ -25,18 +23,16 @@ export function _getCircleBounds(side, crossX, cW) {
|
|
25
23
|
: [circleR >> 1, crossX - (crossLW + circleR) / 2]
|
26
24
|
}
|
27
25
|
|
28
|
-
export function _circle(ctx, x, y, frameCount, sparkle = true) {
|
26
|
+
export function _circle(RC, ctx, x, y, frameCount, sparkle = true) {
|
29
27
|
ctx.beginPath()
|
30
28
|
ctx.arc(x, y, circleR >> 1, 0, Math.PI * 2)
|
31
29
|
ctx.closePath()
|
32
30
|
|
33
|
-
if (!sparkle) ctx.fillStyle =
|
31
|
+
if (!sparkle) ctx.fillStyle = RC._CONST.COLOR.DARK_RED
|
34
32
|
else {
|
35
|
-
|
36
|
-
|
37
|
-
else if (frameCount % 6 >= 3) ctx.fillStyle = '#fff'
|
33
|
+
if (frameCount % 4 < 2) ctx.fillStyle = RC._CONST.COLOR.DARK_RED
|
34
|
+
else ctx.fillStyle = '#fff'
|
38
35
|
}
|
39
36
|
|
40
|
-
// ctx.fillStyle = colorDarkRed // Red fill
|
41
37
|
ctx.fill()
|
42
38
|
}
|
@@ -1,25 +1,27 @@
|
|
1
|
-
import {
|
1
|
+
import { phrases } from '../i18n'
|
2
2
|
|
3
|
-
export const swalInfoOptions = {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
3
|
+
export const swalInfoOptions = RC => {
|
4
|
+
return {
|
5
|
+
icon: 'info',
|
6
|
+
allowEscapeKey: false,
|
7
|
+
allowEnterKey: false,
|
8
|
+
allowOutsideClick: false,
|
9
|
+
showConfirmButton: true,
|
10
|
+
confirmButtonText: phrases.RC_ok[RC.L],
|
11
|
+
showClass: {
|
12
|
+
popup: 'animate__animated animate__fadeInUp',
|
13
|
+
// backdrop: 'animate__animated animate__fadeIn',
|
14
|
+
},
|
15
|
+
hideClass: {
|
16
|
+
popup: 'animate__animated animate__fadeOutDown',
|
17
|
+
// backdrop: 'animate__animated animate__fadeOut',
|
18
|
+
},
|
19
|
+
iconColor: RC._CONST.COLOR.ORANGE,
|
20
|
+
confirmButtonColor: '#aaa',
|
21
|
+
customClass: {
|
22
|
+
icon: 'my__swal2__icon',
|
23
|
+
title: 'my__swal2__title',
|
24
|
+
htmlContainer: 'my__swal2__html',
|
25
|
+
},
|
26
|
+
}
|
25
27
|
}
|
@@ -98,9 +98,15 @@ export function getFullscreen() {
|
|
98
98
|
|
99
99
|
/* -------------------------------------------------------------------------- */
|
100
100
|
|
101
|
-
export function constructInstructions(
|
101
|
+
export function constructInstructions(
|
102
|
+
headline,
|
103
|
+
description = null,
|
104
|
+
scrollable = false
|
105
|
+
) {
|
102
106
|
return (
|
103
|
-
`<div class="calibration-instruction
|
107
|
+
`<div class="calibration-instruction${
|
108
|
+
scrollable ? ' calibration-instruction-scrollable' : ''
|
109
|
+
}"><h1>${headline}</h1>` +
|
104
110
|
(description
|
105
111
|
? `<p class="calibration-description">${description}</p></div>`
|
106
112
|
: '')
|
@@ -69,7 +69,7 @@ export function checkWebcamStatus() {
|
|
69
69
|
* Check if WebGazer video is ready. If so, set the style for it.
|
70
70
|
*
|
71
71
|
*/
|
72
|
-
export function checkWebgazerReady(pipWidthPx, opacity, WG, callback) {
|
72
|
+
export function checkWebgazerReady(RC, pipWidthPx, opacity, WG, callback) {
|
73
73
|
let c = setInterval(() => {
|
74
74
|
let v = document.getElementById('webgazerVideoContainer')
|
75
75
|
if (v) {
|
@@ -78,15 +78,34 @@ export function checkWebgazerReady(pipWidthPx, opacity, WG, callback) {
|
|
78
78
|
v.style.width = pipWidthPx + 'px'
|
79
79
|
v.style.opacity = opacity
|
80
80
|
WG.setVideoViewerSize(parseInt(v.style.width), parseInt(v.style.height))
|
81
|
-
|
82
|
-
|
81
|
+
|
82
|
+
// Set position
|
83
|
+
setDefaultVideoPosition(RC, v)
|
83
84
|
|
84
85
|
// Give callback after 2 sec
|
85
86
|
setTimeout(() => {
|
86
|
-
|
87
|
+
if (RC.isMobile.value)
|
88
|
+
v.style.transition = `right 0.5s, top 0.5s, width 0.5s, height 0.5s, border-radius 0.5s`
|
89
|
+
else
|
90
|
+
v.style.transition = `left 0.5s, bottom 0.5s, width 0.5s, height 0.5s, border-radius 0.5s`
|
87
91
|
callback()
|
88
92
|
}, 1000)
|
89
93
|
clearInterval(c)
|
90
94
|
}
|
91
95
|
}, 200)
|
92
96
|
}
|
97
|
+
|
98
|
+
export function setDefaultVideoPosition(RC, v) {
|
99
|
+
if (RC.isMobile.value) {
|
100
|
+
// Mobile
|
101
|
+
v.style.left = 'unset'
|
102
|
+
v.style.right = RC._CONST.N.VIDEO_MARGIN
|
103
|
+
v.style.top = RC._CONST.N.VIDEO_MARGIN
|
104
|
+
v.style.bottom = 'unset'
|
105
|
+
} else {
|
106
|
+
v.style.left = RC._CONST.N.VIDEO_MARGIN
|
107
|
+
v.style.right = 'unset'
|
108
|
+
v.style.top = 'unset'
|
109
|
+
v.style.bottom = RC._CONST.N.VIDEO_MARGIN
|
110
|
+
}
|
111
|
+
}
|
package/src/const.js
CHANGED
@@ -1,8 +1,28 @@
|
|
1
1
|
import RemoteCalibrator from './core'
|
2
2
|
|
3
3
|
RemoteCalibrator.prototype._CONST = Object.freeze({
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
N: {
|
5
|
+
VIDEO_W: {
|
6
|
+
DESKTOP: 208,
|
7
|
+
MOBILE: 144,
|
8
|
+
},
|
9
|
+
VIDEO_MARGIN: '10px',
|
10
|
+
GAZE_CALIBRATION: {
|
11
|
+
R: 28,
|
12
|
+
MARGIN: 10,
|
13
|
+
BORDER: 8,
|
14
|
+
},
|
15
|
+
},
|
16
|
+
S: {
|
17
|
+
AUTO: 'AUTO',
|
18
|
+
CLICK_TYPE: {
|
19
|
+
MOUSE: 'mouse',
|
20
|
+
TOUCH: 'touch',
|
21
|
+
},
|
22
|
+
},
|
23
|
+
COLOR: {
|
24
|
+
LIGHT_GREY: '#cccccc',
|
25
|
+
ORANGE: '#ff9a00',
|
26
|
+
DARK_RED: '#ac0d0d',
|
7
27
|
},
|
8
28
|
})
|
package/src/core.js
CHANGED
@@ -8,8 +8,14 @@ import platform from 'platform'
|
|
8
8
|
import DeviceDetector from 'device-detector-js'
|
9
9
|
|
10
10
|
import randomPhrases from './components/randomPhrases'
|
11
|
-
import { debug } from './
|
12
|
-
import {
|
11
|
+
import { debug } from './debug'
|
12
|
+
import {
|
13
|
+
getFullscreen,
|
14
|
+
blurAll,
|
15
|
+
constructInstructions,
|
16
|
+
} from './components/utils'
|
17
|
+
import { looseSetLanguage } from './components/language'
|
18
|
+
import { phrases } from './i18n'
|
13
19
|
|
14
20
|
class RemoteCalibrator {
|
15
21
|
constructor() {
|
@@ -29,6 +35,9 @@ class RemoteCalibrator {
|
|
29
35
|
|
30
36
|
this._id = null
|
31
37
|
|
38
|
+
this._lang = null // A single string, e.g., 'en-US'
|
39
|
+
this._langData = []
|
40
|
+
|
32
41
|
this._environmentData = []
|
33
42
|
|
34
43
|
this._displayData = [] // Px
|
@@ -76,6 +85,7 @@ class RemoteCalibrator {
|
|
76
85
|
////
|
77
86
|
|
78
87
|
get id() {
|
88
|
+
if (!this._id) return null
|
79
89
|
return {
|
80
90
|
value: this._id.value,
|
81
91
|
timestamp: this._id.timestamp,
|
@@ -100,6 +110,43 @@ class RemoteCalibrator {
|
|
100
110
|
}
|
101
111
|
}
|
102
112
|
|
113
|
+
get supportedLanguages() {
|
114
|
+
const a = []
|
115
|
+
for (let l in phrases.EE_languageNameEnglish) {
|
116
|
+
a.push({
|
117
|
+
language: l,
|
118
|
+
languageNameEnglish: phrases.EE_languageNameEnglish[l],
|
119
|
+
languageNameNative: phrases.EE_languageNameNative[l],
|
120
|
+
})
|
121
|
+
}
|
122
|
+
|
123
|
+
return a
|
124
|
+
}
|
125
|
+
|
126
|
+
get L() {
|
127
|
+
return this._lang
|
128
|
+
}
|
129
|
+
|
130
|
+
get language() {
|
131
|
+
return this._helper_get(this._langData, 'language')
|
132
|
+
}
|
133
|
+
|
134
|
+
get languageNameEnglish() {
|
135
|
+
return this._helper_get(this._langData, 'languageNameEnglish')
|
136
|
+
}
|
137
|
+
|
138
|
+
get languageNameNative() {
|
139
|
+
return this._helper_get(this._langData, 'languageNameNative')
|
140
|
+
}
|
141
|
+
|
142
|
+
get languageDirection() {
|
143
|
+
return this._helper_get(this._langData, 'languageDirection')
|
144
|
+
}
|
145
|
+
|
146
|
+
get languagePhraseSource() {
|
147
|
+
return this._helper_get(this._langData, 'languagePhraseSource')
|
148
|
+
}
|
149
|
+
|
103
150
|
// Status
|
104
151
|
|
105
152
|
get isFullscreen() {
|
@@ -135,6 +182,15 @@ class RemoteCalibrator {
|
|
135
182
|
return this._helper_get(this._environmentData, 'deviceType')
|
136
183
|
}
|
137
184
|
|
185
|
+
get isMobile() {
|
186
|
+
if (!this._environmentData.length) this.environment()
|
187
|
+
const d = this._helper_get(this._environmentData, 'deviceType')
|
188
|
+
return {
|
189
|
+
value: d.value !== 'desktop',
|
190
|
+
timestamp: d.timestamp,
|
191
|
+
}
|
192
|
+
}
|
193
|
+
|
138
194
|
get model() {
|
139
195
|
if (!this._environmentData.length) this.environment()
|
140
196
|
return this._helper_get(this._environmentData, 'model')
|
@@ -170,6 +226,11 @@ class RemoteCalibrator {
|
|
170
226
|
return this._helper_get(this._environmentData, 'fullDescription')
|
171
227
|
}
|
172
228
|
|
229
|
+
get userLanguage() {
|
230
|
+
if (!this._environmentData.length) this.environment()
|
231
|
+
return this._helper_get(this._environmentData, 'userLanguage')
|
232
|
+
}
|
233
|
+
|
173
234
|
// Screen
|
174
235
|
|
175
236
|
get displayWidthPx() {
|
@@ -274,6 +335,10 @@ class RemoteCalibrator {
|
|
274
335
|
return this._environmentData
|
275
336
|
}
|
276
337
|
|
338
|
+
get languageData() {
|
339
|
+
return this._langData
|
340
|
+
}
|
341
|
+
|
277
342
|
/* --------------------------------- SETTERS -------------------------------- */
|
278
343
|
|
279
344
|
/**
|
@@ -338,6 +403,13 @@ class RemoteCalibrator {
|
|
338
403
|
set newFullscreenData(data) {
|
339
404
|
this._fullscreenData.push(data)
|
340
405
|
}
|
406
|
+
|
407
|
+
/**
|
408
|
+
* @param {{ value: { language: string; languageNameEnglish: string; languageNameNative: string; languageDirection: string; languagePhraseSource: string; }; timestamp: Date; }} data
|
409
|
+
*/
|
410
|
+
set newLanguageData(data) {
|
411
|
+
this._langData.push(data)
|
412
|
+
}
|
341
413
|
}
|
342
414
|
|
343
415
|
/**
|
@@ -351,6 +423,7 @@ RemoteCalibrator.prototype.init = function (options = {}, callback) {
|
|
351
423
|
options = Object.assign(
|
352
424
|
{
|
353
425
|
id: randomPhrases(),
|
426
|
+
language: 'AUTO',
|
354
427
|
fullscreen: false,
|
355
428
|
},
|
356
429
|
options
|
@@ -363,7 +436,15 @@ RemoteCalibrator.prototype.init = function (options = {}, callback) {
|
|
363
436
|
timestamp: new Date(),
|
364
437
|
}
|
365
438
|
|
366
|
-
|
439
|
+
this.environment()
|
440
|
+
|
441
|
+
if (this._CONST.S.AUTO === options.language)
|
442
|
+
// AUTO
|
443
|
+
this.newLanguageData = looseSetLanguage(this.userLanguage.value)
|
444
|
+
else this.newLanguageData = looseSetLanguage(options.language)
|
445
|
+
this._lang = this.language.value
|
446
|
+
|
447
|
+
if (callback && typeof callback === 'function') callback(this._id)
|
367
448
|
}
|
368
449
|
}
|
369
450
|
|
@@ -381,7 +462,9 @@ RemoteCalibrator.prototype.environment = function (callback) {
|
|
381
462
|
|
382
463
|
const data = {
|
383
464
|
value: {
|
384
|
-
bot: bot
|
465
|
+
bot: bot
|
466
|
+
? `${bot.name} (${bot.category}) by ${bot.producer.name}`
|
467
|
+
: null,
|
385
468
|
browser: platform.name,
|
386
469
|
browserVersion: platform.version,
|
387
470
|
deviceType: device.device.type,
|
@@ -392,6 +475,8 @@ RemoteCalibrator.prototype.environment = function (callback) {
|
|
392
475
|
systemFamily: platform.os.family,
|
393
476
|
description: platform.description,
|
394
477
|
fullDescription: platform.ua,
|
478
|
+
userLanguage:
|
479
|
+
window.navigator.userLanguage || window.navigator.language,
|
395
480
|
},
|
396
481
|
timestamp: this.id.timestamp,
|
397
482
|
}
|
@@ -435,6 +520,18 @@ RemoteCalibrator.prototype.getFullscreen = function (f = true) {
|
|
435
520
|
return f && !debug
|
436
521
|
}
|
437
522
|
|
523
|
+
/**
|
524
|
+
* Set a new language
|
525
|
+
*/
|
526
|
+
RemoteCalibrator.prototype.newLanguage = function (lang) {
|
527
|
+
if (this.checkInitialized()) {
|
528
|
+
let data
|
529
|
+
this.newLanguageData = data = looseSetLanguage(lang)
|
530
|
+
this._lang = this.language.value
|
531
|
+
return data
|
532
|
+
}
|
533
|
+
}
|
534
|
+
|
438
535
|
/**
|
439
536
|
*
|
440
537
|
* Add background
|
@@ -447,6 +544,8 @@ RemoteCalibrator.prototype._addBackground = function (inner) {
|
|
447
544
|
if (!b) {
|
448
545
|
b = document.createElement('div')
|
449
546
|
b.id = 'calibration-background'
|
547
|
+
|
548
|
+
document.body.classList.add('lock-view')
|
450
549
|
document.body.appendChild(b)
|
451
550
|
|
452
551
|
b.style.background = this.params.backgroundColor
|
@@ -474,6 +573,7 @@ RemoteCalibrator.prototype._replaceBackground = function (inner) {
|
|
474
573
|
RemoteCalibrator.prototype._removeBackground = function () {
|
475
574
|
let b = document.getElementById('calibration-background')
|
476
575
|
if (b) {
|
576
|
+
document.body.classList.remove('lock-view')
|
477
577
|
document.body.removeChild(b)
|
478
578
|
|
479
579
|
this._background = {
|
@@ -541,11 +641,11 @@ RemoteCalibrator.prototype._setFloatInstructionElementPos = function (
|
|
541
641
|
const r = this.instructionElement.getBoundingClientRect()
|
542
642
|
this.instructionElement.style.top = `calc(50% + ${yOffset + 10}px)`
|
543
643
|
if (side === 'left') {
|
544
|
-
this.instructionElement.style.left =
|
644
|
+
this.instructionElement.style.left = `max(10%, ${r.width / 2}px)`
|
545
645
|
this.instructionElement.style.right = 'unset'
|
546
646
|
this.instructionElement.style.transform = `translate(${-r.width / 2}px, 0)`
|
547
647
|
} else if (side === 'right') {
|
548
|
-
this.instructionElement.style.right =
|
648
|
+
this.instructionElement.style.right = `max(10%, ${r.width / 2}px)`
|
549
649
|
this.instructionElement.style.left = 'unset'
|
550
650
|
this.instructionElement.style.transform = `translate(${r.width / 2}px, 0)`
|
551
651
|
} else {
|
package/src/css/distance.scss
CHANGED
@@ -3,17 +3,22 @@
|
|
3
3
|
}
|
4
4
|
|
5
5
|
#blind-spot-canvas {
|
6
|
-
|
6
|
+
position: fixed;
|
7
7
|
display: block;
|
8
|
-
|
8
|
+
z-index: -1;
|
9
9
|
top: 0;
|
10
10
|
left: 0;
|
11
|
+
bottom: 0;
|
12
|
+
right: 0;
|
13
|
+
padding: 0;
|
14
|
+
margin: 0;
|
11
15
|
}
|
12
16
|
|
13
|
-
#blind-spot-instruction {
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
+
// #blind-spot-instruction {
|
18
|
+
// display: block !important;
|
19
|
+
// top: 65%;
|
20
|
+
// position: fixed;
|
21
|
+
// }
|
17
22
|
|
18
23
|
#pip-video {
|
19
24
|
display: none;
|
@@ -31,7 +36,7 @@
|
|
31
36
|
/* ----------------------------------- PD ----------------------------------- */
|
32
37
|
|
33
38
|
#rc-ruler {
|
34
|
-
position:
|
39
|
+
position: fixed;
|
35
40
|
max-height: 120px;
|
36
41
|
overflow: hidden;
|
37
42
|
}
|
package/src/css/main.css
CHANGED
@@ -28,14 +28,15 @@
|
|
28
28
|
|
29
29
|
.calibration-instruction {
|
30
30
|
position: absolute;
|
31
|
-
margin: 2rem;
|
32
31
|
text-align: left;
|
33
32
|
user-select: none;
|
34
33
|
}
|
35
34
|
|
35
|
+
.calibration-instruction-scrollable {
|
36
|
+
height: 200%;
|
37
|
+
}
|
38
|
+
|
36
39
|
.calibration-instruction h1 {
|
37
|
-
font-size: 2.5rem !important;
|
38
|
-
line-height: 100%;
|
39
40
|
min-width: 360px;
|
40
41
|
font-weight: 700;
|
41
42
|
}
|
@@ -53,21 +54,66 @@
|
|
53
54
|
}
|
54
55
|
|
55
56
|
.calibration-description {
|
56
|
-
|
57
|
-
|
57
|
+
line-height: 170%;
|
58
|
+
}
|
59
|
+
|
60
|
+
/* -------------------------------------------------------------------------- */
|
61
|
+
/* Screen size specific */
|
62
|
+
|
63
|
+
@media (min-width: 481px) {
|
64
|
+
.calibration-instruction {
|
65
|
+
margin: 2rem;
|
66
|
+
}
|
67
|
+
|
68
|
+
.calibration-instruction h1 {
|
69
|
+
line-height: 100%;
|
70
|
+
font-size: 2.5rem !important;
|
71
|
+
}
|
72
|
+
|
73
|
+
.calibration-description {
|
74
|
+
width: calc(100% - 4rem);
|
75
|
+
width: max(min(100% - 4rem, 960px), 300px);
|
76
|
+
}
|
77
|
+
|
78
|
+
.calibration-description,
|
79
|
+
.calibration-description * {
|
80
|
+
font-size: 1.2rem;
|
81
|
+
}
|
82
|
+
|
83
|
+
.calibration-credit-text {
|
84
|
+
font-size: 0.9rem !important;
|
85
|
+
}
|
58
86
|
}
|
59
87
|
|
60
88
|
@media (max-width: 480px) {
|
89
|
+
.calibration-instruction {
|
90
|
+
margin: 1rem;
|
91
|
+
}
|
92
|
+
|
93
|
+
.calibration-instruction h1 {
|
94
|
+
line-height: 120%;
|
95
|
+
font-size: 1.8rem !important;
|
96
|
+
}
|
97
|
+
|
61
98
|
.calibration-description {
|
62
|
-
|
99
|
+
width: calc(100% - 1rem);
|
100
|
+
}
|
101
|
+
|
102
|
+
.calibration-description,
|
103
|
+
.calibration-description * {
|
104
|
+
font-size: 1rem;
|
105
|
+
}
|
106
|
+
|
107
|
+
.calibration-credit-text {
|
108
|
+
font-size: 0.7rem !important;
|
63
109
|
}
|
64
110
|
}
|
65
111
|
|
66
112
|
.float-instruction {
|
67
|
-
position:
|
113
|
+
position: fixed;
|
68
114
|
text-align: center;
|
69
115
|
user-select: none;
|
70
|
-
background: rgba(255, 255, 255, 0.
|
116
|
+
background: rgba(255, 255, 255, 0.9);
|
71
117
|
padding: 10px 17px;
|
72
118
|
margin: 0;
|
73
119
|
left: 50%;
|
@@ -75,6 +121,7 @@
|
|
75
121
|
border-radius: 10px;
|
76
122
|
font-size: 1.2rem;
|
77
123
|
font-weight: 500;
|
124
|
+
z-index: 9999;
|
78
125
|
}
|
79
126
|
|
80
127
|
/* -------------------------------------------------------------------------- */
|
@@ -87,10 +134,18 @@
|
|
87
134
|
|
88
135
|
.calibration-credit-text {
|
89
136
|
position: fixed !important;
|
90
|
-
|
137
|
+
width: 100% !important;
|
91
138
|
bottom: 3px !important;
|
139
|
+
left: 50% !important;
|
92
140
|
transform: translate(-50%, 0) !important;
|
93
|
-
font-size: 0.9rem !important;
|
94
141
|
color: #999 !important;
|
95
142
|
margin: 0 !important;
|
143
|
+
padding: 0 !important;
|
144
|
+
line-height: 100% !important;
|
145
|
+
}
|
146
|
+
|
147
|
+
/* -------------------------------------------------------------------------- */
|
148
|
+
|
149
|
+
.lock-view {
|
150
|
+
overflow: hidden !important;
|
96
151
|
}
|