jspsych-tangram 0.0.13 → 0.0.15
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.
- package/dist/afc/index.browser.js +17751 -0
- package/dist/afc/index.browser.js.map +1 -0
- package/dist/afc/index.browser.min.js +42 -0
- package/dist/afc/index.browser.min.js.map +1 -0
- package/dist/afc/index.cjs +443 -0
- package/dist/afc/index.cjs.map +1 -0
- package/dist/afc/index.d.ts +169 -0
- package/dist/afc/index.js +441 -0
- package/dist/afc/index.js.map +1 -0
- package/dist/construct/index.browser.js +8 -2
- package/dist/construct/index.browser.js.map +1 -1
- package/dist/construct/index.browser.min.js +10 -10
- package/dist/construct/index.browser.min.js.map +1 -1
- package/dist/construct/index.cjs +8 -2
- package/dist/construct/index.cjs.map +1 -1
- package/dist/construct/index.js +8 -2
- package/dist/construct/index.js.map +1 -1
- package/dist/index.cjs +379 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +178 -12
- package/dist/index.js +379 -12
- package/dist/index.js.map +1 -1
- package/dist/nback/index.browser.js +6 -4
- package/dist/nback/index.browser.js.map +1 -1
- package/dist/nback/index.browser.min.js +8 -8
- package/dist/nback/index.browser.min.js.map +1 -1
- package/dist/nback/index.cjs +6 -4
- package/dist/nback/index.cjs.map +1 -1
- package/dist/nback/index.js +6 -4
- package/dist/nback/index.js.map +1 -1
- package/dist/prep/index.browser.js +8 -2
- package/dist/prep/index.browser.js.map +1 -1
- package/dist/prep/index.browser.min.js +10 -10
- package/dist/prep/index.browser.min.js.map +1 -1
- package/dist/prep/index.cjs +8 -2
- package/dist/prep/index.cjs.map +1 -1
- package/dist/prep/index.js +8 -2
- package/dist/prep/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/components/board/GameBoard.tsx +13 -42
- package/src/core/components/board/useGameBoard.ts +52 -0
- package/src/core/components/index.ts +4 -2
- package/src/core/components/pieces/BlueprintRing.tsx +0 -25
- package/src/core/components/pieces/useBlueprintRing.ts +39 -0
- package/src/index.ts +2 -1
- package/src/plugins/tangram-afc/AFCApp.tsx +341 -0
- package/src/plugins/tangram-afc/index.ts +140 -0
- package/src/plugins/tangram-nback/NBackApp.tsx +3 -3
- package/tangram-construct.min.js +10 -10
- package/tangram-nback.min.js +8 -8
- package/tangram-prep.min.js +10 -10
package/dist/index.js
CHANGED
|
@@ -3474,14 +3474,20 @@ function GameBoard(props) {
|
|
|
3474
3474
|
lineHeight: 1.5,
|
|
3475
3475
|
textAlign: "center"
|
|
3476
3476
|
};
|
|
3477
|
+
const scaleX = svgDimensions.width / viewBox.w;
|
|
3478
|
+
const rightEdgeOfSemicircleLogical = viewBox.w / 2 + layout.outerR;
|
|
3479
|
+
const distanceFromRightEdgeLogical = viewBox.w - rightEdgeOfSemicircleLogical;
|
|
3480
|
+
const distanceFromRightEdgePx = distanceFromRightEdgeLogical * scaleX;
|
|
3481
|
+
const charWidth = 24 * 0.6;
|
|
3482
|
+
const offsetLeft = charWidth * 5;
|
|
3477
3483
|
const timerStyle = {
|
|
3478
3484
|
position: "absolute",
|
|
3479
|
-
right:
|
|
3485
|
+
right: `${distanceFromRightEdgePx + offsetLeft}px`,
|
|
3480
3486
|
fontSize: "24px",
|
|
3481
3487
|
fontWeight: "bold",
|
|
3482
3488
|
fontFamily: "monospace",
|
|
3483
3489
|
color: "#333",
|
|
3484
|
-
|
|
3490
|
+
whiteSpace: "nowrap",
|
|
3485
3491
|
textAlign: "right"
|
|
3486
3492
|
};
|
|
3487
3493
|
const gameboardWrapperStyle = {
|
|
@@ -3758,7 +3764,7 @@ function startConstructionTrial(display_element, params, _jsPsych) {
|
|
|
3758
3764
|
return { root, display_element, jsPsych: _jsPsych };
|
|
3759
3765
|
}
|
|
3760
3766
|
|
|
3761
|
-
const info$
|
|
3767
|
+
const info$3 = {
|
|
3762
3768
|
name: "tangram-construct",
|
|
3763
3769
|
version: "1.0.0",
|
|
3764
3770
|
parameters: {
|
|
@@ -3890,7 +3896,7 @@ class TangramConstructPlugin {
|
|
|
3890
3896
|
this.jsPsych = jsPsych;
|
|
3891
3897
|
}
|
|
3892
3898
|
static {
|
|
3893
|
-
this.info = info$
|
|
3899
|
+
this.info = info$3;
|
|
3894
3900
|
}
|
|
3895
3901
|
/**
|
|
3896
3902
|
* Launches the trial by invoking startConstructionTrial
|
|
@@ -4041,7 +4047,7 @@ function startPrepTrial(display_element, params, jsPsych) {
|
|
|
4041
4047
|
return { root, display_element, jsPsych };
|
|
4042
4048
|
}
|
|
4043
4049
|
|
|
4044
|
-
const info$
|
|
4050
|
+
const info$2 = {
|
|
4045
4051
|
name: "tangram-prep",
|
|
4046
4052
|
version: "1.0.0",
|
|
4047
4053
|
parameters: {
|
|
@@ -4129,7 +4135,7 @@ class TangramPrepPlugin {
|
|
|
4129
4135
|
this.jsPsych = jsPsych;
|
|
4130
4136
|
}
|
|
4131
4137
|
static {
|
|
4132
|
-
this.info = info$
|
|
4138
|
+
this.info = info$2;
|
|
4133
4139
|
}
|
|
4134
4140
|
/**
|
|
4135
4141
|
* Launches the trial by invoking startPrepTrial
|
|
@@ -4321,7 +4327,7 @@ function NBackView({ params }) {
|
|
|
4321
4327
|
{
|
|
4322
4328
|
d: pathD(scaledPoly),
|
|
4323
4329
|
fill: fillColor,
|
|
4324
|
-
opacity: CONFIG.opacity.silhouetteMask,
|
|
4330
|
+
opacity: usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask,
|
|
4325
4331
|
stroke: "none"
|
|
4326
4332
|
}
|
|
4327
4333
|
), /* @__PURE__ */ React.createElement(
|
|
@@ -4362,7 +4368,7 @@ function NBackView({ params }) {
|
|
|
4362
4368
|
key: `sil-${i}`,
|
|
4363
4369
|
d: pathD(scaledPoly),
|
|
4364
4370
|
fill: fillColor,
|
|
4365
|
-
opacity: CONFIG.opacity.silhouetteMask,
|
|
4371
|
+
opacity: usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask,
|
|
4366
4372
|
stroke: "none"
|
|
4367
4373
|
}
|
|
4368
4374
|
);
|
|
@@ -4375,7 +4381,7 @@ function NBackView({ params }) {
|
|
|
4375
4381
|
alignItems: "center",
|
|
4376
4382
|
justifyContent: "center",
|
|
4377
4383
|
padding: "20px",
|
|
4378
|
-
background: "#
|
|
4384
|
+
background: "#fff7e0ff"
|
|
4379
4385
|
} }, instructions && /* @__PURE__ */ React.createElement(
|
|
4380
4386
|
"div",
|
|
4381
4387
|
{
|
|
@@ -4425,7 +4431,7 @@ function NBackView({ params }) {
|
|
|
4425
4431
|
)));
|
|
4426
4432
|
}
|
|
4427
4433
|
|
|
4428
|
-
const info = {
|
|
4434
|
+
const info$1 = {
|
|
4429
4435
|
name: "tangram-nback",
|
|
4430
4436
|
version: "1.0.0",
|
|
4431
4437
|
parameters: {
|
|
@@ -4518,7 +4524,7 @@ class TangramNBackPlugin {
|
|
|
4518
4524
|
this.jsPsych = jsPsych;
|
|
4519
4525
|
}
|
|
4520
4526
|
static {
|
|
4521
|
-
this.info = info;
|
|
4527
|
+
this.info = info$1;
|
|
4522
4528
|
}
|
|
4523
4529
|
/**
|
|
4524
4530
|
* Launches the trial by invoking startNBackTrial
|
|
@@ -4552,5 +4558,366 @@ class TangramNBackPlugin {
|
|
|
4552
4558
|
}
|
|
4553
4559
|
}
|
|
4554
4560
|
|
|
4555
|
-
|
|
4561
|
+
function startAFCTrial(display_element, params, _jsPsych) {
|
|
4562
|
+
const root = createRoot(display_element);
|
|
4563
|
+
root.render(React.createElement(AFCView, { params }));
|
|
4564
|
+
return { root, display_element, jsPsych: _jsPsych };
|
|
4565
|
+
}
|
|
4566
|
+
function AFCView({ params }) {
|
|
4567
|
+
const {
|
|
4568
|
+
tangramLeft,
|
|
4569
|
+
tangramRight,
|
|
4570
|
+
instructions,
|
|
4571
|
+
buttonTextLeft,
|
|
4572
|
+
buttonTextRight,
|
|
4573
|
+
showTangramDecomposition,
|
|
4574
|
+
usePrimitiveColors,
|
|
4575
|
+
primitiveColorIndices,
|
|
4576
|
+
onTrialEnd
|
|
4577
|
+
} = params;
|
|
4578
|
+
const trialStartTime = useRef(Date.now());
|
|
4579
|
+
const [hasResponded, setHasResponded] = useState(false);
|
|
4580
|
+
const handleResponse = (choice) => {
|
|
4581
|
+
if (hasResponded) return;
|
|
4582
|
+
setHasResponded(true);
|
|
4583
|
+
const rt = Date.now() - trialStartTime.current;
|
|
4584
|
+
if (onTrialEnd) {
|
|
4585
|
+
onTrialEnd({
|
|
4586
|
+
rt,
|
|
4587
|
+
response: choice,
|
|
4588
|
+
show_tangram_decomposition: showTangramDecomposition,
|
|
4589
|
+
use_primitive_colors: usePrimitiveColors,
|
|
4590
|
+
primitive_color_indices: primitiveColorIndices,
|
|
4591
|
+
button_text_left: buttonTextLeft,
|
|
4592
|
+
button_text_right: buttonTextRight
|
|
4593
|
+
});
|
|
4594
|
+
}
|
|
4595
|
+
};
|
|
4596
|
+
return /* @__PURE__ */ React.createElement("div", { style: {
|
|
4597
|
+
display: "flex",
|
|
4598
|
+
flexDirection: "column",
|
|
4599
|
+
alignItems: "center",
|
|
4600
|
+
justifyContent: "center",
|
|
4601
|
+
padding: "20px",
|
|
4602
|
+
background: "#fff7e0ff",
|
|
4603
|
+
minHeight: "100vh"
|
|
4604
|
+
} }, instructions && /* @__PURE__ */ React.createElement(
|
|
4605
|
+
"div",
|
|
4606
|
+
{
|
|
4607
|
+
style: {
|
|
4608
|
+
maxWidth: "800px",
|
|
4609
|
+
width: "100%",
|
|
4610
|
+
marginBottom: "30px",
|
|
4611
|
+
textAlign: "center",
|
|
4612
|
+
fontSize: "18px",
|
|
4613
|
+
lineHeight: "1.5"
|
|
4614
|
+
},
|
|
4615
|
+
dangerouslySetInnerHTML: { __html: instructions }
|
|
4616
|
+
}
|
|
4617
|
+
), /* @__PURE__ */ React.createElement("div", { style: {
|
|
4618
|
+
display: "flex",
|
|
4619
|
+
flexDirection: "row",
|
|
4620
|
+
gap: "50px",
|
|
4621
|
+
justifyContent: "center",
|
|
4622
|
+
alignItems: "flex-start",
|
|
4623
|
+
flexWrap: "wrap"
|
|
4624
|
+
} }, /* @__PURE__ */ React.createElement(
|
|
4625
|
+
TangramOption,
|
|
4626
|
+
{
|
|
4627
|
+
tangram: tangramLeft,
|
|
4628
|
+
buttonText: buttonTextLeft,
|
|
4629
|
+
onClick: () => handleResponse("left"),
|
|
4630
|
+
disabled: hasResponded,
|
|
4631
|
+
showDecomposition: showTangramDecomposition,
|
|
4632
|
+
usePrimitiveColors,
|
|
4633
|
+
primitiveColorIndices
|
|
4634
|
+
}
|
|
4635
|
+
), /* @__PURE__ */ React.createElement(
|
|
4636
|
+
TangramOption,
|
|
4637
|
+
{
|
|
4638
|
+
tangram: tangramRight,
|
|
4639
|
+
buttonText: buttonTextRight,
|
|
4640
|
+
onClick: () => handleResponse("right"),
|
|
4641
|
+
disabled: hasResponded,
|
|
4642
|
+
showDecomposition: showTangramDecomposition,
|
|
4643
|
+
usePrimitiveColors,
|
|
4644
|
+
primitiveColorIndices
|
|
4645
|
+
}
|
|
4646
|
+
)));
|
|
4647
|
+
}
|
|
4648
|
+
function TangramOption({
|
|
4649
|
+
tangram,
|
|
4650
|
+
buttonText,
|
|
4651
|
+
onClick,
|
|
4652
|
+
disabled,
|
|
4653
|
+
showDecomposition,
|
|
4654
|
+
usePrimitiveColors,
|
|
4655
|
+
primitiveColorIndices
|
|
4656
|
+
}) {
|
|
4657
|
+
if (!tangram) {
|
|
4658
|
+
return /* @__PURE__ */ React.createElement("div", { style: { width: 300, height: 300, background: "#eee" } }, "No Tangram Data");
|
|
4659
|
+
}
|
|
4660
|
+
const CANON = /* @__PURE__ */ new Set([
|
|
4661
|
+
"square",
|
|
4662
|
+
"smalltriangle",
|
|
4663
|
+
"parallelogram",
|
|
4664
|
+
"medtriangle",
|
|
4665
|
+
"largetriangle"
|
|
4666
|
+
]);
|
|
4667
|
+
const filteredTans = tangram.solutionTans.filter((tan) => {
|
|
4668
|
+
const tanName = tan.name ?? tan.kind;
|
|
4669
|
+
return CANON.has(tanName);
|
|
4670
|
+
});
|
|
4671
|
+
const mask = filteredTans.map((tan) => {
|
|
4672
|
+
const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
|
|
4673
|
+
return polygon;
|
|
4674
|
+
});
|
|
4675
|
+
const primitiveDecomposition = filteredTans.map((tan) => ({
|
|
4676
|
+
kind: tan.name ?? tan.kind,
|
|
4677
|
+
polygon: tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }))
|
|
4678
|
+
}));
|
|
4679
|
+
const DISPLAY_SIZE = 300;
|
|
4680
|
+
const viewport = {
|
|
4681
|
+
w: DISPLAY_SIZE,
|
|
4682
|
+
h: DISPLAY_SIZE
|
|
4683
|
+
};
|
|
4684
|
+
const scaleS = React.useMemo(() => {
|
|
4685
|
+
const u = inferUnitFromPolys$1(mask);
|
|
4686
|
+
return u ? CONFIG.layout.grid.unitPx / u : 1;
|
|
4687
|
+
}, [mask]);
|
|
4688
|
+
const centerPos = {
|
|
4689
|
+
cx: viewport.w / 2,
|
|
4690
|
+
cy: viewport.h / 2
|
|
4691
|
+
};
|
|
4692
|
+
const pathD = (poly) => {
|
|
4693
|
+
if (!poly || poly.length === 0) return "";
|
|
4694
|
+
const moves = poly.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`);
|
|
4695
|
+
return moves.join(" ") + " Z";
|
|
4696
|
+
};
|
|
4697
|
+
const renderSilhouette = () => {
|
|
4698
|
+
if (showDecomposition) {
|
|
4699
|
+
const rawPolys = primitiveDecomposition.map((primInfo) => primInfo.polygon);
|
|
4700
|
+
const placedPolys = placeSilhouetteGridAlignedAsPolys(rawPolys, scaleS, centerPos);
|
|
4701
|
+
return /* @__PURE__ */ React.createElement("g", { key: "sil-decomposed", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => {
|
|
4702
|
+
const primInfo = primitiveDecomposition[i];
|
|
4703
|
+
let fillColor = CONFIG.color.silhouetteMask;
|
|
4704
|
+
if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
|
|
4705
|
+
const kindToIndex = {
|
|
4706
|
+
"square": 0,
|
|
4707
|
+
"smalltriangle": 1,
|
|
4708
|
+
"parallelogram": 2,
|
|
4709
|
+
"medtriangle": 3,
|
|
4710
|
+
"largetriangle": 4
|
|
4711
|
+
};
|
|
4712
|
+
const primitiveIndex = kindToIndex[primInfo.kind];
|
|
4713
|
+
if (primitiveIndex !== void 0 && primitiveColorIndices[primitiveIndex] !== void 0) {
|
|
4714
|
+
const colorIndex = primitiveColorIndices[primitiveIndex];
|
|
4715
|
+
const color = CONFIG.color.primitiveColors[colorIndex];
|
|
4716
|
+
if (color) {
|
|
4717
|
+
fillColor = color;
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4720
|
+
}
|
|
4721
|
+
return /* @__PURE__ */ React.createElement(React.Fragment, { key: `prim-${i}` }, /* @__PURE__ */ React.createElement(
|
|
4722
|
+
"path",
|
|
4723
|
+
{
|
|
4724
|
+
d: pathD(scaledPoly),
|
|
4725
|
+
fill: fillColor,
|
|
4726
|
+
opacity: usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask,
|
|
4727
|
+
stroke: "none"
|
|
4728
|
+
}
|
|
4729
|
+
), /* @__PURE__ */ React.createElement(
|
|
4730
|
+
"path",
|
|
4731
|
+
{
|
|
4732
|
+
d: pathD(scaledPoly),
|
|
4733
|
+
fill: "none",
|
|
4734
|
+
stroke: CONFIG.color.tangramDecomposition.stroke,
|
|
4735
|
+
strokeWidth: CONFIG.size.stroke.tangramDecompositionPx
|
|
4736
|
+
}
|
|
4737
|
+
));
|
|
4738
|
+
}));
|
|
4739
|
+
} else {
|
|
4740
|
+
const placedPolys = placeSilhouetteGridAlignedAsPolys(mask, scaleS, centerPos);
|
|
4741
|
+
return /* @__PURE__ */ React.createElement("g", { key: "sil-unified", pointerEvents: "none" }, placedPolys.map((scaledPoly, i) => {
|
|
4742
|
+
const primInfo = primitiveDecomposition[i];
|
|
4743
|
+
let fillColor = CONFIG.color.silhouetteMask;
|
|
4744
|
+
if (usePrimitiveColors && primInfo?.kind && primitiveColorIndices) {
|
|
4745
|
+
const kindToIndex = {
|
|
4746
|
+
"square": 0,
|
|
4747
|
+
"smalltriangle": 1,
|
|
4748
|
+
"parallelogram": 2,
|
|
4749
|
+
"medtriangle": 3,
|
|
4750
|
+
"largetriangle": 4
|
|
4751
|
+
};
|
|
4752
|
+
const primitiveIndex = kindToIndex[primInfo.kind];
|
|
4753
|
+
if (primitiveIndex !== void 0 && primitiveColorIndices[primitiveIndex] !== void 0) {
|
|
4754
|
+
const colorIndex = primitiveColorIndices[primitiveIndex];
|
|
4755
|
+
const color = CONFIG.color.primitiveColors[colorIndex];
|
|
4756
|
+
if (color) {
|
|
4757
|
+
fillColor = color;
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
}
|
|
4761
|
+
return /* @__PURE__ */ React.createElement(
|
|
4762
|
+
"path",
|
|
4763
|
+
{
|
|
4764
|
+
key: `sil-${i}`,
|
|
4765
|
+
d: pathD(scaledPoly),
|
|
4766
|
+
fill: fillColor,
|
|
4767
|
+
opacity: usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask,
|
|
4768
|
+
stroke: "none"
|
|
4769
|
+
}
|
|
4770
|
+
);
|
|
4771
|
+
}));
|
|
4772
|
+
}
|
|
4773
|
+
};
|
|
4774
|
+
return /* @__PURE__ */ React.createElement("div", { style: {
|
|
4775
|
+
display: "flex",
|
|
4776
|
+
flexDirection: "column",
|
|
4777
|
+
alignItems: "center",
|
|
4778
|
+
gap: "20px"
|
|
4779
|
+
} }, /* @__PURE__ */ React.createElement(
|
|
4780
|
+
"svg",
|
|
4781
|
+
{
|
|
4782
|
+
width: viewport.w,
|
|
4783
|
+
height: viewport.h,
|
|
4784
|
+
viewBox: `0 0 ${viewport.w} ${viewport.h}`,
|
|
4785
|
+
style: {
|
|
4786
|
+
display: "block",
|
|
4787
|
+
background: CONFIG.color.bands.silhouette.fillEven,
|
|
4788
|
+
border: `${CONFIG.size.stroke.bandPx}px solid ${CONFIG.color.bands.silhouette.stroke}`,
|
|
4789
|
+
borderRadius: "8px"
|
|
4790
|
+
}
|
|
4791
|
+
},
|
|
4792
|
+
renderSilhouette()
|
|
4793
|
+
), /* @__PURE__ */ React.createElement(
|
|
4794
|
+
"button",
|
|
4795
|
+
{
|
|
4796
|
+
className: "jspsych-btn",
|
|
4797
|
+
onClick,
|
|
4798
|
+
disabled,
|
|
4799
|
+
style: {
|
|
4800
|
+
padding: "12px 30px",
|
|
4801
|
+
fontSize: "16px",
|
|
4802
|
+
cursor: disabled ? "not-allowed" : "pointer",
|
|
4803
|
+
opacity: disabled ? 0.5 : 1
|
|
4804
|
+
}
|
|
4805
|
+
},
|
|
4806
|
+
buttonText
|
|
4807
|
+
));
|
|
4808
|
+
}
|
|
4809
|
+
|
|
4810
|
+
const info = {
|
|
4811
|
+
name: "tangram-afc",
|
|
4812
|
+
version: "1.0.0",
|
|
4813
|
+
parameters: {
|
|
4814
|
+
/** Left tangram specification to display */
|
|
4815
|
+
tangram_left: {
|
|
4816
|
+
type: ParameterType.COMPLEX,
|
|
4817
|
+
default: void 0,
|
|
4818
|
+
description: "TangramSpec object defining left target shape to display"
|
|
4819
|
+
},
|
|
4820
|
+
/** Right tangram specification to display */
|
|
4821
|
+
tangram_right: {
|
|
4822
|
+
type: ParameterType.COMPLEX,
|
|
4823
|
+
default: void 0,
|
|
4824
|
+
description: "TangramSpec object defining right target shape to display"
|
|
4825
|
+
},
|
|
4826
|
+
/** HTML content to display above the tangrams as instructions */
|
|
4827
|
+
instructions: {
|
|
4828
|
+
type: ParameterType.STRING,
|
|
4829
|
+
default: "",
|
|
4830
|
+
description: "HTML content to display above the tangrams as instructions"
|
|
4831
|
+
},
|
|
4832
|
+
/** Text to display on left response button */
|
|
4833
|
+
button_text_left: {
|
|
4834
|
+
type: ParameterType.STRING,
|
|
4835
|
+
default: "Select Left",
|
|
4836
|
+
description: "Text to display on left response button"
|
|
4837
|
+
},
|
|
4838
|
+
/** Text to display on right response button */
|
|
4839
|
+
button_text_right: {
|
|
4840
|
+
type: ParameterType.STRING,
|
|
4841
|
+
default: "Select Right",
|
|
4842
|
+
description: "Text to display on right response button"
|
|
4843
|
+
},
|
|
4844
|
+
/** Whether to show tangram decomposed into individual primitives with borders */
|
|
4845
|
+
show_tangram_decomposition: {
|
|
4846
|
+
type: ParameterType.BOOL,
|
|
4847
|
+
default: false,
|
|
4848
|
+
description: "Whether to show tangram decomposed into individual primitives with borders"
|
|
4849
|
+
},
|
|
4850
|
+
/** Whether to use distinct colors for each primitive shape type */
|
|
4851
|
+
use_primitive_colors: {
|
|
4852
|
+
type: ParameterType.BOOL,
|
|
4853
|
+
default: false,
|
|
4854
|
+
description: "Whether each primitive shape type should have its own distinct color in the displayed tangram"
|
|
4855
|
+
},
|
|
4856
|
+
/** Indices mapping primitives to colors from the color palette */
|
|
4857
|
+
primitive_color_indices: {
|
|
4858
|
+
type: ParameterType.OBJECT,
|
|
4859
|
+
default: [0, 1, 2, 3, 4],
|
|
4860
|
+
description: "Array of 5 integers indexing into primitiveColors array, mapping [square, smalltriangle, parallelogram, medtriangle, largetriangle] to colors"
|
|
4861
|
+
},
|
|
4862
|
+
/** Callback fired when trial ends */
|
|
4863
|
+
onTrialEnd: {
|
|
4864
|
+
type: ParameterType.FUNCTION,
|
|
4865
|
+
default: void 0,
|
|
4866
|
+
description: "Callback when trial completes with full data"
|
|
4867
|
+
}
|
|
4868
|
+
},
|
|
4869
|
+
data: {
|
|
4870
|
+
/** Reaction time in milliseconds */
|
|
4871
|
+
rt: {
|
|
4872
|
+
type: ParameterType.INT,
|
|
4873
|
+
description: "Milliseconds between trial start and button click"
|
|
4874
|
+
},
|
|
4875
|
+
/** Response choice */
|
|
4876
|
+
response: {
|
|
4877
|
+
type: ParameterType.STRING,
|
|
4878
|
+
description: "Which button was clicked: 'left' or 'right'"
|
|
4879
|
+
}
|
|
4880
|
+
},
|
|
4881
|
+
citations: ""
|
|
4882
|
+
};
|
|
4883
|
+
class TangramAFCPlugin {
|
|
4884
|
+
constructor(jsPsych) {
|
|
4885
|
+
this.jsPsych = jsPsych;
|
|
4886
|
+
}
|
|
4887
|
+
static {
|
|
4888
|
+
this.info = info;
|
|
4889
|
+
}
|
|
4890
|
+
/**
|
|
4891
|
+
* Launches the trial by invoking startAFCTrial
|
|
4892
|
+
* with the display element, parameters, and jsPsych instance.
|
|
4893
|
+
*/
|
|
4894
|
+
trial(display_element, trial) {
|
|
4895
|
+
const wrappedOnTrialEnd = (data) => {
|
|
4896
|
+
if (trial.onTrialEnd) {
|
|
4897
|
+
trial.onTrialEnd(data);
|
|
4898
|
+
}
|
|
4899
|
+
const reactContext = display_element.__reactContext;
|
|
4900
|
+
if (reactContext?.root) {
|
|
4901
|
+
reactContext.root.unmount();
|
|
4902
|
+
}
|
|
4903
|
+
display_element.innerHTML = "";
|
|
4904
|
+
this.jsPsych.finishTrial(data);
|
|
4905
|
+
};
|
|
4906
|
+
const params = {
|
|
4907
|
+
tangramLeft: trial.tangram_left,
|
|
4908
|
+
tangramRight: trial.tangram_right,
|
|
4909
|
+
instructions: trial.instructions,
|
|
4910
|
+
buttonTextLeft: trial.button_text_left,
|
|
4911
|
+
buttonTextRight: trial.button_text_right,
|
|
4912
|
+
showTangramDecomposition: trial.show_tangram_decomposition,
|
|
4913
|
+
usePrimitiveColors: trial.use_primitive_colors,
|
|
4914
|
+
primitiveColorIndices: trial.primitive_color_indices,
|
|
4915
|
+
onTrialEnd: wrappedOnTrialEnd
|
|
4916
|
+
};
|
|
4917
|
+
const { root, display_element: element, jsPsych } = startAFCTrial(display_element, params, this.jsPsych);
|
|
4918
|
+
element.__reactContext = { root, jsPsych };
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
|
|
4922
|
+
export { TangramAFCPlugin, TangramConstructPlugin, TangramNBackPlugin, TangramPrepPlugin };
|
|
4556
4923
|
//# sourceMappingURL=index.js.map
|