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
@@ -16675,30 +16675,41 @@ var TangramNBackPlugin = (function (jspsych) {
16675
16675
 
16676
16676
  const CONFIG = {
16677
16677
  color: {
16678
+ background: "#fff7e0ff",
16678
16679
  bands: {
16679
- silhouette: { fillEven: "#fff2ccff", fillOdd: "#fff2ccff", stroke: "#b1b1b1" },
16680
- workspace: { fillEven: "#fff2ccff", fillOdd: "#fff2ccff", stroke: "#b1b1b1" }
16680
+ silhouette: { fillEven: "#ffffff", fillOdd: "#ffffff", stroke: "#b1b1b1" },
16681
+ workspace: { fillEven: "#ffffff", fillOdd: "#ffffff", stroke: "#b1b1b1" }
16681
16682
  },
16682
- completion: { fill: "#ccfff2", stroke: "#13da57" },
16683
+ completion: { fill: "#ccffcc", stroke: "#13da57" },
16683
16684
  silhouetteMask: "#374151",
16684
16685
  anchors: { invalid: "#7dd3fc", valid: "#475569" },
16685
- piece: { draggingFill: "#8e7cc3ff", validFill: "#8e7cc3ff", invalidFill: "#ef4444", invalidStroke: "#dc2626", selectedStroke: "#674ea7", allGreenStroke: "#86efac", borderStroke: "#674ea7" },
16686
+ // validFill used here for placed composites
16687
+ piece: { draggingFill: "#8e7cc3", validFill: "#8e7cc3", invalidFill: "#d55c00", invalidStroke: "#dc2626", selectedStroke: "#674ea7", allGreenStroke: "#86efac", borderStroke: "#674ea7" },
16686
16688
  ui: { light: "#60a5fa", dark: "#1d4ed8" },
16687
16689
  blueprint: { fill: "#374151", selectedStroke: "#111827", badgeFill: "#000000", labelFill: "#ffffff" },
16688
- tangramDecomposition: { stroke: "#fef2cc" }
16690
+ tangramDecomposition: { stroke: "#fef2cc" },
16691
+ primitiveColors: [
16692
+ // from seaborn "colorblind" palette, 6 colors, with red omitted
16693
+ "#0173b2",
16694
+ "#de8f05",
16695
+ "#029e73",
16696
+ "#cc78bc",
16697
+ "#ca9161"
16698
+ ]
16689
16699
  },
16690
16700
  opacity: {
16691
- blueprint: 0.4,
16701
+ blueprint: 0.6,
16692
16702
  silhouetteMask: 0.25,
16693
16703
  //anchors: { valid: 0.80, invalid: 0.50 },
16694
16704
  anchors: { invalid: 0, valid: 0 },
16695
- piece: { invalid: 0.35, dragging: 0.75, locked: 1, normal: 1 }
16705
+ piece: { invalid: 1, dragging: 1, locked: 1, normal: 1 }
16696
16706
  },
16697
16707
  size: {
16698
- stroke: { bandPx: 5, pieceSelectedPx: 3, allGreenStrokePx: 10, pieceBorderPx: 2, tangramDecompositionPx: 1 },
16708
+ stroke: { bandPx: 5, pieceSelectedPx: 5, allGreenStrokePx: 10, pieceBorderPx: 2, tangramDecompositionPx: 1 },
16699
16709
  anchorRadiusPx: { valid: 1, invalid: 1 },
16700
16710
  badgeFontPx: 16,
16701
- centerBadge: { fractionOfOuterR: 0.15, minPx: 20, marginPx: 4 }
16711
+ centerBadge: { fractionOfOuterR: 0.15, minPx: 20, marginPx: 4 },
16712
+ invalidMarker: { sizePx: 10, strokePx: 4 }
16702
16713
  },
16703
16714
  layout: {
16704
16715
  grid: { stepPx: 20, unitPx: 40 },
@@ -16716,7 +16727,8 @@ var TangramNBackPlugin = (function (jspsych) {
16716
16727
  game: {
16717
16728
  snapRadiusPx: 15,
16718
16729
  showBorders: false,
16719
- hideTouchingBorders: true
16730
+ hideTouchingBorders: true,
16731
+ silhouettesBelowPieces: true
16720
16732
  }
16721
16733
  };
16722
16734
 
@@ -16768,6 +16780,8 @@ var TangramNBackPlugin = (function (jspsych) {
16768
16780
  instructions,
16769
16781
  button_text,
16770
16782
  duration,
16783
+ usePrimitiveColors,
16784
+ primitiveColorIndices,
16771
16785
  onTrialEnd
16772
16786
  } = params;
16773
16787
  const trialStartTime = reactExports.useRef(Date.now());
@@ -16823,7 +16837,12 @@ var TangramNBackPlugin = (function (jspsych) {
16823
16837
  ...data,
16824
16838
  accuracy,
16825
16839
  tangram_id: tangram.tangramID,
16826
- is_match: isMatch
16840
+ is_match: isMatch,
16841
+ show_tangram_decomposition,
16842
+ use_primitive_colors: usePrimitiveColors,
16843
+ primitive_color_indices: primitiveColorIndices,
16844
+ duration,
16845
+ button_text
16827
16846
  };
16828
16847
  if (onTrialEnd) {
16829
16848
  onTrialEnd(trialData);
@@ -16877,35 +16896,77 @@ var TangramNBackPlugin = (function (jspsych) {
16877
16896
  if (show_tangram_decomposition) {
16878
16897
  const rawPolys = primitiveDecomposition.map((primInfo) => primInfo.polygon);
16879
16898
  const placedPolys = placeSilhouetteGridAlignedAsPolys(rawPolys, scaleS, centerPos);
16880
- return /* @__PURE__ */ React.createElement("g", { key: "sil-decomposed", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => /* @__PURE__ */ React.createElement(React.Fragment, { key: `prim-${i}` }, /* @__PURE__ */ React.createElement(
16881
- "path",
16882
- {
16883
- d: pathD(scaledPoly),
16884
- fill: CONFIG.color.silhouetteMask,
16885
- opacity: CONFIG.opacity.silhouetteMask,
16886
- stroke: "none"
16899
+ return /* @__PURE__ */ React.createElement("g", { key: "sil-decomposed", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => {
16900
+ const primInfo = primitiveDecomposition[i];
16901
+ let fillColor = CONFIG.color.silhouetteMask;
16902
+ if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
16903
+ const kindToIndex = {
16904
+ "square": 0,
16905
+ "smalltriangle": 1,
16906
+ "parallelogram": 2,
16907
+ "medtriangle": 3,
16908
+ "largetriangle": 4
16909
+ };
16910
+ const primitiveIndex = kindToIndex[primInfo.kind];
16911
+ if (primitiveIndex !== void 0 && primitiveColorIndices[primitiveIndex] !== void 0) {
16912
+ const colorIndex = primitiveColorIndices[primitiveIndex];
16913
+ const color = CONFIG.color.primitiveColors[colorIndex];
16914
+ if (color) {
16915
+ fillColor = color;
16916
+ }
16917
+ }
16887
16918
  }
16888
- ), /* @__PURE__ */ React.createElement(
16889
- "path",
16890
- {
16891
- d: pathD(scaledPoly),
16892
- fill: "none",
16893
- stroke: CONFIG.color.tangramDecomposition.stroke,
16894
- strokeWidth: CONFIG.size.stroke.tangramDecompositionPx
16895
- }
16896
- ))));
16919
+ return /* @__PURE__ */ React.createElement(React.Fragment, { key: `prim-${i}` }, /* @__PURE__ */ React.createElement(
16920
+ "path",
16921
+ {
16922
+ d: pathD(scaledPoly),
16923
+ fill: fillColor,
16924
+ opacity: CONFIG.opacity.silhouetteMask,
16925
+ stroke: "none"
16926
+ }
16927
+ ), /* @__PURE__ */ React.createElement(
16928
+ "path",
16929
+ {
16930
+ d: pathD(scaledPoly),
16931
+ fill: "none",
16932
+ stroke: CONFIG.color.tangramDecomposition.stroke,
16933
+ strokeWidth: CONFIG.size.stroke.tangramDecompositionPx
16934
+ }
16935
+ ));
16936
+ }));
16897
16937
  } else {
16898
16938
  const placedPolys = placeSilhouetteGridAlignedAsPolys(mask, scaleS, centerPos);
16899
- return /* @__PURE__ */ React.createElement("g", { key: "sil-unified", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => /* @__PURE__ */ React.createElement(
16900
- "path",
16901
- {
16902
- key: `sil-${i}`,
16903
- d: pathD(scaledPoly),
16904
- fill: CONFIG.color.silhouetteMask,
16905
- opacity: CONFIG.opacity.silhouetteMask,
16906
- stroke: "none"
16939
+ return /* @__PURE__ */ React.createElement("g", { key: "sil-unified", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => {
16940
+ const primInfo = primitiveDecomposition[i];
16941
+ let fillColor = CONFIG.color.silhouetteMask;
16942
+ if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
16943
+ const kindToIndex = {
16944
+ "square": 0,
16945
+ "smalltriangle": 1,
16946
+ "parallelogram": 2,
16947
+ "medtriangle": 3,
16948
+ "largetriangle": 4
16949
+ };
16950
+ const primitiveIndex = kindToIndex[primInfo.kind];
16951
+ if (primitiveIndex !== void 0 && primitiveColorIndices[primitiveIndex] !== void 0) {
16952
+ const colorIndex = primitiveColorIndices[primitiveIndex];
16953
+ const color = CONFIG.color.primitiveColors[colorIndex];
16954
+ if (color) {
16955
+ fillColor = color;
16956
+ }
16957
+ }
16907
16958
  }
16908
- )));
16959
+ return /* @__PURE__ */ React.createElement(
16960
+ "path",
16961
+ {
16962
+ key: `sil-${i}`,
16963
+ d: pathD(scaledPoly),
16964
+ fill: fillColor,
16965
+ opacity: CONFIG.opacity.silhouetteMask,
16966
+ stroke: "none"
16967
+ }
16968
+ );
16969
+ }));
16909
16970
  }
16910
16971
  };
16911
16972
  return /* @__PURE__ */ React.createElement("div", { style: {
@@ -16914,7 +16975,7 @@ var TangramNBackPlugin = (function (jspsych) {
16914
16975
  alignItems: "center",
16915
16976
  justifyContent: "center",
16916
16977
  padding: "20px",
16917
- background: "#f5f5f5"
16978
+ background: "#fff7e0ff"
16918
16979
  } }, instructions && /* @__PURE__ */ React.createElement(
16919
16980
  "div",
16920
16981
  {
@@ -17004,6 +17065,18 @@ var TangramNBackPlugin = (function (jspsych) {
17004
17065
  default: 3e3,
17005
17066
  description: "Duration in milliseconds to display tangram and accept responses"
17006
17067
  },
17068
+ /** Whether to use distinct colors for each primitive shape type */
17069
+ use_primitive_colors: {
17070
+ type: jspsych.ParameterType.BOOL,
17071
+ default: false,
17072
+ description: "Whether each primitive shape type should have its own distinct color in the displayed tangram"
17073
+ },
17074
+ /** Indices mapping primitives to colors from the color palette */
17075
+ primitive_color_indices: {
17076
+ type: jspsych.ParameterType.OBJECT,
17077
+ default: [0, 1, 2, 3, 4],
17078
+ description: "Array of 5 integers indexing into primitiveColors array, mapping [square, smalltriangle, parallelogram, medtriangle, largetriangle] to colors"
17079
+ },
17007
17080
  /** Callback fired when trial ends */
17008
17081
  onTrialEnd: {
17009
17082
  type: jspsych.ParameterType.FUNCTION,
@@ -17070,6 +17143,8 @@ var TangramNBackPlugin = (function (jspsych) {
17070
17143
  instructions: trial.instructions,
17071
17144
  button_text: trial.button_text,
17072
17145
  duration: trial.duration,
17146
+ usePrimitiveColors: trial.use_primitive_colors,
17147
+ primitiveColorIndices: trial.primitive_color_indices,
17073
17148
  onTrialEnd: wrappedOnTrialEnd
17074
17149
  };
17075
17150
  const { root, display_element: element, jsPsych } = startNBackTrial(display_element, params, this.jsPsych);