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.
Files changed (41) hide show
  1. package/.eslintrc.js +1 -1
  2. package/.husky/pre-commit +1 -1
  3. package/.prettierignore +4 -0
  4. package/CHANGELOG.md +38 -1
  5. package/README.md +33 -13
  6. package/homepage/example.css +4 -0
  7. package/homepage/example.js +1 -0
  8. package/homepage/index.html +26 -0
  9. package/i18n/.eslintrc.js +12 -0
  10. package/i18n/fetch-languages-sheets.js +62 -0
  11. package/lib/RemoteCalibrator.min.js +1 -1
  12. package/lib/RemoteCalibrator.min.js.LICENSE.txt +1 -1
  13. package/lib/RemoteCalibrator.min.js.map +1 -1
  14. package/package.json +12 -8
  15. package/src/components/buttons.js +4 -3
  16. package/src/components/language.js +31 -0
  17. package/src/components/onCanvas.js +4 -8
  18. package/src/components/swalOptions.js +25 -23
  19. package/src/{helpers.js → components/utils.js} +8 -2
  20. package/src/{video.js → components/video.js} +23 -4
  21. package/src/const.js +23 -3
  22. package/src/core.js +106 -6
  23. package/src/css/distance.scss +12 -7
  24. package/src/css/main.css +65 -10
  25. package/src/css/panel.scss +1 -1
  26. package/src/css/screenSize.css +28 -14
  27. package/src/debug.js +2 -0
  28. package/src/displaySize.js +1 -1
  29. package/src/distance/distance.js +20 -13
  30. package/src/distance/distanceTrack.js +9 -8
  31. package/src/gaze/gaze.js +22 -20
  32. package/src/gaze/gazeAccuracy.js +3 -4
  33. package/src/gaze/gazeCalibration.js +30 -22
  34. package/src/gaze/gazeTracker.js +4 -2
  35. package/src/i18n.js +6 -0
  36. package/src/index.js +1 -1
  37. package/src/interpupillaryDistance.js +34 -18
  38. package/src/{panel/panel.js → panel.js} +57 -21
  39. package/src/screenSize.js +72 -35
  40. package/src/constants.js +0 -11
  41. 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.0",
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.5",
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.3.0",
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.0",
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.56.1",
51
- "webpack-cli": "^4.8.0",
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 = 'OK'
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 = 'Cancel'
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 = colorDarkRed
31
+ if (!sparkle) ctx.fillStyle = RC._CONST.COLOR.DARK_RED
34
32
  else {
35
- // 10 Hz
36
- if (frameCount % 6 < 3) ctx.fillStyle = colorDarkRed
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 { colorIconOrange } from '../constants'
1
+ import { phrases } from '../i18n'
2
2
 
3
- export const swalInfoOptions = {
4
- icon: 'info',
5
- allowEscapeKey: false,
6
- allowEnterKey: false,
7
- allowOutsideClick: false,
8
- showConfirmButton: true,
9
- confirmButtonText: 'OK',
10
- showClass: {
11
- popup: 'animate__animated animate__fadeInUp',
12
- // backdrop: 'animate__animated animate__fadeIn',
13
- },
14
- hideClass: {
15
- popup: 'animate__animated animate__fadeOutDown',
16
- // backdrop: 'animate__animated animate__fadeOut',
17
- },
18
- iconColor: colorIconOrange,
19
- confirmButtonColor: '#aaa',
20
- customClass: {
21
- icon: 'my__swal2__icon',
22
- title: 'my__swal2__title',
23
- htmlContainer: 'my__swal2__html',
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(headline, description = null) {
101
+ export function constructInstructions(
102
+ headline,
103
+ description = null,
104
+ scrollable = false
105
+ ) {
102
106
  return (
103
- `<div class="calibration-instruction"><h1>${headline}</h1>` +
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
- v.style.left = '10px'
82
- v.style.bottom = '10px'
81
+
82
+ // Set position
83
+ setDefaultVideoPosition(RC, v)
83
84
 
84
85
  // Give callback after 2 sec
85
86
  setTimeout(() => {
86
- v.style.transition = `left 0.5s, bottom 0.5s, width 0.5s, height 0.5s, border-radius 0.5s`
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
- CREDIT_TEXT: {
5
- BLIND_SPOT_TEST: `As suggested by the Li et al. (2020) "Virtual Chinrest" paper.`,
6
- CREDIT_CARD: `Credit card suggested by the Li et al. (2020) "Virtual Chinrest" paper.`,
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 './constants'
12
- import { getFullscreen, blurAll, constructInstructions } from './helpers'
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
- if (callback) callback(this._id)
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 ? `${bot.name} (${bot.category}) by ${bot.producer.name}` : '',
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 = '10%'
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 = '10%'
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 {
@@ -3,17 +3,22 @@
3
3
  }
4
4
 
5
5
  #blind-spot-canvas {
6
- z-index: -1;
6
+ position: fixed;
7
7
  display: block;
8
- position: absolute;
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
- display: block !important;
15
- top: 65%;
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: absolute;
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
- width: calc(100% - 4rem);
57
- width: max(min(100% - 4rem, 960px), 300px);
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
- font-size: 0.9rem;
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: absolute;
113
+ position: fixed;
68
114
  text-align: center;
69
115
  user-select: none;
70
- background: rgba(255, 255, 255, 0.7);
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
- left: 50% !important;
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
  }
@@ -34,7 +34,7 @@
34
34
 
35
35
  .rc-panel-title {
36
36
  color: #fff !important;
37
- margin: 1rem auto 0 1rem !important;
37
+ margin: 1rem 1rem 0 1rem !important;
38
38
  font-size: 2rem !important;
39
39
  font-weight: 600 !important;
40
40
  }