jspsych-tangram 0.0.12 → 0.0.14

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.
Files changed (49) hide show
  1. package/dist/construct/index.browser.js +283 -64
  2. package/dist/construct/index.browser.js.map +1 -1
  3. package/dist/construct/index.browser.min.js +11 -11
  4. package/dist/construct/index.browser.min.js.map +1 -1
  5. package/dist/construct/index.cjs +283 -64
  6. package/dist/construct/index.cjs.map +1 -1
  7. package/dist/construct/index.d.ts +36 -0
  8. package/dist/construct/index.js +283 -64
  9. package/dist/construct/index.js.map +1 -1
  10. package/dist/index.cjs +394 -94
  11. package/dist/index.cjs.map +1 -1
  12. package/dist/index.d.ts +84 -0
  13. package/dist/index.js +394 -94
  14. package/dist/index.js.map +1 -1
  15. package/dist/nback/index.browser.js +112 -37
  16. package/dist/nback/index.browser.js.map +1 -1
  17. package/dist/nback/index.browser.min.js +11 -11
  18. package/dist/nback/index.browser.min.js.map +1 -1
  19. package/dist/nback/index.cjs +112 -37
  20. package/dist/nback/index.cjs.map +1 -1
  21. package/dist/nback/index.d.ts +24 -0
  22. package/dist/nback/index.js +112 -37
  23. package/dist/nback/index.js.map +1 -1
  24. package/dist/prep/index.browser.js +278 -65
  25. package/dist/prep/index.browser.js.map +1 -1
  26. package/dist/prep/index.browser.min.js +11 -11
  27. package/dist/prep/index.browser.min.js.map +1 -1
  28. package/dist/prep/index.cjs +278 -65
  29. package/dist/prep/index.cjs.map +1 -1
  30. package/dist/prep/index.d.ts +24 -0
  31. package/dist/prep/index.js +278 -65
  32. package/dist/prep/index.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/core/components/board/BoardView.tsx +372 -124
  35. package/src/core/components/board/GameBoard.tsx +39 -44
  36. package/src/core/components/board/useGameBoard.ts +52 -0
  37. package/src/core/components/index.ts +4 -2
  38. package/src/core/components/pieces/BlueprintRing.tsx +100 -67
  39. package/src/core/components/pieces/useBlueprintRing.ts +39 -0
  40. package/src/core/config/config.ts +25 -10
  41. package/src/plugins/tangram-construct/ConstructionApp.tsx +7 -1
  42. package/src/plugins/tangram-construct/index.ts +22 -1
  43. package/src/plugins/tangram-nback/NBackApp.tsx +88 -29
  44. package/src/plugins/tangram-nback/index.ts +14 -0
  45. package/src/plugins/tangram-prep/PrepApp.tsx +7 -1
  46. package/src/plugins/tangram-prep/index.ts +14 -0
  47. package/tangram-construct.min.js +11 -11
  48. package/tangram-nback.min.js +11 -11
  49. package/tangram-prep.min.js +11 -11
@@ -19,6 +19,8 @@ export interface StartNBackTrialParams {
19
19
  instructions?: string;
20
20
  button_text?: string;
21
21
  duration: number;
22
+ usePrimitiveColors?: boolean;
23
+ primitiveColorIndices?: number[];
22
24
  onTrialEnd?: (data: any) => void;
23
25
  }
24
26
 
@@ -49,6 +51,8 @@ function NBackView({ params }: NBackViewProps) {
49
51
  instructions,
50
52
  button_text,
51
53
  duration,
54
+ usePrimitiveColors,
55
+ primitiveColorIndices,
52
56
  onTrialEnd
53
57
  } = params;
54
58
 
@@ -135,7 +139,12 @@ function NBackView({ params }: NBackViewProps) {
135
139
  ...data,
136
140
  accuracy,
137
141
  tangram_id: tangram.tangramID,
138
- is_match: isMatch
142
+ is_match: isMatch,
143
+ show_tangram_decomposition: show_tangram_decomposition,
144
+ use_primitive_colors: usePrimitiveColors,
145
+ primitive_color_indices: primitiveColorIndices,
146
+ duration: duration,
147
+ button_text: button_text
139
148
  };
140
149
 
