paperlab 0.3.1 → 0.5.0
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/README.md +16 -16
- package/dist/{chunk-XE4E43MD.js → chunk-6IADJZX5.js} +2424 -2242
- package/dist/chunk-6IADJZX5.js.map +1 -0
- package/dist/index.cjs +887 -843
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +450 -1934
- package/dist/index.d.ts +450 -1934
- package/dist/index.js +202 -429
- package/dist/index.js.map +1 -1
- package/dist/slots-CIo7FnlY.d.cts +13357 -0
- package/dist/slots-CIo7FnlY.d.ts +13357 -0
- package/dist/stage.cjs +2377 -2125
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.d.cts +52 -204
- package/dist/stage.d.ts +52 -204
- package/dist/stage.js +29 -18
- package/dist/stage.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-XE4E43MD.js.map +0 -1
- package/dist/slots-DUMR64HB.d.cts +0 -6661
- package/dist/slots-DUMR64HB.d.ts +0 -6661
package/dist/index.js
CHANGED
|
@@ -1,187 +1,76 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AGENT_PAYLOAD_VERSION,
|
|
3
3
|
AUTO_CEILING,
|
|
4
|
-
ClothSim,
|
|
5
4
|
DropZone,
|
|
6
|
-
DropZoneRegistry,
|
|
7
5
|
FLAT_SEGMENTS,
|
|
8
6
|
LightRig,
|
|
9
|
-
|
|
7
|
+
PaperBackdrop,
|
|
10
8
|
PaperFallback,
|
|
11
9
|
PaperField,
|
|
12
10
|
PaperFieldMesh,
|
|
13
11
|
PaperLighting,
|
|
14
|
-
PaperMaterial,
|
|
15
12
|
PaperMesh,
|
|
16
13
|
PaperMirror,
|
|
17
|
-
PaperStateMachine,
|
|
18
14
|
SAG_TOL,
|
|
19
|
-
|
|
20
|
-
TRANSMISSION_GAIN,
|
|
21
|
-
accordion,
|
|
22
|
-
applyDeformerStack,
|
|
23
|
-
atlasGrid,
|
|
24
|
-
backContentSchema,
|
|
25
|
-
barcodeBars,
|
|
15
|
+
backdropSchema,
|
|
26
16
|
behaviorConfigSchema,
|
|
27
|
-
bend,
|
|
28
|
-
bendOptionsSchema,
|
|
29
|
-
book,
|
|
30
17
|
buildAgentPayload,
|
|
31
18
|
buildDisplacementGLSL,
|
|
32
|
-
buildFieldFragmentShader,
|
|
33
|
-
buildFieldVertexShader,
|
|
34
19
|
buildJsxSnippet,
|
|
35
|
-
cardContentSchema,
|
|
36
|
-
carry,
|
|
37
|
-
carryDrive,
|
|
38
|
-
carryOptionsSchema,
|
|
39
20
|
clothConfigSchema,
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
contentSchema,
|
|
43
|
-
contentText,
|
|
21
|
+
contentNames,
|
|
22
|
+
contentSchemaFor,
|
|
44
23
|
coreStateNames,
|
|
45
|
-
cornerNames,
|
|
46
|
-
createSheetGeometry,
|
|
47
|
-
crumple,
|
|
48
|
-
crumpleBehavior,
|
|
49
|
-
crumpleBehaviorOptionsSchema,
|
|
50
|
-
crumpleOptionsSchema,
|
|
51
|
-
curl,
|
|
52
|
-
curlOptionsSchema,
|
|
53
|
-
dampTo,
|
|
54
|
-
deformerInstanceSchema,
|
|
55
24
|
describeConfig,
|
|
56
25
|
diffConfig,
|
|
57
26
|
displacePoint,
|
|
58
|
-
drape,
|
|
59
|
-
drapeOptionsSchema,
|
|
60
|
-
drawBacking,
|
|
61
|
-
fall,
|
|
62
|
-
fallOptionsSchema,
|
|
63
|
-
fan,
|
|
64
|
-
fieldBounds,
|
|
65
|
-
fieldKeyboardStep,
|
|
66
|
-
filmNames,
|
|
67
|
-
fitCamera,
|
|
68
|
-
flattenNumeric,
|
|
69
|
-
flight,
|
|
70
|
-
flightOptionsSchema,
|
|
71
|
-
flightPose,
|
|
72
|
-
flip,
|
|
73
|
-
flipOptionsSchema,
|
|
74
|
-
fly,
|
|
75
|
-
flyOptionsSchema,
|
|
76
|
-
fold,
|
|
77
|
-
foldOptionsSchema,
|
|
78
27
|
getBehavior,
|
|
79
28
|
getDeformer,
|
|
80
|
-
getIdlePreset,
|
|
81
29
|
getLayout,
|
|
82
|
-
getLightingPreset,
|
|
83
30
|
getPreset,
|
|
84
31
|
getStock,
|
|
85
|
-
groupFieldPapers,
|
|
86
|
-
gust,
|
|
87
|
-
hang,
|
|
88
|
-
hangOptionsSchema,
|
|
89
32
|
idleNames,
|
|
90
|
-
idlePresets,
|
|
91
33
|
isBuiltinPreset,
|
|
92
|
-
letterFold,
|
|
93
|
-
letterFoldOptionsSchema,
|
|
94
34
|
lightAngles,
|
|
95
|
-
lightPosition,
|
|
96
35
|
lightSchema,
|
|
97
|
-
lightenHex,
|
|
98
36
|
lightingNames,
|
|
99
|
-
lightingPresets,
|
|
100
37
|
listBehaviors,
|
|
101
38
|
listDeformers,
|
|
102
39
|
listLayouts,
|
|
103
40
|
listPresets,
|
|
104
|
-
makeGoboTexture,
|
|
105
41
|
mergeConfig,
|
|
106
42
|
mergeWithDeletes,
|
|
107
|
-
outwardCorner,
|
|
108
43
|
paperConfigSchema,
|
|
109
44
|
paperEdges,
|
|
110
45
|
paperStatesSchema,
|
|
111
46
|
parsePreset,
|
|
112
|
-
peel,
|
|
113
|
-
peelOptionsSchema,
|
|
114
47
|
physicsNames,
|
|
115
|
-
physicsSchema,
|
|
116
|
-
pile,
|
|
117
|
-
quantizeProgress,
|
|
118
48
|
quantizeSegments,
|
|
119
|
-
quantizeTime,
|
|
120
|
-
rack,
|
|
121
|
-
receiptContentSchema,
|
|
122
|
-
receiptTotals,
|
|
123
49
|
recordStateOverride,
|
|
124
50
|
registerBehavior,
|
|
125
51
|
registerDeformer,
|
|
126
52
|
registerLayout,
|
|
127
53
|
registerPreset,
|
|
128
|
-
resolveConfig,
|
|
129
|
-
resolveDeformerStack,
|
|
130
|
-
resolveFieldSlotConfig,
|
|
131
54
|
resolveLighting,
|
|
132
|
-
resolveSegments,
|
|
133
55
|
resolveStateConfig,
|
|
134
|
-
ribbon,
|
|
135
|
-
ribbonOptionsSchema,
|
|
136
|
-
ring,
|
|
137
|
-
roll,
|
|
138
|
-
rollOptionsSchema,
|
|
139
56
|
sceneSchema,
|
|
140
57
|
segmentsForArc,
|
|
141
58
|
segmentsForSine,
|
|
142
59
|
serializePreset,
|
|
143
|
-
settle,
|
|
144
|
-
settleOptionsSchema,
|
|
145
|
-
sheet,
|
|
146
|
-
sheetBackingSize,
|
|
147
60
|
sheetLayoutSchema,
|
|
148
|
-
sheetSchema,
|
|
149
|
-
sheetSlotXY,
|
|
150
|
-
silhouetteRects,
|
|
151
61
|
spanAlong,
|
|
152
|
-
spill,
|
|
153
|
-
spread,
|
|
154
|
-
stackAutoSegments,
|
|
155
|
-
stackMinSegments,
|
|
156
|
-
stackUniformValues,
|
|
157
62
|
stateDefSchema,
|
|
158
|
-
stateEventTransitions,
|
|
159
|
-
stateTransitionSchema,
|
|
160
63
|
stockNames,
|
|
161
|
-
stockSchema,
|
|
162
64
|
stocks,
|
|
163
|
-
stripStates,
|
|
164
65
|
supportsWebGL,
|
|
165
|
-
surfaceSchema,
|
|
166
|
-
sweep,
|
|
167
|
-
tornEdgesOnDetach,
|
|
168
|
-
translucencyUniforms,
|
|
169
|
-
translucencyValues,
|
|
170
66
|
uniquePresetName,
|
|
171
67
|
unregisterPreset,
|
|
172
|
-
unroll,
|
|
173
|
-
unrollOptionsSchema,
|
|
174
|
-
useContentAtlas,
|
|
175
68
|
usePaperStates,
|
|
176
69
|
usePrefersReducedMotion,
|
|
177
70
|
useResolvedConfig,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
withSheetCellFromPaper,
|
|
182
|
-
wrapLines,
|
|
183
|
-
zoneAccepts
|
|
184
|
-
} from "./chunk-XE4E43MD.js";
|
|
71
|
+
washSchema,
|
|
72
|
+
wrapLines
|
|
73
|
+
} from "./chunk-6IADJZX5.js";
|
|
185
74
|
|
|
186
75
|
// src/Paper.tsx
|
|
187
76
|
import { Canvas } from "@react-three/fiber";
|
|
@@ -192,10 +81,12 @@ var Paper = forwardRef(function Paper2({ children, className, style, ...meshProp
|
|
|
192
81
|
const webgl = useMemo(() => typeof window === "undefined" ? true : supportsWebGL(), []);
|
|
193
82
|
return /* @__PURE__ */ jsxs("div", { className, style: { width: "100%", height: "100%", ...style }, children: [
|
|
194
83
|
webgl ? /* @__PURE__ */ jsxs(Canvas, { shadows: true, camera: { position: [0, 0.35, 2.4], fov: 40 }, dpr: [1, 2], children: [
|
|
84
|
+
/* @__PURE__ */ jsx(PaperBackdrop, { backdrop: config.scene.backdrop }),
|
|
195
85
|
/* @__PURE__ */ jsx(
|
|
196
86
|
PaperLighting,
|
|
197
87
|
{
|
|
198
88
|
preset: config.scene.lighting,
|
|
89
|
+
light: config.scene.light,
|
|
199
90
|
floor: -1.05,
|
|
200
91
|
scale: 8,
|
|
201
92
|
reducedMotion: meshProps.reducedMotion
|
|
@@ -208,6 +99,191 @@ var Paper = forwardRef(function Paper2({ children, className, style, ...meshProp
|
|
|
208
99
|
] });
|
|
209
100
|
});
|
|
210
101
|
|
|
102
|
+
// src/config/field-export.ts
|
|
103
|
+
var MOTION_DEFAULTS = { driver: "autoplay", speed: 0.5 };
|
|
104
|
+
var ENTRANCE_DEFAULTS = { type: "rise", stagger: 0.06, duration: 0.9 };
|
|
105
|
+
function camel(name) {
|
|
106
|
+
const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "");
|
|
107
|
+
const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`;
|
|
108
|
+
return safe.charAt(0).toLowerCase() + safe.slice(1);
|
|
109
|
+
}
|
|
110
|
+
function distinctFieldPresets(input) {
|
|
111
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
112
|
+
const usedNames = /* @__PURE__ */ new Set();
|
|
113
|
+
for (const paper of input.papers) {
|
|
114
|
+
const key = JSON.stringify(paper.preset);
|
|
115
|
+
if (byKey.has(key)) continue;
|
|
116
|
+
let varName = camel(paper.presetName);
|
|
117
|
+
while (usedNames.has(varName)) varName += "2";
|
|
118
|
+
usedNames.add(varName);
|
|
119
|
+
byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset });
|
|
120
|
+
}
|
|
121
|
+
return [...byKey.values()];
|
|
122
|
+
}
|
|
123
|
+
function nonDefault(value, defaults) {
|
|
124
|
+
const out = {};
|
|
125
|
+
for (const [k, v] of Object.entries(value ?? {})) {
|
|
126
|
+
if (v === void 0) continue;
|
|
127
|
+
const same = v === defaults[k] || JSON.stringify(v) === JSON.stringify(defaults[k]);
|
|
128
|
+
if (!same) out[k] = v;
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
function diffFieldProps(input) {
|
|
133
|
+
const out = { layout: input.layout };
|
|
134
|
+
const layout = getLayout(input.layout);
|
|
135
|
+
const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults);
|
|
136
|
+
if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions;
|
|
137
|
+
const motion = nonDefault(input.motion, MOTION_DEFAULTS);
|
|
138
|
+
if (Object.keys(motion).length > 0) out.motion = motion;
|
|
139
|
+
const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS);
|
|
140
|
+
if (Object.keys(entrance).length > 0) out.entrance = entrance;
|
|
141
|
+
const scene = nonDefault(
|
|
142
|
+
sceneSchema.parse(input.scene ?? {}),
|
|
143
|
+
sceneSchema.parse({})
|
|
144
|
+
);
|
|
145
|
+
if (Object.keys(scene).length > 0) out.scene = scene;
|
|
146
|
+
return out;
|
|
147
|
+
}
|
|
148
|
+
var LAYOUT_PHRASES = {
|
|
149
|
+
ring: "a ring you can see around",
|
|
150
|
+
fan: "a fanned swatch deck hinged at one corner",
|
|
151
|
+
spread: "a stack slid sideways, each sheet bowing further than the last",
|
|
152
|
+
pile: "a heap on a desk, the sheets underneath pressed flat",
|
|
153
|
+
wall: "a pinned studio wall of sheets, none hanging quite square",
|
|
154
|
+
spill: "a dropped stack caught mid-air, each sheet bent its own way",
|
|
155
|
+
sweep: "a specimen chart of one sheet at every stage of its deformation",
|
|
156
|
+
book: "an open book, its pages splayed from a shared spine",
|
|
157
|
+
accordion: "one continuous strip folded into a concertina",
|
|
158
|
+
rack: "prints stood in a row and leaning back against a wall",
|
|
159
|
+
sheet: "a stamp-block grid on a shared backing sheet"
|
|
160
|
+
};
|
|
161
|
+
function describeFieldConfig(input) {
|
|
162
|
+
const n = input.papers.length;
|
|
163
|
+
const stateful = input.papers.some((p) => p.preset.states || p.states);
|
|
164
|
+
const zones = input.zones ?? [];
|
|
165
|
+
const parts = [];
|
|
166
|
+
if (input.layout === "sheet") {
|
|
167
|
+
const rows = Number(input.layoutOptions?.rows ?? 2);
|
|
168
|
+
const columns = Number(input.layoutOptions?.columns ?? 5);
|
|
169
|
+
parts.push(`a ${rows}\xD7${columns} sheet of papers on a shared backing`);
|
|
170
|
+
} else {
|
|
171
|
+
const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`;
|
|
172
|
+
parts.push(`${n} papers arranged in ${layoutPhrase}`);
|
|
173
|
+
}
|
|
174
|
+
const driver = input.motion?.driver ?? "autoplay";
|
|
175
|
+
if (stateful) {
|
|
176
|
+
parts.push("hovering peels/reacts per paper (interaction states)");
|
|
177
|
+
if (zones.length > 0) {
|
|
178
|
+
parts.push(
|
|
179
|
+
`dragging one past its tear threshold detaches it to carry to the ${zones.map((z) => z.id).join(" or ")} zone (release elsewhere flutters it back)`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
if (driver === "autoplay") parts.push("slowly orbiting on their own");
|
|
184
|
+
if (driver === "drag") parts.push("draggable sideways with the pointer");
|
|
185
|
+
if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? "s" : ""}`);
|
|
186
|
+
}
|
|
187
|
+
const distinct = distinctFieldPresets(input);
|
|
188
|
+
if (distinct.length > 1) {
|
|
189
|
+
parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(", ")})`);
|
|
190
|
+
}
|
|
191
|
+
return parts.join(", ");
|
|
192
|
+
}
|
|
193
|
+
function buildFieldComponentSource(input) {
|
|
194
|
+
const distinct = distinctFieldPresets(input);
|
|
195
|
+
const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]));
|
|
196
|
+
const consts = distinct.map(
|
|
197
|
+
(d) => `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`
|
|
198
|
+
).join("\n\n");
|
|
199
|
+
const slots = input.papers.map((paper) => {
|
|
200
|
+
const varName = varByKey.get(JSON.stringify(paper.preset));
|
|
201
|
+
const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : "";
|
|
202
|
+
const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : "";
|
|
203
|
+
return ` { preset: ${varName}${content}${states} },`;
|
|
204
|
+
}).join("\n");
|
|
205
|
+
const props = Object.entries(diffFieldProps(input)).map(
|
|
206
|
+
([key, value]) => typeof value === "string" ? ` ${key}="${value}"` : ` ${key}={${JSON.stringify(value)}}`
|
|
207
|
+
).join("\n");
|
|
208
|
+
const zones = input.zones ?? [];
|
|
209
|
+
const zoneImport = zones.length > 0 ? ", DropZone" : "";
|
|
210
|
+
const zoneChildren = zones.map((zone) => {
|
|
211
|
+
const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : "";
|
|
212
|
+
const highlight = zone.highlight && zone.highlight !== "glow" ? ` highlight="${zone.highlight}"` : "";
|
|
213
|
+
return ` <DropZone
|
|
214
|
+
id="${zone.id}"${accept}
|
|
215
|
+
bounds={${JSON.stringify(zone.bounds)}}${highlight}
|
|
216
|
+
onPlace={(paper, zone) => {
|
|
217
|
+
// First-run smoke test \u2014 you should see this in the console on drop:
|
|
218
|
+
console.log(paper.presetName, '\u2192', zone.id)
|
|
219
|
+
// Then replace it: stamp a postmark, advance the flow, persist the placement, \u2026
|
|
220
|
+
}}
|
|
221
|
+
/>`;
|
|
222
|
+
}).join("\n");
|
|
223
|
+
if (zones.length === 0) {
|
|
224
|
+
return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'
|
|
225
|
+
|
|
226
|
+
${consts}
|
|
227
|
+
|
|
228
|
+
const papers: FieldPaperSlot[] = [
|
|
229
|
+
${slots}
|
|
230
|
+
]
|
|
231
|
+
|
|
232
|
+
export function PaperGallery() {
|
|
233
|
+
return (
|
|
234
|
+
<PaperField
|
|
235
|
+
papers={papers}
|
|
236
|
+
${props}
|
|
237
|
+
/>
|
|
238
|
+
)
|
|
239
|
+
}`;
|
|
240
|
+
}
|
|
241
|
+
return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'
|
|
242
|
+
|
|
243
|
+
${consts}
|
|
244
|
+
|
|
245
|
+
const papers: FieldPaperSlot[] = [
|
|
246
|
+
${slots}
|
|
247
|
+
]
|
|
248
|
+
|
|
249
|
+
export function PaperGallery() {
|
|
250
|
+
return (
|
|
251
|
+
<PaperField
|
|
252
|
+
papers={papers}
|
|
253
|
+
${props}
|
|
254
|
+
>
|
|
255
|
+
${zoneChildren}
|
|
256
|
+
</PaperField>
|
|
257
|
+
)
|
|
258
|
+
}`;
|
|
259
|
+
}
|
|
260
|
+
function buildFieldAgentPayload(input) {
|
|
261
|
+
return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})
|
|
262
|
+
|
|
263
|
+
1. Install the dependencies:
|
|
264
|
+
|
|
265
|
+
npm i paperlab three @react-three/fiber gsap
|
|
266
|
+
|
|
267
|
+
2. Create the component below as \`components/PaperGallery.tsx\` (or the
|
|
268
|
+
project's component convention). It is self-contained \u2014 every preset it
|
|
269
|
+
uses is inlined, and it owns its own <Canvas>:
|
|
270
|
+
|
|
271
|
+
\`\`\`tsx
|
|
272
|
+
${buildFieldComponentSource(input)}
|
|
273
|
+
\`\`\`
|
|
274
|
+
|
|
275
|
+
3. Sizing: the component fills its parent container. Place it where I ask;
|
|
276
|
+
give the parent an explicit height.
|
|
277
|
+
|
|
278
|
+
4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.
|
|
279
|
+
If the canvas is blank, the parent container almost certainly has no height \u2014
|
|
280
|
+
give it one (this is the classic React Three Fiber integration bug, not a
|
|
281
|
+
paperlab bug).
|
|
282
|
+
|
|
283
|
+
Constraints: don't modify the preset values; three >= 0.160 and React 19 are
|
|
284
|
+
required; the component needs no props.`;
|
|
285
|
+
}
|
|
286
|
+
|
|
211
287
|
// src/field/parity.ts
|
|
212
288
|
import * as THREE from "three";
|
|
213
289
|
var GRID = 48;
|
|
@@ -374,8 +450,8 @@ var parityCases = [
|
|
|
374
450
|
t: 0.8
|
|
375
451
|
}
|
|
376
452
|
];
|
|
377
|
-
function buildParityFragment(stack,
|
|
378
|
-
const composed = buildDisplacementGLSL(stack,
|
|
453
|
+
function buildParityFragment(stack, sheet) {
|
|
454
|
+
const composed = buildDisplacementGLSL(stack, sheet);
|
|
379
455
|
return (
|
|
380
456
|
/* glsl */
|
|
381
457
|
`#version 300 es
|
|
@@ -508,382 +584,79 @@ function runParityHarness(canvas) {
|
|
|
508
584
|
});
|
|
509
585
|
return [...parity, ...runBiasCases(gl)];
|
|
510
586
|
}
|
|
511
|
-
|
|
512
|
-
// src/config/field-export.ts
|
|
513
|
-
var MOTION_DEFAULTS = { driver: "autoplay", speed: 0.5 };
|
|
514
|
-
var ENTRANCE_DEFAULTS = { type: "rise", stagger: 0.06, duration: 0.9 };
|
|
515
|
-
function camel(name) {
|
|
516
|
-
const id = name.replace(/[^a-zA-Z0-9]+(.)/g, (_, c) => c.toUpperCase()).replace(/[^a-zA-Z0-9]/g, "");
|
|
517
|
-
const safe = /^[A-Za-z]/.test(id) ? id : `preset${id}`;
|
|
518
|
-
return safe.charAt(0).toLowerCase() + safe.slice(1);
|
|
519
|
-
}
|
|
520
|
-
function distinctFieldPresets(input) {
|
|
521
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
522
|
-
const usedNames = /* @__PURE__ */ new Set();
|
|
523
|
-
for (const paper of input.papers) {
|
|
524
|
-
const key = JSON.stringify(paper.preset);
|
|
525
|
-
if (byKey.has(key)) continue;
|
|
526
|
-
let varName = camel(paper.presetName);
|
|
527
|
-
while (usedNames.has(varName)) varName += "2";
|
|
528
|
-
usedNames.add(varName);
|
|
529
|
-
byKey.set(key, { varName, presetName: paper.presetName, preset: paper.preset });
|
|
530
|
-
}
|
|
531
|
-
return [...byKey.values()];
|
|
532
|
-
}
|
|
533
|
-
function nonDefault(value, defaults) {
|
|
534
|
-
const out = {};
|
|
535
|
-
for (const [k, v] of Object.entries(value ?? {})) {
|
|
536
|
-
if (v !== void 0 && v !== defaults[k]) out[k] = v;
|
|
537
|
-
}
|
|
538
|
-
return out;
|
|
539
|
-
}
|
|
540
|
-
function diffFieldProps(input) {
|
|
541
|
-
const out = { layout: input.layout };
|
|
542
|
-
const layout = getLayout(input.layout);
|
|
543
|
-
const layoutOptions = nonDefault(input.layoutOptions ?? {}, layout.defaults);
|
|
544
|
-
if (Object.keys(layoutOptions).length > 0) out.layoutOptions = layoutOptions;
|
|
545
|
-
const motion = nonDefault(input.motion, MOTION_DEFAULTS);
|
|
546
|
-
if (Object.keys(motion).length > 0) out.motion = motion;
|
|
547
|
-
const entrance = nonDefault(input.entrance, ENTRANCE_DEFAULTS);
|
|
548
|
-
if (Object.keys(entrance).length > 0) out.entrance = entrance;
|
|
549
|
-
return out;
|
|
550
|
-
}
|
|
551
|
-
var LAYOUT_PHRASES = {
|
|
552
|
-
ring: "a ring you can see around",
|
|
553
|
-
fan: "a fanned swatch deck hinged at one corner",
|
|
554
|
-
spread: "a stack slid sideways, each sheet bowing further than the last",
|
|
555
|
-
pile: "a heap on a desk, the sheets underneath pressed flat",
|
|
556
|
-
wall: "a pinned studio wall of sheets, none hanging quite square",
|
|
557
|
-
spill: "a dropped stack caught mid-air, each sheet bent its own way",
|
|
558
|
-
sweep: "a specimen chart of one sheet at every stage of its deformation",
|
|
559
|
-
book: "an open book, its pages splayed from a shared spine",
|
|
560
|
-
accordion: "one continuous strip folded into a concertina",
|
|
561
|
-
rack: "prints stood in a row and leaning back against a wall",
|
|
562
|
-
sheet: "a stamp-block grid on a shared backing sheet"
|
|
563
|
-
};
|
|
564
|
-
function describeFieldConfig(input) {
|
|
565
|
-
const n = input.papers.length;
|
|
566
|
-
const stateful = input.papers.some((p) => p.preset.states || p.states);
|
|
567
|
-
const zones = input.zones ?? [];
|
|
568
|
-
const parts = [];
|
|
569
|
-
if (input.layout === "sheet") {
|
|
570
|
-
const rows = Number(input.layoutOptions?.rows ?? 2);
|
|
571
|
-
const columns = Number(input.layoutOptions?.columns ?? 5);
|
|
572
|
-
parts.push(`a ${rows}\xD7${columns} sheet of papers on a shared backing`);
|
|
573
|
-
} else {
|
|
574
|
-
const layoutPhrase = LAYOUT_PHRASES[input.layout] ?? `a ${input.layout} layout`;
|
|
575
|
-
parts.push(`${n} papers arranged in ${layoutPhrase}`);
|
|
576
|
-
}
|
|
577
|
-
const driver = input.motion?.driver ?? "autoplay";
|
|
578
|
-
if (stateful) {
|
|
579
|
-
parts.push("hovering peels/reacts per paper (interaction states)");
|
|
580
|
-
if (zones.length > 0) {
|
|
581
|
-
parts.push(
|
|
582
|
-
`dragging one past its tear threshold detaches it to carry to the ${zones.map((z) => z.id).join(" or ")} zone (release elsewhere flutters it back)`
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
} else {
|
|
586
|
-
if (driver === "autoplay") parts.push("slowly orbiting on their own");
|
|
587
|
-
if (driver === "drag") parts.push("draggable sideways with the pointer");
|
|
588
|
-
if (zones.length > 0) parts.push(`${zones.length} drop zone${zones.length > 1 ? "s" : ""}`);
|
|
589
|
-
}
|
|
590
|
-
const distinct = distinctFieldPresets(input);
|
|
591
|
-
if (distinct.length > 1) {
|
|
592
|
-
parts.push(`mixing ${distinct.length} paper presets (${distinct.map((d) => d.presetName).join(", ")})`);
|
|
593
|
-
}
|
|
594
|
-
return parts.join(", ");
|
|
595
|
-
}
|
|
596
|
-
function buildFieldComponentSource(input) {
|
|
597
|
-
const distinct = distinctFieldPresets(input);
|
|
598
|
-
const varByKey = new Map(distinct.map((d) => [JSON.stringify(d.preset), d.varName]));
|
|
599
|
-
const consts = distinct.map(
|
|
600
|
-
(d) => `const ${d.varName} = ${JSON.stringify(diffConfig(d.preset), null, 2)} satisfies PaperConfigInput`
|
|
601
|
-
).join("\n\n");
|
|
602
|
-
const slots = input.papers.map((paper) => {
|
|
603
|
-
const varName = varByKey.get(JSON.stringify(paper.preset));
|
|
604
|
-
const content = paper.content ? `, content: ${JSON.stringify(paper.content)}` : "";
|
|
605
|
-
const states = paper.states ? `, states: ${JSON.stringify(paper.states)}` : "";
|
|
606
|
-
return ` { preset: ${varName}${content}${states} },`;
|
|
607
|
-
}).join("\n");
|
|
608
|
-
const props = Object.entries(diffFieldProps(input)).map(
|
|
609
|
-
([key, value]) => typeof value === "string" ? ` ${key}="${value}"` : ` ${key}={${JSON.stringify(value)}}`
|
|
610
|
-
).join("\n");
|
|
611
|
-
const zones = input.zones ?? [];
|
|
612
|
-
const zoneImport = zones.length > 0 ? ", DropZone" : "";
|
|
613
|
-
const zoneChildren = zones.map((zone) => {
|
|
614
|
-
const accept = zone.accept ? ` accept={${JSON.stringify(zone.accept)}}` : "";
|
|
615
|
-
const highlight = zone.highlight && zone.highlight !== "glow" ? ` highlight="${zone.highlight}"` : "";
|
|
616
|
-
return ` <DropZone
|
|
617
|
-
id="${zone.id}"${accept}
|
|
618
|
-
bounds={${JSON.stringify(zone.bounds)}}${highlight}
|
|
619
|
-
onPlace={(paper, zone) => {
|
|
620
|
-
// First-run smoke test \u2014 you should see this in the console on drop:
|
|
621
|
-
console.log(paper.presetName, '\u2192', zone.id)
|
|
622
|
-
// Then replace it: stamp a postmark, advance the flow, persist the placement, \u2026
|
|
623
|
-
}}
|
|
624
|
-
/>`;
|
|
625
|
-
}).join("\n");
|
|
626
|
-
if (zones.length === 0) {
|
|
627
|
-
return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'
|
|
628
|
-
|
|
629
|
-
${consts}
|
|
630
|
-
|
|
631
|
-
const papers: FieldPaperSlot[] = [
|
|
632
|
-
${slots}
|
|
633
|
-
]
|
|
634
|
-
|
|
635
|
-
export function PaperGallery() {
|
|
636
|
-
return (
|
|
637
|
-
<PaperField
|
|
638
|
-
papers={papers}
|
|
639
|
-
${props}
|
|
640
|
-
/>
|
|
641
|
-
)
|
|
642
|
-
}`;
|
|
643
|
-
}
|
|
644
|
-
return `import { PaperField, type FieldPaperSlot, type PaperConfigInput${zoneImport} } from 'paperlab'
|
|
645
|
-
|
|
646
|
-
${consts}
|
|
647
|
-
|
|
648
|
-
const papers: FieldPaperSlot[] = [
|
|
649
|
-
${slots}
|
|
650
|
-
]
|
|
651
|
-
|
|
652
|
-
export function PaperGallery() {
|
|
653
|
-
return (
|
|
654
|
-
<PaperField
|
|
655
|
-
papers={papers}
|
|
656
|
-
${props}
|
|
657
|
-
>
|
|
658
|
-
${zoneChildren}
|
|
659
|
-
</PaperField>
|
|
660
|
-
)
|
|
661
|
-
}`;
|
|
662
|
-
}
|
|
663
|
-
function buildFieldAgentPayload(input) {
|
|
664
|
-
return `Integrate a Paperlab paper gallery into this project. (paperlab agent-payload v${AGENT_PAYLOAD_VERSION})
|
|
665
|
-
|
|
666
|
-
1. Install the dependencies:
|
|
667
|
-
|
|
668
|
-
npm i paperlab three @react-three/fiber gsap
|
|
669
|
-
|
|
670
|
-
2. Create the component below as \`components/PaperGallery.tsx\` (or the
|
|
671
|
-
project's component convention). It is self-contained \u2014 every preset it
|
|
672
|
-
uses is inlined, and it owns its own <Canvas>:
|
|
673
|
-
|
|
674
|
-
\`\`\`tsx
|
|
675
|
-
${buildFieldComponentSource(input)}
|
|
676
|
-
\`\`\`
|
|
677
|
-
|
|
678
|
-
3. Sizing: the component fills its parent container. Place it where I ask;
|
|
679
|
-
give the parent an explicit height.
|
|
680
|
-
|
|
681
|
-
4. Verify: run the dev server. You should see ${describeFieldConfig(input)}.
|
|
682
|
-
If the canvas is blank, the parent container almost certainly has no height \u2014
|
|
683
|
-
give it one (this is the classic React Three Fiber integration bug, not a
|
|
684
|
-
paperlab bug).
|
|
685
|
-
|
|
686
|
-
Constraints: don't modify the preset values; three >= 0.160 and React 19 are
|
|
687
|
-
required; the component needs no props.`;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
// src/core/modes.ts
|
|
691
|
-
function resolveMode(requested, ctx) {
|
|
692
|
-
if (requested !== "auto") return requested;
|
|
693
|
-
if (ctx.interactive || ctx.physics !== "none" || ctx.count <= 10) return "hero";
|
|
694
|
-
return "field";
|
|
695
|
-
}
|
|
696
587
|
export {
|
|
697
|
-
AGENT_PAYLOAD_VERSION,
|
|
698
588
|
AUTO_CEILING,
|
|
699
|
-
ClothSim,
|
|
700
589
|
DropZone,
|
|
701
|
-
DropZoneRegistry,
|
|
702
590
|
FLAT_SEGMENTS,
|
|
703
591
|
LightRig,
|
|
704
|
-
ON_TWOS_FPS,
|
|
705
592
|
PARITY_EPSILON,
|
|
706
593
|
Paper,
|
|
707
|
-
|
|
594
|
+
PaperBackdrop,
|
|
708
595
|
PaperField,
|
|
709
596
|
PaperFieldMesh,
|
|
710
597
|
PaperLighting,
|
|
711
|
-
PaperMaterial,
|
|
712
598
|
PaperMesh,
|
|
713
|
-
PaperMirror,
|
|
714
|
-
PaperStateMachine,
|
|
715
599
|
SAG_TOL,
|
|
716
|
-
|
|
717
|
-
TRANSMISSION_GAIN,
|
|
718
|
-
accordion,
|
|
719
|
-
applyDeformerStack,
|
|
720
|
-
atlasGrid,
|
|
721
|
-
backContentSchema,
|
|
722
|
-
barcodeBars,
|
|
600
|
+
backdropSchema,
|
|
723
601
|
behaviorConfigSchema,
|
|
724
|
-
bend,
|
|
725
|
-
bendOptionsSchema,
|
|
726
|
-
book,
|
|
727
602
|
buildAgentPayload,
|
|
728
|
-
buildDisplacementGLSL,
|
|
729
603
|
buildFieldAgentPayload,
|
|
730
604
|
buildFieldComponentSource,
|
|
731
|
-
buildFieldFragmentShader,
|
|
732
|
-
buildFieldVertexShader,
|
|
733
605
|
buildJsxSnippet,
|
|
734
|
-
cardContentSchema,
|
|
735
|
-
carry,
|
|
736
|
-
carryDrive,
|
|
737
|
-
carryOptionsSchema,
|
|
738
606
|
clothConfigSchema,
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
contentSchema,
|
|
742
|
-
contentText,
|
|
607
|
+
contentNames,
|
|
608
|
+
contentSchemaFor,
|
|
743
609
|
coreStateNames,
|
|
744
|
-
cornerNames,
|
|
745
|
-
createSheetGeometry,
|
|
746
|
-
crumple,
|
|
747
|
-
crumpleBehavior,
|
|
748
|
-
crumpleBehaviorOptionsSchema,
|
|
749
|
-
crumpleOptionsSchema,
|
|
750
|
-
curl,
|
|
751
|
-
curlOptionsSchema,
|
|
752
|
-
dampTo,
|
|
753
|
-
deformerInstanceSchema,
|
|
754
610
|
describeConfig,
|
|
755
611
|
describeFieldConfig,
|
|
756
612
|
diffConfig,
|
|
757
613
|
diffFieldProps,
|
|
758
|
-
displacePoint,
|
|
759
|
-
distinctFieldPresets,
|
|
760
|
-
drape,
|
|
761
|
-
drapeOptionsSchema,
|
|
762
|
-
drawBacking,
|
|
763
|
-
fall,
|
|
764
|
-
fallOptionsSchema,
|
|
765
|
-
fan,
|
|
766
|
-
fieldBounds,
|
|
767
|
-
fieldKeyboardStep,
|
|
768
|
-
filmNames,
|
|
769
|
-
fitCamera,
|
|
770
|
-
flattenNumeric,
|
|
771
|
-
flight,
|
|
772
|
-
flightOptionsSchema,
|
|
773
|
-
flightPose,
|
|
774
|
-
flip,
|
|
775
|
-
flipOptionsSchema,
|
|
776
|
-
fly,
|
|
777
|
-
flyOptionsSchema,
|
|
778
|
-
fold,
|
|
779
|
-
foldOptionsSchema,
|
|
780
614
|
getBehavior,
|
|
781
615
|
getDeformer,
|
|
782
|
-
getIdlePreset,
|
|
783
616
|
getLayout,
|
|
784
|
-
getLightingPreset,
|
|
785
617
|
getPreset,
|
|
786
618
|
getStock,
|
|
787
|
-
groupFieldPapers,
|
|
788
|
-
gust,
|
|
789
|
-
hang,
|
|
790
|
-
hangOptionsSchema,
|
|
791
619
|
idleNames,
|
|
792
|
-
idlePresets,
|
|
793
620
|
isBuiltinPreset,
|
|
794
|
-
letterFold,
|
|
795
|
-
letterFoldOptionsSchema,
|
|
796
621
|
lightAngles,
|
|
797
|
-
lightPosition,
|
|
798
622
|
lightSchema,
|
|
799
|
-
lightenHex,
|
|
800
623
|
lightingNames,
|
|
801
|
-
lightingPresets,
|
|
802
624
|
listBehaviors,
|
|
803
625
|
listDeformers,
|
|
804
626
|
listLayouts,
|
|
805
627
|
listPresets,
|
|
806
|
-
makeGoboTexture,
|
|
807
628
|
mergeConfig,
|
|
808
629
|
mergeWithDeletes,
|
|
809
|
-
outwardCorner,
|
|
810
630
|
paperConfigSchema,
|
|
811
631
|
paperEdges,
|
|
812
632
|
paperStatesSchema,
|
|
813
633
|
parityCases,
|
|
814
634
|
parsePreset,
|
|
815
|
-
peel,
|
|
816
|
-
peelOptionsSchema,
|
|
817
635
|
physicsNames,
|
|
818
|
-
physicsSchema,
|
|
819
|
-
pile,
|
|
820
|
-
quantizeProgress,
|
|
821
636
|
quantizeSegments,
|
|
822
|
-
quantizeTime,
|
|
823
|
-
rack,
|
|
824
|
-
receiptContentSchema,
|
|
825
|
-
receiptTotals,
|
|
826
637
|
recordStateOverride,
|
|
827
638
|
registerBehavior,
|
|
828
639
|
registerDeformer,
|
|
829
640
|
registerLayout,
|
|
830
641
|
registerPreset,
|
|
831
|
-
resolveConfig,
|
|
832
|
-
resolveDeformerStack,
|
|
833
|
-
resolveFieldSlotConfig,
|
|
834
642
|
resolveLighting,
|
|
835
|
-
resolveMode,
|
|
836
|
-
resolveSegments,
|
|
837
643
|
resolveStateConfig,
|
|
838
|
-
ribbon,
|
|
839
|
-
ribbonOptionsSchema,
|
|
840
|
-
ring,
|
|
841
|
-
roll,
|
|
842
|
-
rollOptionsSchema,
|
|
843
644
|
runParityHarness,
|
|
844
645
|
sceneSchema,
|
|
845
646
|
segmentsForArc,
|
|
846
647
|
segmentsForSine,
|
|
847
648
|
serializePreset,
|
|
848
|
-
settle,
|
|
849
|
-
settleOptionsSchema,
|
|
850
|
-
sheet,
|
|
851
|
-
sheetBackingSize,
|
|
852
649
|
sheetLayoutSchema,
|
|
853
|
-
sheetSchema,
|
|
854
|
-
sheetSlotXY,
|
|
855
|
-
silhouetteRects,
|
|
856
650
|
spanAlong,
|
|
857
|
-
spill,
|
|
858
|
-
spread,
|
|
859
|
-
stackAutoSegments,
|
|
860
|
-
stackMinSegments,
|
|
861
|
-
stackUniformValues,
|
|
862
651
|
stateDefSchema,
|
|
863
|
-
stateEventTransitions,
|
|
864
|
-
stateTransitionSchema,
|
|
865
652
|
stockNames,
|
|
866
|
-
stockSchema,
|
|
867
653
|
stocks,
|
|
868
|
-
stripStates,
|
|
869
654
|
supportsWebGL,
|
|
870
|
-
surfaceSchema,
|
|
871
|
-
sweep,
|
|
872
|
-
tornEdgesOnDetach,
|
|
873
|
-
translucencyUniforms,
|
|
874
|
-
translucencyValues,
|
|
875
655
|
uniquePresetName,
|
|
876
656
|
unregisterPreset,
|
|
877
|
-
unroll,
|
|
878
|
-
unrollOptionsSchema,
|
|
879
|
-
useContentAtlas,
|
|
880
657
|
usePaperStates,
|
|
881
658
|
usePrefersReducedMotion,
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
waveOptionsSchema,
|
|
885
|
-
withSheetCellFromPaper,
|
|
886
|
-
wrapLines,
|
|
887
|
-
zoneAccepts
|
|
659
|
+
washSchema,
|
|
660
|
+
wrapLines
|
|
888
661
|
};
|
|
889
662
|
//# sourceMappingURL=index.js.map
|