jspsych-tangram 0.0.3 → 0.0.5
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/construct/index.browser.js +23 -63
- package/dist/construct/index.browser.js.map +1 -1
- package/dist/construct/index.browser.min.js +11 -15
- package/dist/construct/index.browser.min.js.map +1 -1
- package/dist/construct/index.cjs +23 -63
- package/dist/construct/index.cjs.map +1 -1
- package/dist/construct/index.js +23 -63
- package/dist/construct/index.js.map +1 -1
- package/dist/index.cjs +26 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +26 -64
- package/dist/index.js.map +1 -1
- package/dist/prep/index.browser.js +16 -14
- package/dist/prep/index.browser.js.map +1 -1
- package/dist/prep/index.browser.min.js +1 -1
- package/dist/prep/index.browser.min.js.map +1 -1
- package/dist/prep/index.cjs +16 -14
- package/dist/prep/index.cjs.map +1 -1
- package/dist/prep/index.js +16 -14
- package/dist/prep/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/components/board/GameBoard.tsx +4 -1
- package/src/core/domain/primitives.ts +9 -10
- package/src/core/domain/types.ts +4 -3
- package/src/core/engine/state/BaseGameController.ts +0 -1
- package/src/core/io/InteractionTracker.ts +1 -1
- package/src/core/io/quickstash.ts +3 -29
- package/src/core/types/plugin-interfaces.ts +1 -1
- package/src/plugins/tangram-construct/ConstructionApp.tsx +13 -58
- package/src/plugins/tangram-construct/index.ts +1 -1
- package/src/plugins/tangram-prep/PrepApp.tsx +1 -0
- package/src/plugins/tangram-prep/index.ts +1 -1
- package/tangram-construct.min.js +11 -15
- package/tangram-prep.min.js +1 -1
- package/src/core/io/stims.ts +0 -107
package/dist/construct/index.cjs
CHANGED
|
@@ -187,7 +187,6 @@ class BaseGameController {
|
|
|
187
187
|
const allDone = Object.values(this.state.sectors).every((s) => !!s.completedAt);
|
|
188
188
|
if (allDone && !this.state.endedAt) {
|
|
189
189
|
this.state.endedAt = NOW();
|
|
190
|
-
console.log("[BaseGameController] all sectors complete");
|
|
191
190
|
}
|
|
192
191
|
}
|
|
193
192
|
// ===== Piece Operations =====
|
|
@@ -2928,8 +2927,7 @@ class InteractionTracker {
|
|
|
2928
2927
|
}
|
|
2929
2928
|
const sectorTangramMap = this.controller.state.cfg.sectors.map((s) => ({
|
|
2930
2929
|
sectorId: s.id,
|
|
2931
|
-
tangramId: s.
|
|
2932
|
-
// In our system, sector ID == tangram ID
|
|
2930
|
+
tangramId: s.tangramId
|
|
2933
2931
|
}));
|
|
2934
2932
|
const blueprintOrder = {
|
|
2935
2933
|
primitives: this.controller.state.primitives.map((bp) => bp.id),
|
|
@@ -3156,7 +3154,9 @@ function GameBoard(props) {
|
|
|
3156
3154
|
if (allSectorsComplete && !gameCompleted) {
|
|
3157
3155
|
setGameCompleted(true);
|
|
3158
3156
|
if (tracker) {
|
|
3159
|
-
|
|
3157
|
+
setTimeout(() => {
|
|
3158
|
+
tracker.finalizeTrial("auto_complete");
|
|
3159
|
+
}, 0);
|
|
3160
3160
|
}
|
|
3161
3161
|
}
|
|
3162
3162
|
};
|
|
@@ -3434,10 +3434,10 @@ function constructFromSpec(sideLens, angles, firstEdgeUnits) {
|
|
|
3434
3434
|
return pts;
|
|
3435
3435
|
}
|
|
3436
3436
|
const FIRST_EDGES_UNITS = {
|
|
3437
|
-
"
|
|
3437
|
+
"smalltriangle": [P(0, 0), P(0.5, 0.5)],
|
|
3438
3438
|
"parallelogram": [P(0, 0), P(0.5, 0)],
|
|
3439
|
-
"
|
|
3440
|
-
"
|
|
3439
|
+
"largetriangle": [P(0, 0), P(0.5, -0.5)],
|
|
3440
|
+
"medtriangle": [P(0, 0), P(0.5, 0)],
|
|
3441
3441
|
"square": [P(0, 0), P(0.5, 0)]
|
|
3442
3442
|
};
|
|
3443
3443
|
const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
@@ -3450,8 +3450,8 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
|
3450
3450
|
color: "#f43f5e"
|
|
3451
3451
|
},
|
|
3452
3452
|
{
|
|
3453
|
-
id: "prim:
|
|
3454
|
-
kind: "
|
|
3453
|
+
id: "prim:smalltriangle",
|
|
3454
|
+
kind: "smalltriangle",
|
|
3455
3455
|
sideLens: [HALFDIAGONAL, HALFDIAGONAL, HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT],
|
|
3456
3456
|
angles: [180, 45, 180, 90, 180, 45],
|
|
3457
3457
|
color: "#f59e0b"
|
|
@@ -3464,15 +3464,15 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
|
3464
3464
|
color: "#10b981"
|
|
3465
3465
|
},
|
|
3466
3466
|
{
|
|
3467
|
-
id: "prim:
|
|
3468
|
-
kind: "
|
|
3467
|
+
id: "prim:medtriangle",
|
|
3468
|
+
kind: "medtriangle",
|
|
3469
3469
|
sideLens: [HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL],
|
|
3470
3470
|
angles: [180, 180, 180, 45, 180, 90, 180, 45],
|
|
3471
3471
|
color: "#3b82f6"
|
|
3472
3472
|
},
|
|
3473
3473
|
{
|
|
3474
|
-
id: "prim:
|
|
3475
|
-
kind: "
|
|
3474
|
+
id: "prim:largetriangle",
|
|
3475
|
+
kind: "largetriangle",
|
|
3476
3476
|
sideLens: [
|
|
3477
3477
|
HALFDIAGONAL,
|
|
3478
3478
|
HALFDIAGONAL,
|
|
@@ -3544,101 +3544,61 @@ function convertAnchorCompositeToPixels(anchorComposite, primsByKind, gridStepPx
|
|
|
3544
3544
|
function startConstructionTrial(display_element, params, _jsPsych) {
|
|
3545
3545
|
const CANON = /* @__PURE__ */ new Set([
|
|
3546
3546
|
"square",
|
|
3547
|
-
"
|
|
3547
|
+
"smalltriangle",
|
|
3548
3548
|
"parallelogram",
|
|
3549
|
-
"
|
|
3550
|
-
"
|
|
3549
|
+
"medtriangle",
|
|
3550
|
+
"largetriangle"
|
|
3551
3551
|
]);
|
|
3552
|
-
const SECTOR_IDS = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"];
|
|
3553
|
-
console.log("[ConstructionApp] Starting tangram conversion...");
|
|
3554
|
-
console.log("[ConstructionApp] Received tangrams:", params.tangrams);
|
|
3555
|
-
console.log("[ConstructionApp] Number of tangrams:", params.tangrams.length);
|
|
3556
3552
|
const sectors = params.tangrams.map((tangramSpec, index) => {
|
|
3557
|
-
console.log(`
|
|
3558
|
-
[ConstructionApp] Processing tangram ${index}:`, tangramSpec);
|
|
3559
|
-
console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
|
|
3560
|
-
console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
|
|
3561
|
-
console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
|
|
3562
|
-
console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
|
|
3563
3553
|
const filteredTans = tangramSpec.solutionTans.filter((tan) => {
|
|
3564
3554
|
const tanName = tan.name ?? tan.kind;
|
|
3565
3555
|
const isCanonical = CANON.has(tanName);
|
|
3566
|
-
console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
|
|
3567
3556
|
return isCanonical;
|
|
3568
3557
|
});
|
|
3569
|
-
console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
|
|
3570
3558
|
const mask = filteredTans.map((tan, tanIndex) => {
|
|
3571
|
-
const tanName = tan.name ?? tan.kind;
|
|
3572
3559
|
const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
|
|
3573
|
-
console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
|
|
3574
|
-
console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
|
|
3575
3560
|
return polygon;
|
|
3576
3561
|
});
|
|
3577
|
-
const sectorId =
|
|
3578
|
-
console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
|
|
3579
|
-
console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
|
|
3562
|
+
const sectorId = `sector${index}`;
|
|
3580
3563
|
const sector = {
|
|
3581
3564
|
id: sectorId,
|
|
3565
|
+
tangramId: tangramSpec.tangramID,
|
|
3582
3566
|
silhouette: {
|
|
3583
3567
|
id: sectorId,
|
|
3584
3568
|
mask
|
|
3585
3569
|
}
|
|
3586
3570
|
};
|
|
3587
|
-
console.log(`[ConstructionApp] Created sector:`, sector);
|
|
3588
3571
|
return sector;
|
|
3589
3572
|
});
|
|
3590
|
-
console.log("\n[ConstructionApp] Final sectors array:", sectors);
|
|
3591
|
-
console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
|
|
3592
|
-
console.log("\n[ConstructionApp] Processing quickstash macros...");
|
|
3593
|
-
console.log("[ConstructionApp] quickstash_macros:", params.quickstash_macros);
|
|
3594
|
-
console.log("[ConstructionApp] quickstash_macros count:", params.quickstash_macros?.length ?? 0);
|
|
3595
3573
|
let quickstash = [];
|
|
3596
3574
|
if (params.quickstash_macros && params.quickstash_macros.length > 0) {
|
|
3597
3575
|
const firstMacro = params.quickstash_macros[0];
|
|
3598
|
-
console.log("[ConstructionApp] First macro:", firstMacro);
|
|
3599
3576
|
if (firstMacro && "parts" in firstMacro && firstMacro.parts && firstMacro.parts[0] && "anchorOffset" in firstMacro.parts[0]) {
|
|
3600
|
-
console.log("[ConstructionApp] Detected anchor-based composites, converting to pixels...");
|
|
3601
3577
|
const primsByKind = /* @__PURE__ */ new Map();
|
|
3602
3578
|
PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
|
|
3603
3579
|
quickstash = params.quickstash_macros.map(
|
|
3604
3580
|
(anchorComposite) => convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx)
|
|
3605
3581
|
// Use current CONFIG grid step
|
|
3606
3582
|
);
|
|
3607
|
-
console.log("[ConstructionApp] Converted to pixel-based blueprints:", quickstash);
|
|
3608
3583
|
} else {
|
|
3609
|
-
console.log("[ConstructionApp] Already pixel-based blueprints");
|
|
3610
3584
|
quickstash = params.quickstash_macros;
|
|
3611
3585
|
}
|
|
3612
|
-
} else {
|
|
3613
|
-
console.log("[ConstructionApp] No quickstash macros provided");
|
|
3614
3586
|
}
|
|
3615
3587
|
const gameBoardProps = {
|
|
3616
3588
|
sectors,
|
|
3617
3589
|
quickstash,
|
|
3618
3590
|
primitives: PRIMITIVE_BLUEPRINTS,
|
|
3619
|
-
layout: params.layout
|
|
3620
|
-
target: params.target
|
|
3621
|
-
input: params.input
|
|
3622
|
-
timeLimitMs: params.time_limit_ms
|
|
3591
|
+
layout: params.layout,
|
|
3592
|
+
target: params.target,
|
|
3593
|
+
input: params.input,
|
|
3594
|
+
timeLimitMs: params.time_limit_ms,
|
|
3623
3595
|
maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
|
|
3624
3596
|
mode: "construction",
|
|
3625
|
-
// Explicit construction mode
|
|
3626
3597
|
...params.onInteraction && { onInteraction: params.onInteraction },
|
|
3627
3598
|
...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
|
|
3628
3599
|
};
|
|
3629
|
-
console.log("\n[ConstructionApp] Final GameBoard props:");
|
|
3630
|
-
console.log("[ConstructionApp] sectors count:", gameBoardProps.sectors.length);
|
|
3631
|
-
console.log("[ConstructionApp] quickstash count:", gameBoardProps.quickstash.length);
|
|
3632
|
-
console.log("[ConstructionApp] primitives count:", gameBoardProps.primitives.length);
|
|
3633
|
-
console.log("[ConstructionApp] layout:", gameBoardProps.layout);
|
|
3634
|
-
console.log("[ConstructionApp] target:", gameBoardProps.target);
|
|
3635
|
-
console.log("[ConstructionApp] input:", gameBoardProps.input);
|
|
3636
|
-
console.log("[ConstructionApp] timeLimitMs:", gameBoardProps.timeLimitMs);
|
|
3637
|
-
console.log("[ConstructionApp] mode:", gameBoardProps.mode);
|
|
3638
|
-
console.log("[ConstructionApp] Full props:", gameBoardProps);
|
|
3639
3600
|
const root = client.createRoot(display_element);
|
|
3640
3601
|
root.render(React.createElement(GameBoard, gameBoardProps));
|
|
3641
|
-
console.log("[ConstructionApp] GameBoard rendered successfully");
|
|
3642
3602
|
return { root, display_element, jsPsych: _jsPsych };
|
|
3643
3603
|
}
|
|
3644
3604
|
|
|
@@ -3762,7 +3722,7 @@ class TangramConstructPlugin {
|
|
|
3762
3722
|
target: trial.target,
|
|
3763
3723
|
input: trial.input,
|
|
3764
3724
|
layout: trial.layout,
|
|
3765
|
-
time_limit_ms: trial.time_limit_ms
|
|
3725
|
+
time_limit_ms: trial.time_limit_ms,
|
|
3766
3726
|
onInteraction: trial.onInteraction,
|
|
3767
3727
|
onTrialEnd: wrappedOnTrialEnd
|
|
3768
3728
|
};
|