141
150
  if (onTrialEnd) {
@@ -208,25 +217,50 @@ function NBackView({ params }: NBackViewProps) {
208
217
 
209
218
  return (
210
219
  <g key="sil-decomposed" pointerEvents="none">
211
- {placedPolys.map((scaledPoly, i) => (
212
- <React.Fragment key={`prim-${i}`}>
213
- {/* Fill path */}
214
- <path
215
- d={pathD(scaledPoly)}
216
- fill={CONFIG.color.silhouetteMask}
217
- opacity={CONFIG.opacity.silhouetteMask}
218
- stroke="none"
219
- />
220
+ {placedPolys.map((scaledPoly, i) => {
221
+ // Get color for this primitive based on its kind
222
+ const primInfo = primitiveDecomposition[i];
223
+ let fillColor = CONFIG.color.silhouetteMask;
220
224
 
221
- {/* Full perimeter border */}
222
- <path
223
- d={pathD(scaledPoly)}
224
- fill="none"
225
- stroke={CONFIG.color.tangramDecomposition.stroke}
226
- strokeWidth={CONFIG.size.stroke.tangramDecompositionPx}
227
- />
228
- </React.Fragment>
229
- ))}
225
+ if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
226
+ // Map primitive kind to index
227
+ const kindToIndex: Record<TanKind, number> = {
228
+ 'square': 0,
229
+ 'smalltriangle': 1,
230
+ 'parallelogram': 2,
231
+ 'medtriangle': 3,
232
+ 'largetriangle': 4
233
+ };
234
+ const primitiveIndex = kindToIndex[primInfo.kind as TanKind];
235
+ if (primitiveIndex !== undefined && primitiveColorIndices[primitiveIndex] !== undefined) {
236
+ const colorIndex = primitiveColorIndices[primitiveIndex];
237
+ const color = CONFIG.color.primitiveColors[colorIndex];
238
+ if (color) {
239
+ fillColor = color;
240
+ }
241
+ }
242
+ }
243
+
244
+ return (
245
+ <React.Fragment key={`prim-${i}`}>
246
+ {/* Fill path */}
247
+ <path
248
+ d={pathD(scaledPoly)}
249
+ fill={fillColor}
250
+ opacity={CONFIG.opacity.silhouetteMask}
251
+ stroke="none"
252
+ />
253
+
254
+ {/* Full perimeter border */}
255
+ <path
256
+ d={pathD(scaledPoly)}
257
+ fill="none"
258
+ stroke={CONFIG.color.tangramDecomposition.stroke}
259
+ strokeWidth={CONFIG.size.stroke.tangramDecompositionPx}
260
+ />
261
+ </React.Fragment>
262
+ );
263
+ })}
230
264
  </g>
231
265
  );
232
266
  } else {
@@ -235,15 +269,40 @@ function NBackView({ params }: NBackViewProps) {
235
269
 
236
270
  return (
237
271
  <g key="sil-unified" pointerEvents="none">
238
- {placedPolys.map((scaledPoly, i) => (
239
- <path
240
- key={`sil-${i}`}
241
- d={pathD(scaledPoly)}
242
- fill={CONFIG.color.silhouetteMask}
243
- opacity={CONFIG.opacity.silhouetteMask}
244
- stroke="none"
245
- />
246
- ))}
272
+ {placedPolys.map((scaledPoly, i) => {
273
+ // Get color for this primitive based on its kind
274
+ const primInfo = primitiveDecomposition[i];
275
+ let fillColor = CONFIG.color.silhouetteMask;
276
+
277
+ if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
278
+ // Map primitive kind to index
279
+ const kindToIndex: Record<TanKind, number> = {
280
+ 'square': 0,
281
+ 'smalltriangle': 1,
282
+ 'parallelogram': 2,
283
+ 'medtriangle': 3,
284
+ 'largetriangle': 4
285
+ };
286
+ const primitiveIndex = kindToIndex[primInfo.kind as TanKind];
287
+ if (primitiveIndex !== undefined && primitiveColorIndices[primitiveIndex] !== undefined) {
288
+ const colorIndex = primitiveColorIndices[primitiveIndex];
289
+ const color = CONFIG.color.primitiveColors[colorIndex];
290
+ if (color) {
291
+ fillColor = color;
292
+ }
293
+ }
294
+ }
295
+
296
+ return (
297
+ <path
298
+ key={`sil-${i}`}
299
+ d={pathD(scaledPoly)}
300
+ fill={fillColor}
301
+ opacity={CONFIG.opacity.silhouetteMask}
302
+ stroke="none"
303
+ />
304
+ );
305
+ })}
247
306
  </g>
248
307
  );
249
308
  }
@@ -256,7 +315,7 @@ function NBackView({ params }: NBackViewProps) {
256
315
  alignItems: "center",
257
316
  justifyContent: "center",
258
317
  padding: "20px",
259
- background: "#f5f5f5"
318
+ background: "#fff7e0ff"
260
319
  }}>
