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.
@@ -1,13 +1,13 @@
1
1
  import tinycolor from 'tinycolor2'
2
2
 
3
- import RemoteCalibrator from '../core'
4
- import text from '../text.json'
3
+ import RemoteCalibrator from './core'
4
+ import { phrases } from './i18n'
5
5
 
6
6
  // Icons from Google Material UI
7
- import Camera from '../media/photo_camera.svg'
8
- import Phone from '../media/smartphone.svg'
7
+ import Camera from './media/photo_camera.svg'
8
+ import Phone from './media/smartphone.svg'
9
9
 
10
- import '../css/panel.scss'
10
+ import './css/panel.scss'
11
11
 
12
12
  RemoteCalibrator.prototype.removePanel = function () {
13
13
  if (!this._hasPanel) return false
@@ -86,12 +86,12 @@ RemoteCalibrator.prototype.panel = async function (
86
86
 
87
87
  options = Object.assign(
88
88
  {
89
- headline: text.panel.headline,
90
- description: text.panel.description,
89
+ headline: phrases.RC_panelTitle[this.L],
90
+ description: phrases.RC_panelIntro[this.L],
91
91
  showNextButton: false,
92
- nextHeadline: text.panel.nextHeadline,
93
- nextDescription: text.panel.nextDescription,
94
- nextButton: text.panel.nextButton,
92
+ nextHeadline: phrases.RC_panelTitleNext[this.L],
93
+ nextDescription: phrases.RC_panelIntroNext[this.L],
94
+ nextButton: phrases.RC_panelButton[this.L],
95
95
  color: '#3490de',
96
96
  _demoActivateAll: false, // ! Private
97
97
  },
@@ -119,6 +119,9 @@ RemoteCalibrator.prototype.panel = async function (
119
119
 
120
120
  const panel = document.createElement('div')
121
121
  panel.className = panel.id = 'rc-panel'
122
+ if (this.LD === this._CONST.RTL) panel.className += ' rc-lang-rtl'
123
+ else panel.className += ' rc-lang-ltr'
124
+
122
125
  panel.innerHTML = `<h1 class="rc-panel-title" id="rc-panel-title">${options.headline}</h1>`
123
126
  panel.innerHTML += `<p class="rc-panel-description" id="rc-panel-description">${options.description}</p>`
124
127
  panel.innerHTML += '<div class="rc-panel-steps" id="rc-panel-steps"></div>'
@@ -129,17 +132,18 @@ RemoteCalibrator.prototype.panel = async function (
129
132
  const steps = panel.querySelector('#rc-panel-steps')
130
133
 
131
134
  // Observe panel size for adjusting steps
135
+ const RC = this
132
136
  const panelObserver = new ResizeObserver(() => {
133
- _setStepsClassesSL(steps, panel.offsetWidth)
137
+ _setStepsClassesSL(steps, panel.offsetWidth, RC.LD)
134
138
  })
135
139
  panelObserver.observe(panel)
136
- _setStepsClassesSL(steps, panel.offsetWidth)
140
+ _setStepsClassesSL(steps, panel.offsetWidth, this.LD)
137
141
 
138
142
  if (tasks.length === 0) {
139
143
  steps.className += ' rc-panel-no-steps'
140
144
  } else {
141
145
  for (let t in tasks) {
142
- const b = _newStepBlock(t, tasks[t], options)
146
+ const b = _newStepBlock(this, t, tasks[t], options)
143
147
  steps.appendChild(b)
144
148
  }
145
149
  }
@@ -155,7 +159,21 @@ RemoteCalibrator.prototype.panel = async function (
155
159
  this._panel.panelObserver = panelObserver
156
160
  this._panel.panelTasks = tasks
157
161
  this._panel.panelParent = parent
158
- this._panel.panelOptions = options
162
+
163
+ const tempOptions = { ...options }
164
+ if (options.headline === phrases.RC_panelTitle[this.L])
165
+ delete tempOptions.headline
166
+ if (options.description === phrases.RC_panelIntro[this.L])
167
+ delete tempOptions.description
168
+ if (options.nextHeadline === phrases.RC_panelTitleNext[this.L])
169
+ delete tempOptions.nextHeadline
170
+ if (options.nextDescription === phrases.RC_panelIntroNext[this.L])
171
+ delete tempOptions.nextDescription
172
+ if (options.nextButton === phrases.RC_panelButton[this.L])
173
+ delete tempOptions.nextButton
174
+
175
+ this._panel.panelOptions = tempOptions
176
+
159
177
  this._panel.panelCallback = callback
160
178
  this._panel.panelResolve = resolveOnFinish
161
179
 
@@ -184,27 +202,33 @@ RemoteCalibrator.prototype.panel = async function (
184
202
  const _validTaskList = {
185
203
  screenSize: {
186
204
  use: 1,
187
- name: 'Screen Size',
205
+ name: phrases.RC_screenSize['en-US'],
206
+ phraseHandle: 'RC_screenSize',
188
207
  },
189
208
  displaySize: {
190
209
  use: 0,
191
- name: 'Display Size',
210
+ name: phrases.RC_displaySize['en-US'],
211
+ phraseHandle: 'RC_displaySize',
192
212
  },
193
213
  measureDistance: {
194
214
  use: 2,
195
- name: 'Viewing Distance',
215
+ name: phrases.RC_viewingDistance['en-US'],
216
+ phraseHandle: 'RC_viewingDistance',
196
217
  },
197
218
  trackDistance: {
198
219
  use: 2,
199
- name: 'Head Tracking',
220
+ name: phrases.RC_headTracking['en-US'],
221
+ phraseHandle: 'RC_headTracking',
200
222
  },
201
223
  trackGaze: {
202
224
  use: 2,
203
- name: 'Gaze Tracking',
225
+ name: phrases.RC_gazeTracking['en-US'],
226
+ phraseHandle: 'RC_gazeTracking',
204
227
  },
205
228
  environment: {
206
229
  use: 0,
207
- name: 'System Information',
230
+ name: phrases.RC_environment['en-US'],
231
+ phraseHandle: 'RC_environment',
208
232
  },
209
233
  }
210
234
  const _validTaskListNames = Object.keys(_validTaskList)
@@ -223,7 +247,7 @@ const _validateTask = task => {
223
247
  return true
224
248
  }
225
249
 
226
- const _newStepBlock = (index, task, options) => {
250
+ const _newStepBlock = (RC, index, task, options) => {
227
251
  let useCode = _validTaskList[_getTaskName(task)].use
228
252
  let use, useTip
229
253
 
@@ -260,7 +284,7 @@ const _newStepBlock = (index, task, options) => {
260
284
  b.innerHTML =
261
285
  (use.length ? `<p class="rc-panel-step-use">${use}</p>` : '') +
262
286
  `<p class="rc-panel-step-name">${Number(index) + 1}&nbsp;&nbsp;${
263
- _validTaskList[_getTaskName(task)].name
287
+ phrases[_validTaskList[_getTaskName(task)].phraseHandle][RC.L]
264
288
  }</p>` +
265
289
  (use.length ? `<p class="rc-panel-step-use-tip">${use} ${useTip}</p>` : '')
266
290
  // b.disabled = true
@@ -276,13 +300,22 @@ const _nextStepBlock = (index, options) => {
276
300
  return b
277
301
  }
278
302
 
279
- const _setStepsClassesSL = (steps, panelWidth) => {
303
+ const _setStepsClassesSL = (steps, panelWidth, LD) => {
280
304
  if (panelWidth < 640) {
281
305
  steps.classList.add('rc-panel-steps-s')
282
306
  steps.classList.remove('rc-panel-steps-l')
307
+
308
+ steps.childNodes.forEach(e => {
309
+ e.classList.add(`rc-lang-${LD.toLowerCase()}`)
310
+ })
283
311
  } else {
284
312
  steps.classList.add('rc-panel-steps-l')
285
313
  steps.classList.remove('rc-panel-steps-s')
314
+
315
+ steps.childNodes.forEach(e => {
316
+ e.classList.remove(`rc-lang-ltr`)
317
+ e.classList.remove(`rc-lang-rtl`)
318
+ })
286
319
  }
287
320
  }
288
321
 
package/src/screenSize.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import RemoteCalibrator from './core'
2
- import { toFixedNumber, blurAll, remap } from './helpers'
2
+ import { toFixedNumber, blurAll, remap } from './components/utils'
3
3
 
4
4
  import Card from './media/card.svg'
5
5
  import Arrow from './media/arrow.svg'
@@ -7,7 +7,7 @@ import USBA from './media/usba.svg'
7
7
  import USBC from './media/usbc.svg'
8
8
  import { bindKeys, unbindKeys } from './components/keyBinder'
9
9
  import { addButtons } from './components/buttons'
10
- import text from './text.json'
10
+ import { phrases } from './i18n'
11
11
 
12
12
  // TODO Make it customizable
13
13
  const defaultObj = 'usba'
@@ -49,19 +49,30 @@ RemoteCalibrator.prototype.screenSize = function (options = {}, callback) {
49
49
  quitFullscreenOnFinished: false,
50
50
  repeatTesting: 1,
51
51
  decimalPlace: 1,
52
- headline: text.screenSize.headline,
53
- description: text.screenSize.description,
52
+ headline: '🖥️ ' + phrases.RC_screenSizeTitle[this.L],
53
+ description: phrases.RC_screenSizeIntro[this.L],
54
54
  },
55
55
  options
56
56
  )
57
57
 
58
58
  this.getFullscreen(options.fullscreen)
59
59
 
60
- options.description += `<br /><b class="rc-size-obj-selection">I have a <select id="matching-obj"><option value="usba" selected>USB Type-A Connector</option><option value="usbc">USB Type-C Connector</option><option value="card">Credit Card</option></select> with me.</b>`
60
+ options.description += `<br /><br /><b class="rc-size-obj-selection">${phrases.RC_screenSizeHave[
61
+ this.L
62
+ ].replace(
63
+ 'xxx',
64
+ `<select id="matching-obj"><option value="usba" selected>${
65
+ phrases.RC_screenSizeUSBA[this.L]
66
+ }</option><option value="usbc">${
67
+ phrases.RC_screenSizeUSBC[this.L]
68
+ }</option><option value="card">${
69
+ phrases.RC_screenSizeCreditCard[this.L]
70
+ }</option></select>`
71
+ )}</b>`
61
72
 
62
73
  this._addBackground()
63
74
  this._addBackgroundText(options.headline, options.description)
64
- this._addCreditOnBackground(this._CONST.CREDIT_TEXT.CREDIT_CARD)
75
+ this._addCreditOnBackground(phrases.RC_screenSizeCredit[this.L])
65
76
 
66
77
  getSize(this, this.background, options, callback)
67
78
 
@@ -71,8 +82,8 @@ RemoteCalibrator.prototype.screenSize = function (options = {}, callback) {
71
82
  function getSize(RC, parent, options, callback) {
72
83
  // Slider
73
84
  const sliderElement = document.createElement('input')
74
- sliderElement.id = 'size-slider'
75
- sliderElement.className = 'slider'
85
+ sliderElement.id = 'rc-size-slider'
86
+ sliderElement.className = 'rc-slider'
76
87
  sliderElement.type = 'range'
77
88
  sliderElement.min = 0
78
89
  sliderElement.max = 100
@@ -83,37 +94,27 @@ function getSize(RC, parent, options, callback) {
83
94
  sliderElement.step = 0.1
84
95
 
85
96
  setSliderPosition(sliderElement, parent)
97
+ setSliderStyle(sliderElement)
86
98
  parent.appendChild(sliderElement)
87
99
 
88
100
  const _onDown = (e, type) => {
89
101
  if (
90
- e.target.className === 'slider' &&
91
- e.target.id === 'size-slider' &&
102
+ e.target.className === 'rc-slider' &&
103
+ e.target.id === 'rc-size-slider' &&
92
104
  ((type === RC._CONST.S.CLICK_TYPE.MOUSE && e.which === 1) ||
93
105
  type === RC._CONST.S.CLICK_TYPE.TOUCH)
94
106
  ) {
95
107
  e.target.style.cursor = 'grabbing'
96
- arrowFillElement.setAttribute('fill', RC._CONST.COLOR.DARK_RED)
108
+ arrowFillElement.setAttribute('fill', RC._CONST.COLOR.ORANGE)
109
+ const _onEnd = () => {
110
+ sliderElement.style.cursor = 'grab'
111
+ arrowFillElement.setAttribute('fill', RC._CONST.COLOR.LIGHT_GREY)
112
+ document.removeEventListener('mouseup', _onEnd, false)
113
+ }
97
114
  if (type === RC._CONST.S.CLICK_TYPE.MOUSE)
98
- document.addEventListener(
99
- 'mouseup',
100
- function _onMouseUp() {
101
- sliderElement.style.cursor = 'grab'
102
- arrowFillElement.setAttribute('fill', '#aaa')
103
- document.removeEventListener('mouseup', _onMouseUp, false)
104
- },
105
- false
106
- )
115
+ document.addEventListener('mouseup', _onEnd, false)
107
116
  else if (type === RC._CONST.S.CLICK_TYPE.TOUCH)
108
- document.addEventListener(
109
- 'touchend',
110
- function _onTouchend() {
111
- sliderElement.style.cursor = 'grab'
112
- arrowFillElement.setAttribute('fill', '#aaa')
113
- document.removeEventListener('mouseup', _onTouchend, false)
114
- },
115
- false
116
- )
117
+ document.addEventListener('touchend', _onEnd, false)
117
118
  }
118
119
  }
119
120
 
@@ -139,7 +140,7 @@ function getSize(RC, parent, options, callback) {
139
140
  switchMatchingObj('card', elements)
140
141
  // Card & Arrow
141
142
  let arrowFillElement = document.getElementById('size-arrow-fill')
142
- arrowFillElement.setAttribute('fill', '#aaa')
143
+ arrowFillElement.setAttribute('fill', RC._CONST.COLOR.LIGHT_GREY)
143
144
  let arrowSizes = {
144
145
  width: elements.arrow.getBoundingClientRect().width,
145
146
  height: elements.arrow.getBoundingClientRect().height,
@@ -153,6 +154,7 @@ function getSize(RC, parent, options, callback) {
153
154
 
154
155
  setSizes()
155
156
  const onSliderInput = () => {
157
+ setSliderStyle(sliderElement)
156
158
  setSizes()
157
159
  }
158
160
  const resizeObserver = new ResizeObserver(() => {
@@ -206,6 +208,7 @@ function getSize(RC, parent, options, callback) {
206
208
  })
207
209
 
208
210
  addButtons(
211
+ RC.L,
209
212
  RC.background,
210
213
  {
211
214
  go: finishFunction,
@@ -262,7 +265,7 @@ const addMatchingObj = (names, parent) => {
262
265
  elements[name] = element
263
266
  }
264
267
 
265
- setObjectsPosition(elements, document.querySelector('#size-slider'))
268
+ setObjectsPosition(elements, document.querySelector('#rc-size-slider'))
266
269
 
267
270
  return elements
268
271
  }
@@ -272,8 +275,9 @@ const switchMatchingObj = (name, elements, setSizes) => {
272
275
  if (obj === name) elements[obj].style.visibility = 'visible'
273
276
  else elements[obj].style.visibility = 'hidden'
274
277
  }
275
- if (name === 'card') elements.arrow.style.visibility = 'visible'
276
- else elements.arrow.style.visibility = 'hidden'
278
+ // if (name === 'card') elements.arrow.style.visibility = 'visible'
279
+ // else elements.arrow.style.visibility = 'hidden'
280
+ elements.arrow.style.visibility = 'hidden'
277
281
  if (setSizes) setSizes()
278
282
  }
279
283
 
@@ -324,3 +328,12 @@ const setObjectsPosition = (objects, slider) => {
324
328
  for (let i in objects)
325
329
  objects[i].style.top = slider.getBoundingClientRect().top + 50 + 'px'
326
330
  }
331
+
332
+ /* -------------------------------------------------------------------------- */
333
+
334
+ const setSliderStyle = ele => {
335
+ const ratio = ele.value / ele.max
336
+ ele.style.background = `linear-gradient(90deg, #ffc772, #ffc772 ${
337
+ ratio * 100
338
+ }%, #fff ${ratio * 100}%)`
339
+ }
package/src/text.json DELETED
@@ -1,34 +0,0 @@
1
- {
2
- "screenSize": {
3
- "headline": "🖥️ Screen Size Calibration",
4
- "description": "We will measure your screen size. Find a <b>USB connector</b> (like the one providing power to your laptop) or a <b>credit card</b> (or any card of the same size), place it on the screen and drag the slider to match the sizes of the physical and displayed objects. When the sizes match, press <b>RETURN</b> or click <b>OK</b>."
5
- },
6
- "measureDistance": {
7
- "headline": "📏 Measure Viewing Distance",
8
- "description": "We'll measure your viewing distance. To do this, we will perform a blind spot test. Close/Cover one of your eyes (as instructed below) and focus on the black crosshair. Press <b>SPACE</b> or click <b>OK</b> when the red circle disappears. If it doesn't disappear, try moving closer to the screen."
9
- },
10
- "trackDistance": {
11
- "headline": "🙂 Set up for Head Tracking",
12
- "description": "Now we'll set up head tracking, to monitor viewing distance. When asked, please grant permission to access your camera. We'll perform a blind spot test first. Close/Cover one of your eyes (as instructed below) and focus on the black crosshair. Please press <b>SPACE</b> or click <b>OK</b> when the red dot disappears. If it doesn't disappear, try moving closer to the screen. You'll do this twice with each eye. Once you're done, head tracking will begin."
13
- },
14
- "calibrateGaze": {
15
- "headline": "👀 Set up for Gaze Tracking",
16
- "description": "Now we'll set up gaze tracking, to monitor eye position. When asked, please grant permission to access your camera. Try to keep your face centered in the video feed. Click on the <b style=\"color: #ff005c\">pink dot</b> at each location that it stops at. Make sure that your eyes are on the dot when you click."
17
- },
18
- "getGazeAccuracy": {
19
- "headline": "👀 Get Gaze Accuracy",
20
- "description": "We will measure your gaze accuracy. Please do not move the mouse and look at the fixation at the middle of the screen for the next 5 seconds."
21
- },
22
- "panel": {
23
- "headline": "Please press a button, to calibrate.",
24
- "description": "",
25
- "nextHeadline": "Thanks for calibrating. Hit the button to continue.",
26
- "nextDescription": "",
27
- "nextButton": "Done"
28
- },
29
- "measurePD": {
30
- "headline": "👁️ Measure Pupillary Distance",
31
- "description": "We'll measure the distance between the centers of your eyes. Hold the cable to your eyes, align the thumbs with the centers of your pupils. Then hold the cable against the ruler and align the left thumb with zero, check where the right thumb is. Finally, click on the ruler and click <b>OK</b> to submit your measurement. You can use the video image as a reference. If you do have a ruler with you, go ahead and use it.",
32
- "shortDescription": "Hold the cable to your eyes, align the thumbs with the centers of your pupils. Then hold the cable against the ruler and align the left thumb with zero, check where the right thumb is. Finally, click on the ruler and click <b>OK</b> to submit your measurement. You can use the video image as a reference. If you do have a ruler with you, go ahead and use it."
33
- }
34
- }