@jspsych/plugin-tobii-user-position 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,421 @@
1
+ /**
2
+ * Display component for user position guide
3
+ * Shows a face outline that scales with distance, similar to Tobii Eye Tracker Manager
4
+ */
5
+ export class PositionDisplay {
6
+ constructor(container, options) {
7
+ // Constants for the display
8
+ this.BOX_WIDTH = 400;
9
+ this.BOX_HEIGHT = 300;
10
+ this.MIN_FACE_SCALE = 0.4; // Scale when far away
11
+ this.MAX_FACE_SCALE = 1.6; // Scale when too close
12
+ this.OPTIMAL_FACE_SCALE = 1.0; // Scale at optimal distance
13
+ this.container = container;
14
+ this.options = options;
15
+ this.createDisplay();
16
+ }
17
+ createDisplay() {
18
+ this.container.innerHTML = '';
19
+ // Message
20
+ this.messageElement = document.createElement('div');
21
+ this.messageElement.className = 'tobii-user-position-message';
22
+ this.messageElement.textContent = this.options.message;
23
+ this.container.appendChild(this.messageElement);
24
+ // Position guide container
25
+ const guideContainer = document.createElement('div');
26
+ guideContainer.className = 'tobii-user-position-guide';
27
+ this.container.appendChild(guideContainer);
28
+ // Tracking box (represents the optimal tracking zone)
29
+ this.trackingBoxElement = document.createElement('div');
30
+ this.trackingBoxElement.className = 'tobii-tracking-box';
31
+ this.trackingBoxElement.setAttribute('role', 'img');
32
+ this.trackingBoxElement.setAttribute('aria-label', 'Head position tracking display');
33
+ this.trackingBoxElement.style.cssText = `
34
+ position: relative;
35
+ width: ${this.BOX_WIDTH}px;
36
+ height: ${this.BOX_HEIGHT}px;
37
+ border: 3px solid #666;
38
+ border-radius: 12px;
39
+ background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
40
+ overflow: hidden;
41
+ box-shadow: inset 0 0 30px rgba(0,0,0,0.5);
42
+ `;
43
+ guideContainer.appendChild(this.trackingBoxElement);
44
+ // Optimal zone indicator (center rectangle)
45
+ const optimalZone = document.createElement('div');
46
+ optimalZone.style.cssText = `
47
+ position: absolute;
48
+ top: 50%;
49
+ left: 50%;
50
+ transform: translate(-50%, -50%);
51
+ width: 60%;
52
+ height: 70%;
53
+ border: 2px dashed rgba(255,255,255,0.2);
54
+ border-radius: 8px;
55
+ `;
56
+ this.trackingBoxElement.appendChild(optimalZone);
57
+ // Face outline container (this moves and scales)
58
+ this.faceOutlineElement = document.createElement('div');
59
+ this.faceOutlineElement.className = 'tobii-face-outline';
60
+ this.faceOutlineElement.setAttribute('aria-hidden', 'true');
61
+ this.faceOutlineElement.style.cssText = `
62
+ position: absolute;
63
+ top: 50%;
64
+ left: 50%;
65
+ transform: translate(-50%, -50%);
66
+ transition: all 0.1s ease-out;
67
+ `;
68
+ this.trackingBoxElement.appendChild(this.faceOutlineElement);
69
+ // Create face SVG
70
+ this.createFaceSVG();
71
+ // Distance bar (vertical bar on the side)
72
+ if (this.options.showDistanceFeedback) {
73
+ this.distanceBarContainer = document.createElement('div');
74
+ this.distanceBarContainer.style.cssText = `
75
+ position: absolute;
76
+ right: -40px;
77
+ top: 10%;
78
+ width: 20px;
79
+ height: 80%;
80
+ background: rgba(0,0,0,0.3);
81
+ border-radius: 10px;
82
+ border: 2px solid #444;
83
+ overflow: hidden;
84
+ `;
85
+ guideContainer.appendChild(this.distanceBarContainer);
86
+ // Distance labels
87
+ const closeLabel = document.createElement('div');
88
+ closeLabel.textContent = 'Close';
89
+ closeLabel.style.cssText = `
90
+ position: absolute;
91
+ right: -70px;
92
+ top: 0;
93
+ font-size: 10px;
94
+ color: #888;
95
+ `;
96
+ guideContainer.appendChild(closeLabel);
97
+ const farLabel = document.createElement('div');
98
+ farLabel.textContent = 'Far';
99
+ farLabel.style.cssText = `
100
+ position: absolute;
101
+ right: -55px;
102
+ bottom: 10%;
103
+ font-size: 10px;
104
+ color: #888;
105
+ `;
106
+ guideContainer.appendChild(farLabel);
107
+ this.distanceBarFill = document.createElement('div');
108
+ this.distanceBarFill.style.cssText = `
109
+ position: absolute;
110
+ bottom: 0;
111
+ left: 0;
112
+ width: 100%;
113
+ height: 50%;
114
+ background: ${this.options.goodColor};
115
+ border-radius: 8px;
116
+ transition: all 0.1s ease-out;
117
+ `;
118
+ this.distanceBarContainer.appendChild(this.distanceBarFill);
119
+ // Optimal zone marker on distance bar
120
+ const optimalMarker = document.createElement('div');
121
+ optimalMarker.style.cssText = `
122
+ position: absolute;
123
+ left: -2px;
124
+ right: -2px;
125
+ top: 40%;
126
+ height: 20%;
127
+ border: 2px solid rgba(255,255,255,0.5);
128
+ border-radius: 4px;
129
+ pointer-events: none;
130
+ `;
131
+ this.distanceBarContainer.appendChild(optimalMarker);
132
+ }
133
+ // Textual feedback
134
+ this.feedbackElement = document.createElement('div');
135
+ this.feedbackElement.className = 'tobii-position-feedback';
136
+ this.feedbackElement.setAttribute('role', 'status');
137
+ this.feedbackElement.setAttribute('aria-live', 'polite');
138
+ this.feedbackElement.style.cssText = `
139
+ margin-top: 20px;
140
+ font-size: 1.1em;
141
+ font-weight: 600;
142
+ text-align: center;
143
+ `;
144
+ this.container.appendChild(this.feedbackElement);
145
+ }
146
+ createFaceSVG() {
147
+ // Base size for the face
148
+ const baseWidth = 120;
149
+ const baseHeight = 150;
150
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
151
+ svg.setAttribute('width', `${baseWidth}`);
152
+ svg.setAttribute('height', `${baseHeight}`);
153
+ svg.setAttribute('viewBox', `0 0 ${baseWidth} ${baseHeight}`);
154
+ svg.style.cssText = 'overflow: visible;';
155
+ // Face outline (oval)
156
+ const faceOutline = document.createElementNS('http://www.w3.org/2000/svg', 'ellipse');
157
+ faceOutline.setAttribute('cx', '60');
158
+ faceOutline.setAttribute('cy', '80');
159
+ faceOutline.setAttribute('rx', '50');
160
+ faceOutline.setAttribute('ry', '65');
161
+ faceOutline.setAttribute('fill', 'none');
162
+ faceOutline.setAttribute('stroke', '#888');
163
+ faceOutline.setAttribute('stroke-width', '3');
164
+ faceOutline.setAttribute('stroke-dasharray', '8,4');
165
+ svg.appendChild(faceOutline);
166
+ // Left eye socket
167
+ this.leftEyeElement = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
168
+ this.leftEyeElement.setAttribute('cx', '40');
169
+ this.leftEyeElement.setAttribute('cy', '65');
170
+ this.leftEyeElement.setAttribute('r', '12');
171
+ this.leftEyeElement.setAttribute('fill', this.options.poorColor);
172
+ this.leftEyeElement.setAttribute('stroke', '#fff');
173
+ this.leftEyeElement.setAttribute('stroke-width', '2');
174
+ svg.appendChild(this.leftEyeElement);
175
+ // Right eye socket
176
+ this.rightEyeElement = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
177
+ this.rightEyeElement.setAttribute('cx', '80');
178
+ this.rightEyeElement.setAttribute('cy', '65');
179
+ this.rightEyeElement.setAttribute('r', '12');
180
+ this.rightEyeElement.setAttribute('fill', this.options.poorColor);
181
+ this.rightEyeElement.setAttribute('stroke', '#fff');
182
+ this.rightEyeElement.setAttribute('stroke-width', '2');
183
+ svg.appendChild(this.rightEyeElement);
184
+ // Nose hint
185
+ const nose = document.createElementNS('http://www.w3.org/2000/svg', 'path');
186
+ nose.setAttribute('d', 'M60,75 L55,95 L65,95 Z');
187
+ nose.setAttribute('fill', 'none');
188
+ nose.setAttribute('stroke', '#666');
189
+ nose.setAttribute('stroke-width', '2');
190
+ svg.appendChild(nose);
191
+ this.faceOutlineElement.appendChild(svg);
192
+ }
193
+ /**
194
+ * Update the display with new position data
195
+ */
196
+ updatePosition(positionData) {
197
+ if (!positionData) {
198
+ this.showNoData();
199
+ return;
200
+ }
201
+ // Calculate average position from both eyes
202
+ const avgX = this.getAveragePosition(positionData.leftX, positionData.rightX, positionData.leftValid, positionData.rightValid);
203
+ const avgY = this.getAveragePosition(positionData.leftY, positionData.rightY, positionData.leftValid, positionData.rightValid);
204
+ const avgZ = this.getAveragePosition(positionData.leftZ, positionData.rightZ, positionData.leftValid, positionData.rightValid);
205
+ // Update face position and scale
206
+ this.updateFaceDisplay(avgX, avgY, avgZ, positionData);
207
+ // Update distance bar
208
+ if (this.options.showDistanceFeedback && avgZ !== null) {
209
+ this.updateDistanceBar(avgZ);
210
+ }
211
+ // Update eye indicators
212
+ this.updateEyeIndicators(positionData);
213
+ // Update textual feedback
214
+ this.updateTextualFeedback(avgX, avgY, avgZ);
215
+ }
216
+ getAveragePosition(left, right, leftValid, rightValid) {
217
+ if (leftValid && rightValid && left !== null && right !== null) {
218
+ return (left + right) / 2;
219
+ }
220
+ else if (leftValid && left !== null) {
221
+ return left;
222
+ }
223
+ else if (rightValid && right !== null) {
224
+ return right;
225
+ }
226
+ return null;
227
+ }
228
+ updateFaceDisplay(x, y, z, _positionData) {
229
+ if (x === null || y === null) {
230
+ this.faceOutlineElement.style.opacity = '0.3';
231
+ return;
232
+ }
233
+ this.faceOutlineElement.style.opacity = '1';
234
+ // Calculate position offset from center
235
+ // x, y are 0-1 where 0.5 is center
236
+ // Y axis is inverted: y=0 is bottom, y=1 is top, so we invert it for screen coordinates
237
+ const offsetX = (x - 0.5) * this.BOX_WIDTH * 0.8;
238
+ const offsetY = (0.5 - y) * this.BOX_HEIGHT * 0.8; // Inverted Y
239
+ // Calculate scale based on distance (z)
240
+ // z is 0-1 where ~0.5 is optimal
241
+ // Based on track box: z=0 means at back (far), z=1 means at front (close)
242
+ let scale = this.OPTIMAL_FACE_SCALE;
243
+ if (z !== null) {
244
+ // z=1 (close) -> MAX_FACE_SCALE, z=0.5 -> OPTIMAL_FACE_SCALE, z=0 (far) -> MIN_FACE_SCALE
245
+ scale = this.MIN_FACE_SCALE + z * (this.MAX_FACE_SCALE - this.MIN_FACE_SCALE);
246
+ scale = Math.max(this.MIN_FACE_SCALE, Math.min(this.MAX_FACE_SCALE, scale));
247
+ }
248
+ this.faceOutlineElement.style.transform = `translate(calc(-50% + ${offsetX}px), calc(-50% + ${offsetY}px)) scale(${scale})`;
249
+ }
250
+ updateDistanceBar(z) {
251
+ if (!this.distanceBarFill)
252
+ return;
253
+ // z is 0-1, where z=1 is close (top of bar) and z=0 is far (bottom)
254
+ // Fill from bottom, so height represents z directly (closeness)
255
+ const fillPercent = z * 100;
256
+ this.distanceBarFill.style.height = `${fillPercent}%`;
257
+ // Color based on optimal range derived from distance thresholds
258
+ const goodMin = 0.5 - this.options.distanceThresholdGood;
259
+ const goodMax = 0.5 + this.options.distanceThresholdGood;
260
+ const fairMin = 0.5 - this.options.distanceThresholdFair;
261
+ const fairMax = 0.5 + this.options.distanceThresholdFair;
262
+ let color;
263
+ if (z >= goodMin && z <= goodMax) {
264
+ color = this.options.goodColor;
265
+ }
266
+ else if (z >= fairMin && z <= fairMax) {
267
+ color = this.options.fairColor;
268
+ }
269
+ else {
270
+ color = this.options.poorColor;
271
+ }
272
+ this.distanceBarFill.style.background = color;
273
+ }
274
+ updateEyeIndicators(positionData) {
275
+ // Update left eye color based on validity
276
+ if (this.leftEyeElement) {
277
+ const leftColor = positionData.leftValid ? this.options.goodColor : this.options.poorColor;
278
+ this.leftEyeElement.setAttribute('fill', leftColor);
279
+ }
280
+ // Update right eye color based on validity
281
+ if (this.rightEyeElement) {
282
+ const rightColor = positionData.rightValid ? this.options.goodColor : this.options.poorColor;
283
+ this.rightEyeElement.setAttribute('fill', rightColor);
284
+ }
285
+ }
286
+ updateTextualFeedback(x, y, z) {
287
+ if (!this.feedbackElement)
288
+ return;
289
+ if (x === null || y === null || z === null) {
290
+ this.feedbackElement.textContent =
291
+ 'Eyes not detected - please position yourself in front of the tracker';
292
+ this.feedbackElement.style.color = this.options.poorColor;
293
+ return;
294
+ }
295
+ const quality = this.assessPositionQuality(x, y, z);
296
+ let feedback;
297
+ let color;
298
+ if (quality.isGoodPosition) {
299
+ feedback = '✓ Position is good';
300
+ color = this.options.goodColor;
301
+ }
302
+ else {
303
+ const issues = [];
304
+ // Horizontal feedback — use configurable threshold (offset from 0.5 center)
305
+ const posFairThreshold = this.options.positionThresholdFair;
306
+ if (x < 0.5 - posFairThreshold)
307
+ issues.push('move right');
308
+ else if (x > 0.5 + posFairThreshold)
309
+ issues.push('move left');
310
+ // Vertical feedback (y=0 is bottom, y=1 is top)
311
+ if (y < 0.5 - posFairThreshold)
312
+ issues.push('move up');
313
+ else if (y > 0.5 + posFairThreshold)
314
+ issues.push('move down');
315
+ // Distance feedback (z=1 is close, z=0 is far)
316
+ const distFairThreshold = this.options.distanceThresholdFair;
317
+ if (z > 0.5 + distFairThreshold)
318
+ issues.push('move back');
319
+ else if (z < 0.5 - distFairThreshold)
320
+ issues.push('move closer');
321
+ if (issues.length > 0) {
322
+ feedback = `Please ${issues.join(' and ')}`;
323
+ }
324
+ else {
325
+ feedback = 'Position: Almost there...';
326
+ }
327
+ color =
328
+ quality.distanceStatus === 'poor' ||
329
+ quality.horizontalStatus === 'poor' ||
330
+ quality.verticalStatus === 'poor'
331
+ ? this.options.poorColor
332
+ : this.options.fairColor;
333
+ }
334
+ this.feedbackElement.textContent = feedback;
335
+ this.feedbackElement.style.color = color;
336
+ }
337
+ assessPositionQuality(x, y, z) {
338
+ // Assess horizontal position (0.5 is center)
339
+ const xOffset = Math.abs(x - 0.5);
340
+ let horizontalStatus;
341
+ if (xOffset < this.options.positionThresholdGood)
342
+ horizontalStatus = 'good';
343
+ else if (xOffset < this.options.positionThresholdFair)
344
+ horizontalStatus = 'fair';
345
+ else
346
+ horizontalStatus = 'poor';
347
+ // Assess vertical position (0.5 is center)
348
+ const yOffset = Math.abs(y - 0.5);
349
+ let verticalStatus;
350
+ if (yOffset < this.options.positionThresholdGood)
351
+ verticalStatus = 'good';
352
+ else if (yOffset < this.options.positionThresholdFair)
353
+ verticalStatus = 'fair';
354
+ else
355
+ verticalStatus = 'poor';
356
+ // Assess distance (0.5 is optimal)
357
+ const zOffset = Math.abs(z - 0.5);
358
+ let distanceStatus;
359
+ if (zOffset < this.options.distanceThresholdGood)
360
+ distanceStatus = 'good';
361
+ else if (zOffset < this.options.distanceThresholdFair)
362
+ distanceStatus = 'fair';
363
+ else
364
+ distanceStatus = 'poor';
365
+ const isGoodPosition = horizontalStatus === 'good' && verticalStatus === 'good' && distanceStatus === 'good';
366
+ return {
367
+ isGoodPosition,
368
+ horizontalStatus,
369
+ verticalStatus,
370
+ distanceStatus,
371
+ averageX: x,
372
+ averageY: y,
373
+ averageZ: z,
374
+ };
375
+ }
376
+ showNoData() {
377
+ if (this.feedbackElement) {
378
+ this.feedbackElement.textContent = 'Waiting for tracker data...';
379
+ this.feedbackElement.style.color = this.options.poorColor;
380
+ }
381
+ this.faceOutlineElement.style.opacity = '0.3';
382
+ }
383
+ /**
384
+ * Get current position quality
385
+ */
386
+ getCurrentQuality(positionData) {
387
+ if (!positionData) {
388
+ return {
389
+ isGoodPosition: false,
390
+ horizontalStatus: 'poor',
391
+ verticalStatus: 'poor',
392
+ distanceStatus: 'poor',
393
+ averageX: null,
394
+ averageY: null,
395
+ averageZ: null,
396
+ };
397
+ }
398
+ const avgX = this.getAveragePosition(positionData.leftX, positionData.rightX, positionData.leftValid, positionData.rightValid);
399
+ const avgY = this.getAveragePosition(positionData.leftY, positionData.rightY, positionData.leftValid, positionData.rightValid);
400
+ const avgZ = this.getAveragePosition(positionData.leftZ, positionData.rightZ, positionData.leftValid, positionData.rightValid);
401
+ if (avgX === null || avgY === null || avgZ === null) {
402
+ return {
403
+ isGoodPosition: false,
404
+ horizontalStatus: 'poor',
405
+ verticalStatus: 'poor',
406
+ distanceStatus: 'poor',
407
+ averageX: avgX,
408
+ averageY: avgY,
409
+ averageZ: avgZ,
410
+ };
411
+ }
412
+ return this.assessPositionQuality(avgX, avgY, avgZ);
413
+ }
414
+ /**
415
+ * Remove the display
416
+ */
417
+ destroy() {
418
+ this.container.innerHTML = '';
419
+ }
420
+ }
421
+ //# sourceMappingURL=position-display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"position-display.js","sourceRoot":"","sources":["position-display.ts"],"names":[],"mappings":"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"}