261
320
  {/* Instructions */}
262
321
  {instructions && (
@@ -41,6 +41,18 @@ const info = {
41
41
  default: 3000,
42
42
  description: "Duration in milliseconds to display tangram and accept responses"
43
43
  },
44
+ /** Whether to use distinct colors for each primitive shape type */
45
+ use_primitive_colors: {
46
+ type: ParameterType.BOOL,
47
+ default: false,
48
+ description: "Whether each primitive shape type should have its own distinct color in the displayed tangram"
49
+ },
50
+ /** Indices mapping primitives to colors from the color palette */
51
+ primitive_color_indices: {
52
+ type: ParameterType.OBJECT,
53
+ default: [0, 1, 2, 3, 4],
54
+ description: "Array of 5 integers indexing into primitiveColors array, mapping [square, smalltriangle, parallelogram, medtriangle, largetriangle] to colors"
55
+ },
44
56
  /** Callback fired when trial ends */
45
57
  onTrialEnd: {
46
58
  type: ParameterType.FUNCTION,
@@ -127,6 +139,8 @@ class TangramNBackPlugin implements JsPsychPlugin<Info> {
127
139
  instructions: trial.instructions,
128
140
  button_text: trial.button_text,
129
141
  duration: trial.duration,
142
+ usePrimitiveColors: trial.use_primitive_colors,
143
+ primitiveColorIndices: trial.primitive_color_indices,
130
144
  onTrialEnd: wrappedOnTrialEnd
131
145
  };
132
146
 
@@ -36,6 +36,8 @@ export interface StartPrepTrialParams {
36
36
  instructions?: string;
37
37
  onInteraction?: (event: any) => void;
38
38
  onTrialEnd?: (data: any) => void;
39
+ usePrimitiveColorsBlueprints?: boolean;
40
+ primitiveColorIndices?: number[];
39
41
  }
40
42
 
41
43
  /**
@@ -58,6 +60,8 @@ export function startPrepTrial(
58
60
  primitiveOrder,
59
61
  onInteraction,
60
62
  onTrialEnd,
63
+ usePrimitiveColorsBlueprints,
64
+ primitiveColorIndices,
61
65
  } = params;
62
66
 
63
67
  // Extract non-callback params for trial data
@@ -188,7 +192,9 @@ export function startPrepTrial(
188
192
  ...(params.instructions && { instructions: params.instructions }),
189
193
  onControllerReady: handleControllerReady,
190
194
  ...(onInteraction && { onInteraction }),
191
- ...(onTrialEnd && { onTrialEnd })
195
+ ...(onTrialEnd && { onTrialEnd }),
196
+ ...(usePrimitiveColorsBlueprints !== undefined && { usePrimitiveColorsBlueprints }),
197
+ ...(primitiveColorIndices !== undefined && { primitiveColorIndices })
192
198
  }));
193
199
 
194
200
  return { root, display_element, jsPsych };
@@ -62,6 +62,18 @@ const info = {
62
62
  onTrialEnd: {
63
63
  type: ParameterType.FUNCTION,
64
64
  default: undefined
65
+ },
66
+ /** Whether to use distinct colors for each primitive shape type in blueprints */
67
+ use_primitive_colors_blueprints: {
68
+ type: ParameterType.BOOL,
69
+ default: false,
70
+ description: "Whether each primitive shape type should have its own distinct color in the blueprint dock area"
71
+ },
72
+ /** Indices mapping primitives to colors from the color palette */
73
+ primitive_color_indices: {
74
+ type: ParameterType.OBJECT,
75
+ default: [0, 1, 2, 3, 4],
76
+ description: "Array of 5 integers indexing into primitiveColors array, mapping [square, smalltriangle, parallelogram, medtriangle, largetriangle] to colors"
65
77
  }
66
78
  },
67
79
  data: {
@@ -124,6 +136,8 @@ class TangramPrepPlugin implements JsPsychPlugin<Info> {
124
136
  instructions: trial.instructions,
125
137
  onInteraction: trial.onInteraction,
126
138
  onTrialEnd: wrappedOnTrialEnd,
139
+ usePrimitiveColorsBlueprints: trial.use_primitive_colors_blueprints,
140
+ primitiveColorIndices: trial.primitive_color_indices,
127
141
  };
128
142
 
129
143
  const { root, display_element: element, jsPsych } = startPrepTrial(display_element, params, this.jsPsych);