jspsych-tangram 0.0.2 → 0.0.4
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 +94 -40
- package/dist/construct/index.browser.js.map +1 -1
- package/dist/construct/index.browser.min.js +15 -11
- package/dist/construct/index.browser.min.js.map +1 -1
- package/dist/construct/index.cjs +94 -40
- package/dist/construct/index.cjs.map +1 -1
- package/dist/construct/index.js +94 -40
- package/dist/construct/index.js.map +1 -1
- package/dist/index.cjs +96 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +96 -40
- package/dist/index.js.map +1 -1
- package/dist/prep/index.browser.js +14 -13
- 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 +14 -13
- package/dist/prep/index.cjs.map +1 -1
- package/dist/prep/index.js +14 -13
- package/dist/prep/index.js.map +1 -1
- package/package.json +1 -1
- package/src/core/domain/primitives.ts +11 -12
- package/src/core/domain/types.ts +4 -4
- package/src/core/io/InteractionTracker.ts +1 -1
- package/src/core/io/quickstash.ts +3 -29
- package/src/core/types/plugin-interfaces.ts +6 -5
- package/src/index.spec.ts +0 -19
- package/src/plugins/tangram-construct/ConstructionApp.tsx +103 -30
- package/src/plugins/tangram-prep/PrepApp.tsx +1 -0
- package/tangram-construct.min.js +15 -11
- package/tangram-prep.min.js +1 -1
- package/src/core/io/json-to-tangram-spec.ts +0 -110
- package/src/core/io/stims.ts +0 -110
package/dist/index.cjs
CHANGED
|
@@ -2928,8 +2928,7 @@ class InteractionTracker {
|
|
|
2928
2928
|
}
|
|
2929
2929
|
const sectorTangramMap = this.controller.state.cfg.sectors.map((s) => ({
|
|
2930
2930
|
sectorId: s.id,
|
|
2931
|
-
tangramId: s.
|
|
2932
|
-
// In our system, sector ID == tangram ID
|
|
2931
|
+
tangramId: s.tangramId
|
|
2933
2932
|
}));
|
|
2934
2933
|
const blueprintOrder = {
|
|
2935
2934
|
primitives: this.controller.state.primitives.map((bp) => bp.id),
|
|
@@ -3434,11 +3433,11 @@ function constructFromSpec(sideLens, angles, firstEdgeUnits) {
|
|
|
3434
3433
|
return pts;
|
|
3435
3434
|
}
|
|
3436
3435
|
const FIRST_EDGES_UNITS = {
|
|
3437
|
-
|
|
3438
|
-
parallelogram: [P(0, 0), P(0.5, 0)],
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
square: [P(0, 0), P(0.5, 0)]
|
|
3436
|
+
"smalltriangle": [P(0, 0), P(0.5, 0.5)],
|
|
3437
|
+
"parallelogram": [P(0, 0), P(0.5, 0)],
|
|
3438
|
+
"largetriangle": [P(0, 0), P(0.5, -0.5)],
|
|
3439
|
+
"medtriangle": [P(0, 0), P(0.5, 0)],
|
|
3440
|
+
"square": [P(0, 0), P(0.5, 0)]
|
|
3442
3441
|
};
|
|
3443
3442
|
const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
3444
3443
|
const specs = [
|
|
@@ -3450,8 +3449,8 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
|
3450
3449
|
color: "#f43f5e"
|
|
3451
3450
|
},
|
|
3452
3451
|
{
|
|
3453
|
-
id: "prim:
|
|
3454
|
-
kind: "
|
|
3452
|
+
id: "prim:smalltriangle",
|
|
3453
|
+
kind: "smalltriangle",
|
|
3455
3454
|
sideLens: [HALFDIAGONAL, HALFDIAGONAL, HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT],
|
|
3456
3455
|
angles: [180, 45, 180, 90, 180, 45],
|
|
3457
3456
|
color: "#f59e0b"
|
|
@@ -3464,15 +3463,15 @@ const PRIMITIVE_BLUEPRINTS_CACHE = (() => {
|
|
|
3464
3463
|
color: "#10b981"
|
|
3465
3464
|
},
|
|
3466
3465
|
{
|
|
3467
|
-
id: "prim:
|
|
3468
|
-
kind: "
|
|
3466
|
+
id: "prim:medtriangle",
|
|
3467
|
+
kind: "medtriangle",
|
|
3469
3468
|
sideLens: [HALFUNIT, HALFUNIT, HALFUNIT, HALFUNIT, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL, HALFDIAGONAL],
|
|
3470
3469
|
angles: [180, 180, 180, 45, 180, 90, 180, 45],
|
|
3471
3470
|
color: "#3b82f6"
|
|
3472
3471
|
},
|
|
3473
3472
|
{
|
|
3474
|
-
id: "prim:
|
|
3475
|
-
kind: "
|
|
3473
|
+
id: "prim:largetriangle",
|
|
3474
|
+
kind: "largetriangle",
|
|
3476
3475
|
sideLens: [
|
|
3477
3476
|
HALFDIAGONAL,
|
|
3478
3477
|
HALFDIAGONAL,
|
|
@@ -3542,48 +3541,103 @@ function convertAnchorCompositeToPixels(anchorComposite, primsByKind, gridStepPx
|
|
|
3542
3541
|
}
|
|
3543
3542
|
|
|
3544
3543
|
function startConstructionTrial(display_element, params, _jsPsych) {
|
|
3545
|
-
const
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3544
|
+
const CANON = /* @__PURE__ */ new Set([
|
|
3545
|
+
"square",
|
|
3546
|
+
"smalltriangle",
|
|
3547
|
+
"parallelogram",
|
|
3548
|
+
"medtriangle",
|
|
3549
|
+
"largetriangle"
|
|
3550
|
+
]);
|
|
3551
|
+
console.log("[ConstructionApp] Starting tangram conversion...");
|
|
3552
|
+
console.log("[ConstructionApp] Received tangrams:", params.tangrams);
|
|
3553
|
+
console.log("[ConstructionApp] Number of tangrams:", params.tangrams.length);
|
|
3554
|
+
const sectors = params.tangrams.map((tangramSpec, index) => {
|
|
3555
|
+
console.log(`
|
|
3556
|
+
[ConstructionApp] Processing tangram ${index}:`, tangramSpec);
|
|
3557
|
+
console.log(`[ConstructionApp] tangramID: ${tangramSpec.tangramID}`);
|
|
3558
|
+
console.log(`[ConstructionApp] setLabel: ${tangramSpec.setLabel}`);
|
|
3559
|
+
console.log(`[ConstructionApp] solutionTans count: ${tangramSpec.solutionTans?.length}`);
|
|
3560
|
+
console.log(`[ConstructionApp] solutionTans:`, tangramSpec.solutionTans);
|
|
3561
|
+
const filteredTans = tangramSpec.solutionTans.filter((tan) => {
|
|
3562
|
+
const tanName = tan.name ?? tan.kind;
|
|
3563
|
+
const isCanonical = CANON.has(tanName);
|
|
3564
|
+
console.log(`[ConstructionApp] Tan "${tanName}": canonical=${isCanonical}, vertices count=${tan.vertices?.length}`);
|
|
3565
|
+
return isCanonical;
|
|
3566
|
+
});
|
|
3567
|
+
console.log(`[ConstructionApp] Filtered to ${filteredTans.length} canonical pieces`);
|
|
3568
|
+
const mask = filteredTans.map((tan, tanIndex) => {
|
|
3569
|
+
const tanName = tan.name ?? tan.kind;
|
|
3570
|
+
const polygon = tan.vertices.map(([x, y]) => ({ x: x ?? 0, y: -(y ?? 0) }));
|
|
3571
|
+
console.log(`[ConstructionApp] Polygon ${tanIndex} (${tanName}): ${tan.vertices.length} vertices -> ${polygon.length} points`);
|
|
3572
|
+
console.log(`[ConstructionApp] First vertex: [${tan.vertices[0]?.[0]}, ${tan.vertices[0]?.[1]}] -> {x: ${polygon[0]?.x}, y: ${polygon[0]?.y}}`);
|
|
3573
|
+
return polygon;
|
|
3574
|
+
});
|
|
3575
|
+
const sectorId = `sector${index}`;
|
|
3576
|
+
console.log(`[ConstructionApp] Assigned sector ID: ${sectorId}`);
|
|
3577
|
+
console.log(`[ConstructionApp] Final mask has ${mask.length} polygons`);
|
|
3578
|
+
const sector = {
|
|
3579
|
+
id: sectorId,
|
|
3580
|
+
tangramId: tangramSpec.tangramID,
|
|
3581
|
+
silhouette: {
|
|
3582
|
+
id: sectorId,
|
|
3583
|
+
mask
|
|
3584
|
+
}
|
|
3585
|
+
};
|
|
3586
|
+
console.log(`[ConstructionApp] Created sector:`, sector);
|
|
3587
|
+
return sector;
|
|
3588
|
+
});
|
|
3589
|
+
console.log("\n[ConstructionApp] Final sectors array:", sectors);
|
|
3590
|
+
console.log(`[ConstructionApp] Total sectors created: ${sectors.length}`);
|
|
3591
|
+
console.log("\n[ConstructionApp] Processing quickstash macros...");
|
|
3592
|
+
console.log("[ConstructionApp] quickstash_macros:", params.quickstash_macros);
|
|
3593
|
+
console.log("[ConstructionApp] quickstash_macros count:", params.quickstash_macros?.length ?? 0);
|
|
3556
3594
|
let quickstash = [];
|
|
3557
3595
|
if (params.quickstash_macros && params.quickstash_macros.length > 0) {
|
|
3558
3596
|
const firstMacro = params.quickstash_macros[0];
|
|
3597
|
+
console.log("[ConstructionApp] First macro:", firstMacro);
|
|
3559
3598
|
if (firstMacro && "parts" in firstMacro && firstMacro.parts && firstMacro.parts[0] && "anchorOffset" in firstMacro.parts[0]) {
|
|
3599
|
+
console.log("[ConstructionApp] Detected anchor-based composites, converting to pixels...");
|
|
3560
3600
|
const primsByKind = /* @__PURE__ */ new Map();
|
|
3561
3601
|
PRIMITIVE_BLUEPRINTS.forEach((p) => primsByKind.set(p.kind, p));
|
|
3562
3602
|
quickstash = params.quickstash_macros.map(
|
|
3563
3603
|
(anchorComposite) => convertAnchorCompositeToPixels(anchorComposite, primsByKind, CONFIG.layout.grid.stepPx)
|
|
3564
3604
|
// Use current CONFIG grid step
|
|
3565
3605
|
);
|
|
3606
|
+
console.log("[ConstructionApp] Converted to pixel-based blueprints:", quickstash);
|
|
3566
3607
|
} else {
|
|
3608
|
+
console.log("[ConstructionApp] Already pixel-based blueprints");
|
|
3567
3609
|
quickstash = params.quickstash_macros;
|
|
3568
3610
|
}
|
|
3611
|
+
} else {
|
|
3612
|
+
console.log("[ConstructionApp] No quickstash macros provided");
|
|
3569
3613
|
}
|
|
3614
|
+
const gameBoardProps = {
|
|
3615
|
+
sectors,
|
|
3616
|
+
quickstash,
|
|
3617
|
+
primitives: PRIMITIVE_BLUEPRINTS,
|
|
3618
|
+
layout: params.layout || "semicircle",
|
|
3619
|
+
target: params.target || "silhouette",
|
|
3620
|
+
input: params.input || "drag",
|
|
3621
|
+
timeLimitMs: params.time_limit_ms || 0,
|
|
3622
|
+
maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
|
|
3623
|
+
mode: "construction",
|
|
3624
|
+
// Explicit construction mode
|
|
3625
|
+
...params.onInteraction && { onInteraction: params.onInteraction },
|
|
3626
|
+
...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
|
|
3627
|
+
};
|
|
3628
|
+
console.log("\n[ConstructionApp] Final GameBoard props:");
|
|
3629
|
+
console.log("[ConstructionApp] sectors count:", gameBoardProps.sectors.length);
|
|
3630
|
+
console.log("[ConstructionApp] quickstash count:", gameBoardProps.quickstash.length);
|
|
3631
|
+
console.log("[ConstructionApp] primitives count:", gameBoardProps.primitives.length);
|
|
3632
|
+
console.log("[ConstructionApp] layout:", gameBoardProps.layout);
|
|
3633
|
+
console.log("[ConstructionApp] target:", gameBoardProps.target);
|
|
3634
|
+
console.log("[ConstructionApp] input:", gameBoardProps.input);
|
|
3635
|
+
console.log("[ConstructionApp] timeLimitMs:", gameBoardProps.timeLimitMs);
|
|
3636
|
+
console.log("[ConstructionApp] mode:", gameBoardProps.mode);
|
|
3637
|
+
console.log("[ConstructionApp] Full props:", gameBoardProps);
|
|
3570
3638
|
const root = client.createRoot(display_element);
|
|
3571
|
-
root.render(
|
|
3572
|
-
|
|
3573
|
-
sectors,
|
|
3574
|
-
quickstash,
|
|
3575
|
-
primitives: PRIMITIVE_BLUEPRINTS,
|
|
3576
|
-
layout: params.layout || "semicircle",
|
|
3577
|
-
target: params.target || "silhouette",
|
|
3578
|
-
input: params.input || "drag",
|
|
3579
|
-
timeLimitMs: params.time_limit_ms || 0,
|
|
3580
|
-
maxQuickstashSlots: CONFIG.layout.defaults.maxQuickstashSlots,
|
|
3581
|
-
mode: "construction",
|
|
3582
|
-
// Explicit construction mode
|
|
3583
|
-
...params.onInteraction && { onInteraction: params.onInteraction },
|
|
3584
|
-
...params.onTrialEnd && { onTrialEnd: params.onTrialEnd }
|
|
3585
|
-
})
|
|
3586
|
-
);
|
|
3639
|
+
root.render(React.createElement(GameBoard, gameBoardProps));
|
|
3640
|
+
console.log("[ConstructionApp] GameBoard rendered successfully");
|
|
3587
3641
|
return { root, display_element, jsPsych: _jsPsych };
|
|
3588
3642
|
}
|
|
3589
3643
|
|
|
@@ -3730,6 +3784,8 @@ function startPrepTrial(display_element, params, jsPsych) {
|
|
|
3730
3784
|
} = params;
|
|
3731
3785
|
const prepSectors = Array.from({ length: numQuickstashSlots }, (_, i) => ({
|
|
3732
3786
|
id: `prep-sector-${i}`,
|
|
3787
|
+
tangramId: `prep-sector-${i}`,
|
|
3788
|
+
// dummy value since prep mode doesn't have tangrams
|
|
3733
3789
|
silhouette: {
|
|
3734
3790
|
id: `prep-silhouette-${i}`,
|
|
3735
3791
|
mask: []
|