anim-3d-obj 2.0.8 → 2.0.10

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/index.cjs CHANGED
@@ -230,6 +230,10 @@ var Obj = React__namespace.memo(
230
230
  oneAtATime = false,
231
231
  remainJoined = false,
232
232
  ytilt = false,
233
+ backfaceHidden = false,
234
+ chainEffects,
235
+ onChainComplete,
236
+ onChainReverseComplete,
233
237
  className,
234
238
  style
235
239
  }) => {
@@ -238,7 +242,131 @@ var Obj = React__namespace.memo(
238
242
  const d = typeof depth === "number" ? depth : parseFloat(String(depth));
239
243
  const animation1 = toAnimationShorthand(anim1) ?? void 0;
240
244
  const animation2 = toAnimationShorthand(anim2) ?? void 0;
245
+ const [phase, setPhase] = React__namespace.useState(
246
+ flat ? "chained" : "folded"
247
+ );
248
+ const hasChain = Array.isArray(chainEffects) && chainEffects.length > 0;
249
+ const sideCountRef = React__namespace.useRef(0);
250
+ const chainDur = React__namespace.useMemo(() => {
251
+ if (!hasChain) return 0;
252
+ return Math.max(
253
+ 0,
254
+ ...chainEffects.map(
255
+ (e) => (e.duration ?? 0.5) + (e.delay ?? 0)
256
+ )
257
+ );
258
+ }, [chainEffects, hasChain]);
259
+ const prevFlatForChain = React__namespace.useRef(flat);
260
+ React__namespace.useEffect(() => {
261
+ if (flat === prevFlatForChain.current) return;
262
+ prevFlatForChain.current = flat;
263
+ if (flat) {
264
+ setPhase("unfolding");
265
+ } else {
266
+ if (hasChain && (phase === "chained" || phase === "chaining")) {
267
+ setPhase("unchaining");
268
+ } else {
269
+ setPhase("folding");
270
+ }
271
+ }
272
+ }, [flat]);
273
+ React__namespace.useEffect(() => {
274
+ let timer;
275
+ if (phase === "unfolding") {
276
+ const sideCount = sideCountRef.current;
277
+ const unfoldDur = oneAtATime ? transitionDuration * sideCount : transitionDuration;
278
+ timer = setTimeout(() => {
279
+ if (hasChain) {
280
+ setPhase("chaining");
281
+ } else {
282
+ setPhase("chained");
283
+ onChainComplete?.();
284
+ }
285
+ }, unfoldDur * 1e3 + 60);
286
+ }
287
+ if (phase === "chaining") {
288
+ timer = setTimeout(() => {
289
+ setPhase("chained");
290
+ onChainComplete?.();
291
+ }, chainDur * 1e3 + 60);
292
+ }
293
+ if (phase === "unchaining") {
294
+ timer = setTimeout(() => {
295
+ setPhase("folding");
296
+ }, chainDur * 1e3 + 60);
297
+ }
298
+ if (phase === "folding") {
299
+ const sideCount = sideCountRef.current;
300
+ const foldDur = oneAtATime ? transitionDuration * sideCount : transitionDuration;
301
+ timer = setTimeout(() => {
302
+ setPhase("folded");
303
+ onChainReverseComplete?.();
304
+ }, foldDur * 1e3 + 60);
305
+ }
306
+ return () => {
307
+ if (timer) clearTimeout(timer);
308
+ };
309
+ }, [
310
+ phase,
311
+ hasChain,
312
+ chainDur,
313
+ transitionDuration,
314
+ oneAtATime,
315
+ onChainComplete,
316
+ onChainReverseComplete
317
+ ]);
318
+ const isFlatNow = phase === "unfolding" || phase === "chaining" || phase === "chained" || phase === "unchaining";
319
+ const chainActive = phase === "chaining" || phase === "chained";
320
+ const chainMap = React__namespace.useMemo(() => {
321
+ const map = /* @__PURE__ */ new Map();
322
+ if (chainEffects) {
323
+ for (const e of chainEffects) {
324
+ map.set(e.faceName, e);
325
+ }
326
+ }
327
+ return map;
328
+ }, [chainEffects]);
329
+ function chainStyle(faceName) {
330
+ const eff = chainMap.get(faceName);
331
+ if (!eff) return {};
332
+ const dur = (eff.duration ?? 0.5) + "s";
333
+ const delay = (eff.delay ?? 0) + "s";
334
+ const timing = eff.timing ?? "ease-in-out";
335
+ const props = [];
336
+ const styles = {};
337
+ if (eff.scaleX !== void 0 || eff.scaleY !== void 0) {
338
+ const sx = eff.scaleX ?? 1;
339
+ const sy = eff.scaleY ?? 1;
340
+ if (chainActive) {
341
+ styles.transform = (styles.transform ?? "") + ` scaleX(${sx}) scaleY(${sy})`;
342
+ }
343
+ props.push("transform");
344
+ }
345
+ if (eff.background !== void 0) {
346
+ if (chainActive) {
347
+ styles.background = eff.background;
348
+ }
349
+ props.push("background");
350
+ }
351
+ if (eff.opacity !== void 0) {
352
+ if (chainActive) {
353
+ styles.opacity = eff.opacity;
354
+ }
355
+ props.push("opacity");
356
+ }
357
+ if (props.length > 0) {
358
+ const transitionParts = props.map(
359
+ (p) => `${p} ${dur} ${timing} ${delay}`
360
+ );
361
+ styles.transition = transitionParts.join(", ");
362
+ }
363
+ return styles;
364
+ }
241
365
  const faceList = faces && faces.length > 0 ? faces : DEFAULT_FACE_NAMES.map((name) => ({ name }));
366
+ sideCountRef.current = faceList.filter(
367
+ (f) => ["front", "right", "back", "left"].includes(f.name)
368
+ ).length;
369
+ const bfv = backfaceHidden ? "hidden" : "visible";
242
370
  const transitionCss = (delay = 0) => `transform ${transitionDuration}s ease-in-out ${delay}s`;
243
371
  const tiltCount = React__namespace.useRef(0);
244
372
  const prevFlat = React__namespace.useRef(flat);
@@ -268,7 +396,7 @@ var Obj = React__namespace.memo(
268
396
  }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);
269
397
  const renderStandard = () => faceList.map((face, i) => {
270
398
  const dims = faceDimensions(face.name, w, h, d);
271
- const transform = flat ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
399
+ const baseTransform = isFlatNow ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
272
400
  const {
273
401
  style: fStyle,
274
402
  className: fCls,
@@ -276,16 +404,23 @@ var Obj = React__namespace.memo(
276
404
  } = faceAppearance(face, globalDef);
277
405
  const idx = STAGGER_ORDER.indexOf(face.name);
278
406
  const delay = oneAtATime ? (idx >= 0 ? idx : i) * transitionDuration : 0;
407
+ const cStyle = chainStyle(face.name);
408
+ const scaleAppend = cStyle.transform ? ` ${cStyle.transform}` : "";
409
+ const transform = baseTransform + scaleAppend;
410
+ const foldTransition = transitionCss(delay);
411
+ const combinedTransition = cStyle.transition ? `${foldTransition}, ${cStyle.transition}` : foldTransition;
279
412
  return /* @__PURE__ */ jsxRuntime.jsx(
280
413
  "div",
281
414
  {
282
415
  className: fCls,
283
416
  style: {
284
417
  ...fStyle,
418
+ ...cStyle,
285
419
  width: dims.width,
286
420
  height: dims.height,
287
421
  transform,
288
- transition: transitionCss(delay)
422
+ transition: combinedTransition,
423
+ backfaceVisibility: bfv
289
424
  },
290
425
  children: body
291
426
  },
@@ -315,19 +450,29 @@ var Obj = React__namespace.memo(
315
450
  className: fCls,
316
451
  body
317
452
  } = faceAppearance(face, globalDef);
453
+ const cStyle = chainStyle(face.name);
454
+ const baseTransform = extra.transform ?? "";
455
+ const scaleAppend = cStyle.transform ? ` ${cStyle.transform}` : "";
456
+ const mergedTransform = baseTransform ? `${baseTransform}${scaleAppend}` : scaleAppend || void 0;
457
+ const foldTransition = extra.transition ?? "";
458
+ const combinedTransition = cStyle.transition ? `${foldTransition}, ${cStyle.transition}` : foldTransition;
318
459
  return /* @__PURE__ */ jsxRuntime.jsx(
319
460
  "div",
320
461
  {
321
462
  className: fCls,
322
463
  style: {
323
464
  ...fStyle,
465
+ ...cStyle,
324
466
  width: dims.width,
325
467
  height: dims.height,
326
468
  display: "flex",
327
469
  alignItems: "center",
328
470
  justifyContent: "center",
329
471
  boxSizing: "border-box",
330
- ...extra
472
+ backfaceVisibility: bfv,
473
+ ...extra,
474
+ transform: mergedTransform ?? extra.transform,
475
+ transition: combinedTransition || extra.transition
331
476
  },
332
477
  children: body
333
478
  },
@@ -342,7 +487,7 @@ var Obj = React__namespace.memo(
342
487
  position: "absolute",
343
488
  left: "50%",
344
489
  top: "50%",
345
- transform: flat ? "translate(-50%, -50%)" : `translate(-50%, -50%) translateZ(${d / 2}px)`,
490
+ transform: isFlatNow ? "translate(-50%, -50%)" : `translate(-50%, -50%) translateZ(${d / 2}px)`,
346
491
  transition: transitionCss(0)
347
492
  },
348
493
  "front-j"
@@ -358,7 +503,7 @@ var Obj = React__namespace.memo(
358
503
  height: 0,
359
504
  transformOrigin: "0 0",
360
505
  transformStyle: "preserve-3d",
361
- transform: flat ? "none" : `translateZ(${d / 2}px) rotateY(90deg)`,
506
+ transform: isFlatNow ? "none" : `translateZ(${d / 2}px) rotateY(90deg)`,
362
507
  transition: transitionCss(step)
363
508
  },
364
509
  children: [
@@ -384,7 +529,7 @@ var Obj = React__namespace.memo(
384
529
  height: 0,
385
530
  transformOrigin: "0 0",
386
531
  transformStyle: "preserve-3d",
387
- transform: flat ? "none" : "rotateY(90deg)",
532
+ transform: isFlatNow ? "none" : "rotateY(90deg)",
388
533
  transition: transitionCss(step * 2)
389
534
  },
390
535
  children: [
@@ -410,7 +555,7 @@ var Obj = React__namespace.memo(
410
555
  height: 0,
411
556
  transformOrigin: "0 0",
412
557
  transformStyle: "preserve-3d",
413
- transform: flat ? "none" : "rotateY(90deg)",
558
+ transform: isFlatNow ? "none" : "rotateY(90deg)",
414
559
  transition: transitionCss(step * 3)
415
560
  },
416
561
  children: renderFaceEl(
@@ -434,7 +579,7 @@ var Obj = React__namespace.memo(
434
579
  ),
435
580
  otherFaces.map((face, i) => {
436
581
  const dims = faceDimensions(face.name, w, h, d);
437
- const xform = flat ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
582
+ const xform = isFlatNow ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
438
583
  const {
439
584
  style: fStyle,
440
585
  className: fCls,
@@ -449,7 +594,8 @@ var Obj = React__namespace.memo(
449
594
  width: dims.width,
450
595
  height: dims.height,
451
596
  transform: xform,
452
- transition: transitionCss(0)
597
+ transition: transitionCss(0),
598
+ backfaceVisibility: bfv
453
599
  },
454
600
  children: body
455
601
  },
@@ -489,7 +635,7 @@ var Obj = React__namespace.memo(
489
635
  className: "anim3d-wrapper",
490
636
  style: {
491
637
  ...cssVars,
492
- animation: flat ? "none" : animation1,
638
+ animation: isFlatNow ? "none" : animation1,
493
639
  transformStyle: "preserve-3d",
494
640
  transition: transitionCss()
495
641
  },
@@ -499,7 +645,7 @@ var Obj = React__namespace.memo(
499
645
  className: "anim3d-wrapper",
500
646
  style: {
501
647
  ...cssVars,
502
- animation: flat ? "none" : animation2,
648
+ animation: isFlatNow ? "none" : animation2,
503
649
  transformStyle: "preserve-3d",
504
650
  transition: transitionCss()
505
651
  },
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/keyframes.ts","../src/components/Obj.tsx"],"names":["React","jsx","jsxs","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AnimationConfig } from \"./types\";\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n","import * as React from \"react\";\nimport type {\n ObjProps,\n FaceDef,\n FaceName,\n GlobalDef,\n} from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n// Re-export the canonical ObjProps from types.ts\nexport type { ObjProps } from \"../types\";\n\n/* ------------------------------------------------------------------ */\n/* Face transform — 3D cuboid positions */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransform3D(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const hw = w / 2;\n const hh = h / 2;\n const hd = d / 2;\n\n switch (name as FaceName) {\n case \"front\":\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n case \"back\":\n return `translate(-50%, -50%) rotateY(180deg) translateZ(${hd}px)`;\n case \"left\":\n return `translate(-50%, -50%) rotateY(-90deg) translateZ(${hw}px)`;\n case \"right\":\n return `translate(-50%, -50%) rotateY(90deg) translateZ(${hw}px)`;\n case \"top\":\n return `translate(-50%, -50%) rotateX(90deg) translateZ(${hh}px)`;\n case \"bottom\":\n return `translate(-50%, -50%) rotateX(-90deg) translateZ(${hh}px)`;\n case \"top_front\":\n return `translate(-50%, -50%) rotateX(45deg) translateZ(${hh}px)`;\n case \"top_rear\":\n return `translate(-50%, -50%) rotateX(135deg) translateZ(${hh}px)`;\n case \"bottom_front\":\n return `translate(-50%, -50%) rotateX(-45deg) translateZ(${hh}px)`;\n case \"bottom_rear\":\n return `translate(-50%, -50%) rotateX(-135deg) translateZ(${hh}px)`;\n default:\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Face transform — flat (unfolded) positions */\n/* */\n/* Flat order: front | right | back | left */\n/* Centred on the midpoint of the full row. */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransformFlat(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const total = 2 * w + 2 * d;\n const half = total / 2;\n\n let cx: number;\n\n switch (name as FaceName) {\n case \"front\":\n cx = w / 2;\n break;\n case \"right\":\n cx = w + d / 2;\n break;\n case \"back\":\n cx = w + d + w / 2;\n break;\n case \"left\":\n cx = w + d + w + d / 2;\n break;\n case \"top\":\n case \"top_front\":\n case \"top_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(-${h}px)`;\n case \"bottom\":\n case \"bottom_front\":\n case \"bottom_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(${h}px)`;\n default:\n cx = w / 2;\n break;\n }\n\n return `translate(-50%, -50%) translateX(${cx - half}px)`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a legacy CSS text string into a CSSProperties object */\n/* ------------------------------------------------------------------ */\n\nfunction parseCssText(css?: string): React.CSSProperties {\n if (!css) return {};\n const style: Record<string, string> = {};\n css.split(\";\").forEach((rule) => {\n const [prop, ...rest] = rule.split(\":\");\n if (!prop || rest.length === 0) return;\n const key = prop\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n style[key] = rest.join(\":\").trim();\n });\n return style as React.CSSProperties;\n}\n\n/* ------------------------------------------------------------------ */\n/* Resolve face dimensions for non-standard faces */\n/* ------------------------------------------------------------------ */\n\nfunction faceDimensions(\n name: string,\n w: number,\n h: number,\n d: number\n): { width: number; height: number } {\n switch (name as FaceName) {\n case \"left\":\n case \"right\":\n return { width: d, height: h };\n case \"top\":\n case \"bottom\":\n case \"top_front\":\n case \"top_rear\":\n case \"bottom_front\":\n case \"bottom_rear\":\n return { width: w, height: d };\n default:\n return { width: w, height: h };\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Build appearance style for a face (colours, borders, etc.) */\n/* Does NOT include position / transform / size. */\n/* ------------------------------------------------------------------ */\n\nfunction faceAppearance(\n face: FaceDef,\n globalDef?: GlobalDef\n): {\n style: React.CSSProperties;\n className: string;\n body: React.ReactNode;\n} {\n const globalStyle = parseCssText(globalDef?.css);\n const faceInlineStyle = parseCssText(face.css);\n\n const style: React.CSSProperties = {\n ...globalStyle,\n ...(globalDef?.style ?? {}),\n ...faceInlineStyle,\n ...(face.style ?? {}),\n };\n\n const className = [\"anim3d-face\", face.className]\n .filter(Boolean)\n .join(\" \");\n\n const body = face.body ?? globalDef?.body ?? null;\n\n return { style, className, body };\n}\n\n/* ------------------------------------------------------------------ */\n/* Default 6-sided cube when no faces are provided */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_FACE_NAMES: FaceName[] = [\n \"front\",\n \"back\",\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Stagger order for oneAtATime (standard mode) */\n/* ------------------------------------------------------------------ */\n\nconst STAGGER_ORDER: string[] = [\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n \"top\",\n \"bottom\",\n \"top_front\",\n \"top_rear\",\n \"bottom_front\",\n \"bottom_rear\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Obj: React.FC<ObjProps> = React.memo(\n ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 600,\n perspectiveOrigin = \"50% 50%\",\n faces,\n global: globalDef,\n anim1,\n anim2,\n showCenterDiv = false,\n flat = false,\n transitionDuration = 1,\n oneAtATime = false,\n remainJoined = false,\n ytilt = false,\n className,\n style,\n }) => {\n const w =\n typeof width === \"number\" ? width : parseFloat(String(width));\n const h =\n typeof height === \"number\" ? height : parseFloat(String(height));\n const d =\n typeof depth === \"number\" ? depth : parseFloat(String(depth));\n\n // Resolve animation shorthands\n const animation1 = toAnimationShorthand(anim1) ?? undefined;\n const animation2 = toAnimationShorthand(anim2) ?? undefined;\n\n // Determine which faces to render\n const faceList: FaceDef[] =\n faces && faces.length > 0\n ? faces\n : DEFAULT_FACE_NAMES.map((name) => ({ name }));\n\n const transitionCss = (delay = 0) =>\n `transform ${transitionDuration}s ease-in-out ${delay}s`;\n\n /* ============================================================ */\n /* Y-tilt — fire a one-shot rotateX(0→45→0) each time */\n /* flat changes. We alternate between two identical keyframe */\n /* names (a/b) so the browser re-triggers the animation. */\n /* ============================================================ */\n\n const tiltCount = React.useRef(0);\n const prevFlat = React.useRef(flat);\n const [tiltAnim, setTiltAnim] = React.useState<\n string | undefined\n >(undefined);\n\n React.useEffect(() => {\n if (flat !== prevFlat.current) {\n prevFlat.current = flat;\n if (ytilt) {\n tiltCount.current += 1;\n const sideCount = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(\n f.name\n )\n ).length;\n const totalDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n const name =\n tiltCount.current % 2 === 0\n ? \"anim3d-ytilt-a\"\n : \"anim3d-ytilt-b\";\n setTiltAnim(\n `${name} ${totalDur}s ease-in-out 1 forwards`\n );\n // Clear animation after it completes so it can re-trigger\n const timer = setTimeout(\n () => setTiltAnim(undefined),\n totalDur * 1000 + 50\n );\n return () => clearTimeout(timer);\n }\n }\n }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);\n\n /* ============================================================ */\n /* Standard rendering (no remainJoined) */\n /* ============================================================ */\n\n const renderStandard = () =>\n faceList.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const transform = flat\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n const idx = STAGGER_ORDER.indexOf(face.name);\n const delay = oneAtATime\n ? (idx >= 0 ? idx : i) * transitionDuration\n : 0;\n\n return (\n <div\n key={face.name + \"-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform,\n transition: transitionCss(delay),\n }}\n >\n {body}\n </div>\n );\n });\n\n /* ============================================================ */\n /* Joined rendering — nested hinge structure */\n /* */\n /* Chain: front → right → back → left (hinged at shared edges) */\n /* The left–front edge is the break‑point. */\n /* */\n /* Flat order: front | right | back | left (left on far right) */\n /* ============================================================ */\n\n const renderJoined = () => {\n const findFace = (n: string) =>\n faceList.find((f) => f.name === n);\n\n const frontFace = findFace(\"front\");\n const rightFace = findFace(\"right\");\n const backFace = findFace(\"back\");\n const leftFace = findFace(\"left\");\n\n const sideNames = new Set([\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n ]);\n const otherFaces = faceList.filter(\n (f) => !sideNames.has(f.name)\n );\n\n const step = oneAtATime ? transitionDuration : 0;\n\n /* Helper: render a single face element with merged styles */\n const renderFaceEl = (\n face: FaceDef | undefined,\n dims: { width: number; height: number },\n extra: React.CSSProperties,\n key: string\n ) => {\n if (!face) return null;\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={key}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxSizing: \"border-box\",\n ...extra,\n }}\n >\n {body}\n </div>\n );\n };\n\n return (\n <>\n {/* ---- Front face (anchor) ---- */}\n {renderFaceEl(\n frontFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: \"50%\",\n top: \"50%\",\n transform: flat\n ? \"translate(-50%, -50%)\"\n : `translate(-50%, -50%) translateZ(${d / 2}px)`,\n transition: transitionCss(0),\n },\n \"front-j\"\n )}\n\n {/* ---- Right hinge (pivots at front's right edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: `calc(50% + ${w / 2}px)`,\n top: \"50%\",\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : `translateZ(${d / 2}px) rotateY(90deg)`,\n transition: transitionCss(step),\n }}\n >\n {/* Right face */}\n {renderFaceEl(\n rightFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"right-j\"\n )}\n\n {/* ---- Back hinge (pivots at right's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: d,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 2),\n }}\n >\n {/* Back face */}\n {renderFaceEl(\n backFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"back-j\"\n )}\n\n {/* ---- Left hinge (pivots at back's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: w,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 3),\n }}\n >\n {/* Left face */}\n {renderFaceEl(\n leftFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"left-j\"\n )}\n </div>\n </div>\n </div>\n\n {/* ---- Non-side faces (top, bottom, etc.) ---- */}\n {otherFaces.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const xform = flat\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={face.name + \"-o-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform: xform,\n transition: transitionCss(0),\n }}\n >\n {body}\n </div>\n );\n })}\n </>\n );\n };\n\n /* ============================================================ */\n /* Render tree */\n /* ============================================================ */\n\n const cssVars = {\n \"--obj-w\": w + \"px\",\n \"--obj-h\": h + \"px\",\n \"--obj-d\": d + \"px\",\n } as React.CSSProperties;\n\n return (\n <div\n className={[\"anim3d-stage\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{\n perspective,\n perspectiveOrigin,\n ...cssVars,\n ...style,\n }}\n data-anim-3d-obj\n role=\"img\"\n aria-label=\"3D object\"\n >\n {/* Y-tilt wrapper — sits between stage and anim wrappers */}\n <div\n style={{\n transformStyle: \"preserve-3d\",\n animation: tiltAnim,\n }}\n >\n {/* Outer animation wrapper (anim1) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: flat ? \"none\" : animation1,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {/* Inner animation wrapper (anim2) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: flat ? \"none\" : animation2,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {showCenterDiv && (\n <div className=\"anim3d-center\" />\n )}\n {remainJoined\n ? renderJoined()\n : renderStandard()}\n </div>\n </div>\n </div>\n </div>\n );\n }\n);\n\nObj.displayName = \"Obj\";\n"]}
1
+ {"version":3,"sources":["../src/keyframes.ts","../src/components/Obj.tsx"],"names":["React","jsx","jsxs","Fragment"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { AnimationConfig } from \"./types\";\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n","import * as React from \"react\";\nimport type {\n ObjProps,\n FaceDef,\n FaceName,\n FaceChainEffect,\n GlobalDef,\n} from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n// Re-export the canonical ObjProps from types.ts\nexport type { ObjProps } from \"../types\";\n\n/* ------------------------------------------------------------------ */\n/* Face transform — 3D cuboid positions */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransform3D(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const hw = w / 2;\n const hh = h / 2;\n const hd = d / 2;\n\n switch (name as FaceName) {\n case \"front\":\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n case \"back\":\n return `translate(-50%, -50%) rotateY(180deg) translateZ(${hd}px)`;\n case \"left\":\n return `translate(-50%, -50%) rotateY(-90deg) translateZ(${hw}px)`;\n case \"right\":\n return `translate(-50%, -50%) rotateY(90deg) translateZ(${hw}px)`;\n case \"top\":\n return `translate(-50%, -50%) rotateX(90deg) translateZ(${hh}px)`;\n case \"bottom\":\n return `translate(-50%, -50%) rotateX(-90deg) translateZ(${hh}px)`;\n case \"top_front\":\n return `translate(-50%, -50%) rotateX(45deg) translateZ(${hh}px)`;\n case \"top_rear\":\n return `translate(-50%, -50%) rotateX(135deg) translateZ(${hh}px)`;\n case \"bottom_front\":\n return `translate(-50%, -50%) rotateX(-45deg) translateZ(${hh}px)`;\n case \"bottom_rear\":\n return `translate(-50%, -50%) rotateX(-135deg) translateZ(${hh}px)`;\n default:\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Face transform — flat (unfolded) positions */\n/* */\n/* Flat order: front | right | back | left */\n/* Centred on the midpoint of the full row. */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransformFlat(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const total = 2 * w + 2 * d;\n const half = total / 2;\n\n let cx: number;\n\n switch (name as FaceName) {\n case \"front\":\n cx = w / 2;\n break;\n case \"right\":\n cx = w + d / 2;\n break;\n case \"back\":\n cx = w + d + w / 2;\n break;\n case \"left\":\n cx = w + d + w + d / 2;\n break;\n case \"top\":\n case \"top_front\":\n case \"top_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(-${h}px)`;\n case \"bottom\":\n case \"bottom_front\":\n case \"bottom_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(${h}px)`;\n default:\n cx = w / 2;\n break;\n }\n\n return `translate(-50%, -50%) translateX(${cx - half}px)`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a legacy CSS text string into a CSSProperties object */\n/* ------------------------------------------------------------------ */\n\nfunction parseCssText(css?: string): React.CSSProperties {\n if (!css) return {};\n const style: Record<string, string> = {};\n css.split(\";\").forEach((rule) => {\n const [prop, ...rest] = rule.split(\":\");\n if (!prop || rest.length === 0) return;\n const key = prop\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n style[key] = rest.join(\":\").trim();\n });\n return style as React.CSSProperties;\n}\n\n/* ------------------------------------------------------------------ */\n/* Resolve face dimensions for non-standard faces */\n/* ------------------------------------------------------------------ */\n\nfunction faceDimensions(\n name: string,\n w: number,\n h: number,\n d: number\n): { width: number; height: number } {\n switch (name as FaceName) {\n case \"left\":\n case \"right\":\n return { width: d, height: h };\n case \"top\":\n case \"bottom\":\n case \"top_front\":\n case \"top_rear\":\n case \"bottom_front\":\n case \"bottom_rear\":\n return { width: w, height: d };\n default:\n return { width: w, height: h };\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Build appearance style for a face (colours, borders, etc.) */\n/* Does NOT include position / transform / size. */\n/* ------------------------------------------------------------------ */\n\nfunction faceAppearance(\n face: FaceDef,\n globalDef?: GlobalDef\n): {\n style: React.CSSProperties;\n className: string;\n body: React.ReactNode;\n} {\n const globalStyle = parseCssText(globalDef?.css);\n const faceInlineStyle = parseCssText(face.css);\n\n const style: React.CSSProperties = {\n ...globalStyle,\n ...(globalDef?.style ?? {}),\n ...faceInlineStyle,\n ...(face.style ?? {}),\n };\n\n const className = [\"anim3d-face\", face.className]\n .filter(Boolean)\n .join(\" \");\n\n const body = face.body ?? globalDef?.body ?? null;\n\n return { style, className, body };\n}\n\n/* ------------------------------------------------------------------ */\n/* Default 6-sided cube when no faces are provided */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_FACE_NAMES: FaceName[] = [\n \"front\",\n \"back\",\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Stagger order for oneAtATime (standard mode) */\n/* ------------------------------------------------------------------ */\n\nconst STAGGER_ORDER: string[] = [\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n \"top\",\n \"bottom\",\n \"top_front\",\n \"top_rear\",\n \"bottom_front\",\n \"bottom_rear\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\n/**\n * Animation phase state machine:\n *\n * folded ──(flat=true)──► unfolding ──(done)──► chaining ──(done)──► chained\n * ▲ │\n * └──(done)── folding ◄──(done)── unchaining ◄──(flat=false)──────────┘\n *\n * When there are no chainEffects the chaining/unchaining phases are\n * zero-duration and effectively skipped.\n */\ntype AnimPhase =\n | \"folded\"\n | \"unfolding\"\n | \"chaining\"\n | \"chained\"\n | \"unchaining\"\n | \"folding\";\n\nexport const Obj: React.FC<ObjProps> = React.memo(\n ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 600,\n perspectiveOrigin = \"50% 50%\",\n faces,\n global: globalDef,\n anim1,\n anim2,\n showCenterDiv = false,\n flat = false,\n transitionDuration = 1,\n oneAtATime = false,\n remainJoined = false,\n ytilt = false,\n backfaceHidden = false,\n chainEffects,\n onChainComplete,\n onChainReverseComplete,\n className,\n style,\n }) => {\n const w =\n typeof width === \"number\" ? width : parseFloat(String(width));\n const h =\n typeof height === \"number\" ? height : parseFloat(String(height));\n const d =\n typeof depth === \"number\" ? depth : parseFloat(String(depth));\n\n // Resolve animation shorthands\n const animation1 = toAnimationShorthand(anim1) ?? undefined;\n const animation2 = toAnimationShorthand(anim2) ?? undefined;\n\n /* ============================================================ */\n /* Chain-phase state machine */\n /* ============================================================ */\n\n const [phase, setPhase] = React.useState<AnimPhase>(\n flat ? \"chained\" : \"folded\"\n );\n\n const hasChain =\n Array.isArray(chainEffects) && chainEffects.length > 0;\n\n // Compute total unfold duration (includes stagger)\n const sideCountRef = React.useRef(0);\n\n // Max chain-effect duration (effect duration + effect delay)\n const chainDur = React.useMemo(() => {\n if (!hasChain) return 0;\n return Math.max(\n 0,\n ...chainEffects!.map(\n (e) => (e.duration ?? 0.5) + (e.delay ?? 0)\n )\n );\n }, [chainEffects, hasChain]);\n\n // React to `flat` prop changes\n const prevFlatForChain = React.useRef(flat);\n React.useEffect(() => {\n if (flat === prevFlatForChain.current) return;\n prevFlatForChain.current = flat;\n\n if (flat) {\n // Forward: start unfolding\n setPhase(\"unfolding\");\n } else {\n // Reverse: if chained, undo chain effects first\n if (hasChain && (phase === \"chained\" || phase === \"chaining\")) {\n setPhase(\"unchaining\");\n } else {\n setPhase(\"folding\");\n }\n }\n }, [flat]); // intentionally minimal deps — phase is read, not a dep\n\n // Phase transition timers\n React.useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (phase === \"unfolding\") {\n // Wait for unfold CSS transitions to finish, then chain\n const sideCount = sideCountRef.current;\n const unfoldDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n timer = setTimeout(() => {\n if (hasChain) {\n setPhase(\"chaining\");\n } else {\n setPhase(\"chained\");\n onChainComplete?.();\n }\n }, unfoldDur * 1000 + 60);\n }\n\n if (phase === \"chaining\") {\n timer = setTimeout(() => {\n setPhase(\"chained\");\n onChainComplete?.();\n }, chainDur * 1000 + 60);\n }\n\n if (phase === \"unchaining\") {\n timer = setTimeout(() => {\n setPhase(\"folding\");\n }, chainDur * 1000 + 60);\n }\n\n if (phase === \"folding\") {\n const sideCount = sideCountRef.current;\n const foldDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n timer = setTimeout(() => {\n setPhase(\"folded\");\n onChainReverseComplete?.();\n }, foldDur * 1000 + 60);\n }\n\n return () => {\n if (timer) clearTimeout(timer);\n };\n }, [\n phase,\n hasChain,\n chainDur,\n transitionDuration,\n oneAtATime,\n onChainComplete,\n onChainReverseComplete,\n ]);\n\n // Derived booleans for rendering\n const isFlatNow =\n phase === \"unfolding\" ||\n phase === \"chaining\" ||\n phase === \"chained\" ||\n phase === \"unchaining\";\n const chainActive = phase === \"chaining\" || phase === \"chained\";\n\n // Build a map of chain effects by face name for quick lookup\n const chainMap = React.useMemo(() => {\n const map = new Map<string, FaceChainEffect>();\n if (chainEffects) {\n for (const e of chainEffects) {\n map.set(e.faceName, e);\n }\n }\n return map;\n }, [chainEffects]);\n\n /** Merge chain-effect styles onto a face when chain is active */\n function chainStyle(\n faceName: string\n ): React.CSSProperties {\n const eff = chainMap.get(faceName);\n if (!eff) return {};\n\n const dur = (eff.duration ?? 0.5) + \"s\";\n const delay = (eff.delay ?? 0) + \"s\";\n const timing = eff.timing ?? \"ease-in-out\";\n\n const props: string[] = [];\n const styles: React.CSSProperties = {};\n\n if (eff.scaleX !== undefined || eff.scaleY !== undefined) {\n const sx = eff.scaleX ?? 1;\n const sy = eff.scaleY ?? 1;\n if (chainActive) {\n styles.transform =\n (styles.transform ?? \"\") + ` scaleX(${sx}) scaleY(${sy})`;\n }\n props.push(\"transform\");\n }\n\n if (eff.background !== undefined) {\n if (chainActive) {\n styles.background = eff.background;\n }\n props.push(\"background\");\n }\n\n if (eff.opacity !== undefined) {\n if (chainActive) {\n styles.opacity = eff.opacity;\n }\n props.push(\"opacity\");\n }\n\n // Build transition string for chain properties\n if (props.length > 0) {\n const transitionParts = props.map(\n (p) => `${p} ${dur} ${timing} ${delay}`\n );\n styles.transition = transitionParts.join(\", \");\n }\n\n return styles;\n }\n\n // Determine which faces to render\n const faceList: FaceDef[] =\n faces && faces.length > 0\n ? faces\n : DEFAULT_FACE_NAMES.map((name) => ({ name }));\n\n // Keep sideCountRef up to date for phase timer calculations\n sideCountRef.current = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(f.name)\n ).length;\n\n const bfv: React.CSSProperties[\"backfaceVisibility\"] =\n backfaceHidden ? \"hidden\" : \"visible\";\n\n const transitionCss = (delay = 0) =>\n `transform ${transitionDuration}s ease-in-out ${delay}s`;\n\n /* ============================================================ */\n /* Y-tilt — fire a one-shot rotateX(0→45→0) each time */\n /* flat changes. We alternate between two identical keyframe */\n /* names (a/b) so the browser re-triggers the animation. */\n /* ============================================================ */\n\n const tiltCount = React.useRef(0);\n const prevFlat = React.useRef(flat);\n const [tiltAnim, setTiltAnim] = React.useState<\n string | undefined\n >(undefined);\n\n React.useEffect(() => {\n if (flat !== prevFlat.current) {\n prevFlat.current = flat;\n if (ytilt) {\n tiltCount.current += 1;\n const sideCount = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(\n f.name\n )\n ).length;\n const totalDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n const name =\n tiltCount.current % 2 === 0\n ? \"anim3d-ytilt-a\"\n : \"anim3d-ytilt-b\";\n setTiltAnim(\n `${name} ${totalDur}s ease-in-out 1 forwards`\n );\n // Clear animation after it completes so it can re-trigger\n const timer = setTimeout(\n () => setTiltAnim(undefined),\n totalDur * 1000 + 50\n );\n return () => clearTimeout(timer);\n }\n }\n }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);\n\n /* ============================================================ */\n /* Standard rendering (no remainJoined) */\n /* ============================================================ */\n\n const renderStandard = () =>\n faceList.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const baseTransform = isFlatNow\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n const idx = STAGGER_ORDER.indexOf(face.name);\n const delay = oneAtATime\n ? (idx >= 0 ? idx : i) * transitionDuration\n : 0;\n\n // Merge chain-effect styles\n const cStyle = chainStyle(face.name);\n // Chain scale is appended to the flat transform\n const scaleAppend =\n cStyle.transform\n ? ` ${cStyle.transform}`\n : \"\";\n const transform = baseTransform + scaleAppend;\n // Build combined transition: fold transition + chain transitions\n const foldTransition = transitionCss(delay);\n const combinedTransition = cStyle.transition\n ? `${foldTransition}, ${cStyle.transition}`\n : foldTransition;\n\n return (\n <div\n key={face.name + \"-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n ...cStyle,\n width: dims.width,\n height: dims.height,\n transform,\n transition: combinedTransition,\n backfaceVisibility: bfv,\n }}\n >\n {body}\n </div>\n );\n });\n\n /* ============================================================ */\n /* Joined rendering — nested hinge structure */\n /* */\n /* Chain: front → right → back → left (hinged at shared edges) */\n /* The left–front edge is the break‑point. */\n /* */\n /* Flat order: front | right | back | left (left on far right) */\n /* ============================================================ */\n\n const renderJoined = () => {\n const findFace = (n: string) =>\n faceList.find((f) => f.name === n);\n\n const frontFace = findFace(\"front\");\n const rightFace = findFace(\"right\");\n const backFace = findFace(\"back\");\n const leftFace = findFace(\"left\");\n\n const sideNames = new Set([\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n ]);\n const otherFaces = faceList.filter(\n (f) => !sideNames.has(f.name)\n );\n\n const step = oneAtATime ? transitionDuration : 0;\n\n /* Helper: render a single face element with merged styles */\n const renderFaceEl = (\n face: FaceDef | undefined,\n dims: { width: number; height: number },\n extra: React.CSSProperties,\n key: string\n ) => {\n if (!face) return null;\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n // Chain effect styles\n const cStyle = chainStyle(face.name);\n // If chain has a scale transform, append it to existing transform\n const baseTransform = extra.transform ?? \"\";\n const scaleAppend = cStyle.transform\n ? ` ${cStyle.transform}`\n : \"\";\n const mergedTransform = baseTransform\n ? `${baseTransform}${scaleAppend}`\n : scaleAppend || undefined;\n\n const foldTransition =\n (extra.transition as string) ?? \"\";\n const combinedTransition = cStyle.transition\n ? `${foldTransition}, ${cStyle.transition}`\n : foldTransition;\n\n return (\n <div\n key={key}\n className={fCls}\n style={{\n ...fStyle,\n ...cStyle,\n width: dims.width,\n height: dims.height,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxSizing: \"border-box\",\n backfaceVisibility: bfv,\n ...extra,\n transform: mergedTransform ?? extra.transform,\n transition: combinedTransition || extra.transition,\n }}\n >\n {body}\n </div>\n );\n };\n\n return (\n <>\n {/* ---- Front face (anchor) ---- */}\n {renderFaceEl(\n frontFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: \"50%\",\n top: \"50%\",\n transform: isFlatNow\n ? \"translate(-50%, -50%)\"\n : `translate(-50%, -50%) translateZ(${d / 2}px)`,\n transition: transitionCss(0),\n },\n \"front-j\"\n )}\n\n {/* ---- Right hinge (pivots at front's right edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: `calc(50% + ${w / 2}px)`,\n top: \"50%\",\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : `translateZ(${d / 2}px) rotateY(90deg)`,\n transition: transitionCss(step),\n }}\n >\n {/* Right face */}\n {renderFaceEl(\n rightFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"right-j\"\n )}\n\n {/* ---- Back hinge (pivots at right's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: d,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 2),\n }}\n >\n {/* Back face */}\n {renderFaceEl(\n backFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"back-j\"\n )}\n\n {/* ---- Left hinge (pivots at back's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: w,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 3),\n }}\n >\n {/* Left face */}\n {renderFaceEl(\n leftFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"left-j\"\n )}\n </div>\n </div>\n </div>\n\n {/* ---- Non-side faces (top, bottom, etc.) ---- */}\n {otherFaces.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const xform = isFlatNow\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={face.name + \"-o-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform: xform,\n transition: transitionCss(0),\n backfaceVisibility: bfv,\n }}\n >\n {body}\n </div>\n );\n })}\n </>\n );\n };\n\n /* ============================================================ */\n /* Render tree */\n /* ============================================================ */\n\n const cssVars = {\n \"--obj-w\": w + \"px\",\n \"--obj-h\": h + \"px\",\n \"--obj-d\": d + \"px\",\n } as React.CSSProperties;\n\n return (\n <div\n className={[\"anim3d-stage\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{\n perspective,\n perspectiveOrigin,\n ...cssVars,\n ...style,\n }}\n data-anim-3d-obj\n role=\"img\"\n aria-label=\"3D object\"\n >\n {/* Y-tilt wrapper — sits between stage and anim wrappers */}\n <div\n style={{\n transformStyle: \"preserve-3d\",\n animation: tiltAnim,\n }}\n >\n {/* Outer animation wrapper (anim1) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: isFlatNow ? \"none\" : animation1,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {/* Inner animation wrapper (anim2) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: isFlatNow ? \"none\" : animation2,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {showCenterDiv && (\n <div className=\"anim3d-center\" />\n )}\n {remainJoined\n ? renderJoined()\n : renderStandard()}\n </div>\n </div>\n </div>\n </div>\n );\n }\n);\n\nObj.displayName = \"Obj\";\n"]}
package/dist/index.d.mts CHANGED
@@ -31,6 +31,18 @@ type GlobalDef = {
31
31
  style?: CSSProperties;
32
32
  body?: ReactNode | string;
33
33
  };
34
+ /** Effect applied to a specific face after unfold completes (chained animation).
35
+ * On reverse, these effects are undone before the fold begins. */
36
+ type FaceChainEffect = {
37
+ faceName: string;
38
+ scaleX?: number;
39
+ scaleY?: number;
40
+ background?: string;
41
+ opacity?: number;
42
+ duration?: number;
43
+ delay?: number;
44
+ timing?: TimingFn;
45
+ };
34
46
  type ObjProps = {
35
47
  width?: number;
36
48
  height?: number;
@@ -51,10 +63,20 @@ type ObjProps = {
51
63
  /** When true, connected edges stay joined during unfold (front→right→back chain).
52
64
  * The left–front edge is the break point. */
53
65
  remainJoined?: boolean;
54
- /** When true, the object tilts 45° on the X-axis (tips forward) during
66
+ /** When true, the object tilts 45° on the X-axis (bird's-eye view) during
55
67
  * a fold/unfold transition, then returns to 0° when the transition
56
68
  * completes. Only active while flat is changing. */
57
69
  ytilt?: boolean;
70
+ /** When true, faces are hidden when rotated away from the viewer
71
+ * (CSS backface-visibility: hidden). Default false. */
72
+ backfaceHidden?: boolean;
73
+ /** Effects applied to individual faces after the unfold completes.
74
+ * Reversed automatically before a fold begins. */
75
+ chainEffects?: FaceChainEffect[];
76
+ /** Called when the full forward chain (unfold + effects) completes */
77
+ onChainComplete?: () => void;
78
+ /** Called when the full reverse chain (un-effects + fold) completes */
79
+ onChainReverseComplete?: () => void;
58
80
  className?: string;
59
81
  style?: CSSProperties;
60
82
  };
@@ -66,4 +88,4 @@ declare function resolveAnimation(cfg?: AnimationConfig): string | null;
66
88
  /** Build the full CSS animation shorthand from a config and resolved name */
67
89
  declare function toAnimationShorthand(cfg?: AnimationConfig): string | null;
68
90
 
69
- export { type AnimationConfig, type AnimationDirection, type AnimationFill, type AnimationPlayState, type BuiltInAnimName, type FaceDef, type FaceName, type GlobalDef, Obj, type ObjProps, type TimingFn, Obj as default, resolveAnimation, toAnimationShorthand };
91
+ export { type AnimationConfig, type AnimationDirection, type AnimationFill, type AnimationPlayState, type BuiltInAnimName, type FaceChainEffect, type FaceDef, type FaceName, type GlobalDef, Obj, type ObjProps, type TimingFn, Obj as default, resolveAnimation, toAnimationShorthand };
package/dist/index.d.ts CHANGED
@@ -31,6 +31,18 @@ type GlobalDef = {
31
31
  style?: CSSProperties;
32
32
  body?: ReactNode | string;
33
33
  };
34
+ /** Effect applied to a specific face after unfold completes (chained animation).
35
+ * On reverse, these effects are undone before the fold begins. */
36
+ type FaceChainEffect = {
37
+ faceName: string;
38
+ scaleX?: number;
39
+ scaleY?: number;
40
+ background?: string;
41
+ opacity?: number;
42
+ duration?: number;
43
+ delay?: number;
44
+ timing?: TimingFn;
45
+ };
34
46
  type ObjProps = {
35
47
  width?: number;
36
48
  height?: number;
@@ -51,10 +63,20 @@ type ObjProps = {
51
63
  /** When true, connected edges stay joined during unfold (front→right→back chain).
52
64
  * The left–front edge is the break point. */
53
65
  remainJoined?: boolean;
54
- /** When true, the object tilts 45° on the X-axis (tips forward) during
66
+ /** When true, the object tilts 45° on the X-axis (bird's-eye view) during
55
67
  * a fold/unfold transition, then returns to 0° when the transition
56
68
  * completes. Only active while flat is changing. */
57
69
  ytilt?: boolean;
70
+ /** When true, faces are hidden when rotated away from the viewer
71
+ * (CSS backface-visibility: hidden). Default false. */
72
+ backfaceHidden?: boolean;
73
+ /** Effects applied to individual faces after the unfold completes.
74
+ * Reversed automatically before a fold begins. */
75
+ chainEffects?: FaceChainEffect[];
76
+ /** Called when the full forward chain (unfold + effects) completes */
77
+ onChainComplete?: () => void;
78
+ /** Called when the full reverse chain (un-effects + fold) completes */
79
+ onChainReverseComplete?: () => void;
58
80
  className?: string;
59
81
  style?: CSSProperties;
60
82
  };
@@ -66,4 +88,4 @@ declare function resolveAnimation(cfg?: AnimationConfig): string | null;
66
88
  /** Build the full CSS animation shorthand from a config and resolved name */
67
89
  declare function toAnimationShorthand(cfg?: AnimationConfig): string | null;
68
90
 
69
- export { type AnimationConfig, type AnimationDirection, type AnimationFill, type AnimationPlayState, type BuiltInAnimName, type FaceDef, type FaceName, type GlobalDef, Obj, type ObjProps, type TimingFn, Obj as default, resolveAnimation, toAnimationShorthand };
91
+ export { type AnimationConfig, type AnimationDirection, type AnimationFill, type AnimationPlayState, type BuiltInAnimName, type FaceChainEffect, type FaceDef, type FaceName, type GlobalDef, Obj, type ObjProps, type TimingFn, Obj as default, resolveAnimation, toAnimationShorthand };
package/dist/index.js CHANGED
@@ -206,6 +206,10 @@ var Obj = React.memo(
206
206
  oneAtATime = false,
207
207
  remainJoined = false,
208
208
  ytilt = false,
209
+ backfaceHidden = false,
210
+ chainEffects,
211
+ onChainComplete,
212
+ onChainReverseComplete,
209
213
  className,
210
214
  style
211
215
  }) => {
@@ -214,7 +218,131 @@ var Obj = React.memo(
214
218
  const d = typeof depth === "number" ? depth : parseFloat(String(depth));
215
219
  const animation1 = toAnimationShorthand(anim1) ?? void 0;
216
220
  const animation2 = toAnimationShorthand(anim2) ?? void 0;
221
+ const [phase, setPhase] = React.useState(
222
+ flat ? "chained" : "folded"
223
+ );
224
+ const hasChain = Array.isArray(chainEffects) && chainEffects.length > 0;
225
+ const sideCountRef = React.useRef(0);
226
+ const chainDur = React.useMemo(() => {
227
+ if (!hasChain) return 0;
228
+ return Math.max(
229
+ 0,
230
+ ...chainEffects.map(
231
+ (e) => (e.duration ?? 0.5) + (e.delay ?? 0)
232
+ )
233
+ );
234
+ }, [chainEffects, hasChain]);
235
+ const prevFlatForChain = React.useRef(flat);
236
+ React.useEffect(() => {
237
+ if (flat === prevFlatForChain.current) return;
238
+ prevFlatForChain.current = flat;
239
+ if (flat) {
240
+ setPhase("unfolding");
241
+ } else {
242
+ if (hasChain && (phase === "chained" || phase === "chaining")) {
243
+ setPhase("unchaining");
244
+ } else {
245
+ setPhase("folding");
246
+ }
247
+ }
248
+ }, [flat]);
249
+ React.useEffect(() => {
250
+ let timer;
251
+ if (phase === "unfolding") {
252
+ const sideCount = sideCountRef.current;
253
+ const unfoldDur = oneAtATime ? transitionDuration * sideCount : transitionDuration;
254
+ timer = setTimeout(() => {
255
+ if (hasChain) {
256
+ setPhase("chaining");
257
+ } else {
258
+ setPhase("chained");
259
+ onChainComplete?.();
260
+ }
261
+ }, unfoldDur * 1e3 + 60);
262
+ }
263
+ if (phase === "chaining") {
264
+ timer = setTimeout(() => {
265
+ setPhase("chained");
266
+ onChainComplete?.();
267
+ }, chainDur * 1e3 + 60);
268
+ }
269
+ if (phase === "unchaining") {
270
+ timer = setTimeout(() => {
271
+ setPhase("folding");
272
+ }, chainDur * 1e3 + 60);
273
+ }
274
+ if (phase === "folding") {
275
+ const sideCount = sideCountRef.current;
276
+ const foldDur = oneAtATime ? transitionDuration * sideCount : transitionDuration;
277
+ timer = setTimeout(() => {
278
+ setPhase("folded");
279
+ onChainReverseComplete?.();
280
+ }, foldDur * 1e3 + 60);
281
+ }
282
+ return () => {
283
+ if (timer) clearTimeout(timer);
284
+ };
285
+ }, [
286
+ phase,
287
+ hasChain,
288
+ chainDur,
289
+ transitionDuration,
290
+ oneAtATime,
291
+ onChainComplete,
292
+ onChainReverseComplete
293
+ ]);
294
+ const isFlatNow = phase === "unfolding" || phase === "chaining" || phase === "chained" || phase === "unchaining";
295
+ const chainActive = phase === "chaining" || phase === "chained";
296
+ const chainMap = React.useMemo(() => {
297
+ const map = /* @__PURE__ */ new Map();
298
+ if (chainEffects) {
299
+ for (const e of chainEffects) {
300
+ map.set(e.faceName, e);
301
+ }
302
+ }
303
+ return map;
304
+ }, [chainEffects]);
305
+ function chainStyle(faceName) {
306
+ const eff = chainMap.get(faceName);
307
+ if (!eff) return {};
308
+ const dur = (eff.duration ?? 0.5) + "s";
309
+ const delay = (eff.delay ?? 0) + "s";
310
+ const timing = eff.timing ?? "ease-in-out";
311
+ const props = [];
312
+ const styles = {};
313
+ if (eff.scaleX !== void 0 || eff.scaleY !== void 0) {
314
+ const sx = eff.scaleX ?? 1;
315
+ const sy = eff.scaleY ?? 1;
316
+ if (chainActive) {
317
+ styles.transform = (styles.transform ?? "") + ` scaleX(${sx}) scaleY(${sy})`;
318
+ }
319
+ props.push("transform");
320
+ }
321
+ if (eff.background !== void 0) {
322
+ if (chainActive) {
323
+ styles.background = eff.background;
324
+ }
325
+ props.push("background");
326
+ }
327
+ if (eff.opacity !== void 0) {
328
+ if (chainActive) {
329
+ styles.opacity = eff.opacity;
330
+ }
331
+ props.push("opacity");
332
+ }
333
+ if (props.length > 0) {
334
+ const transitionParts = props.map(
335
+ (p) => `${p} ${dur} ${timing} ${delay}`
336
+ );
337
+ styles.transition = transitionParts.join(", ");
338
+ }
339
+ return styles;
340
+ }
217
341
  const faceList = faces && faces.length > 0 ? faces : DEFAULT_FACE_NAMES.map((name) => ({ name }));
342
+ sideCountRef.current = faceList.filter(
343
+ (f) => ["front", "right", "back", "left"].includes(f.name)
344
+ ).length;
345
+ const bfv = backfaceHidden ? "hidden" : "visible";
218
346
  const transitionCss = (delay = 0) => `transform ${transitionDuration}s ease-in-out ${delay}s`;
219
347
  const tiltCount = React.useRef(0);
220
348
  const prevFlat = React.useRef(flat);
@@ -244,7 +372,7 @@ var Obj = React.memo(
244
372
  }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);
245
373
  const renderStandard = () => faceList.map((face, i) => {
246
374
  const dims = faceDimensions(face.name, w, h, d);
247
- const transform = flat ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
375
+ const baseTransform = isFlatNow ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
248
376
  const {
249
377
  style: fStyle,
250
378
  className: fCls,
@@ -252,16 +380,23 @@ var Obj = React.memo(
252
380
  } = faceAppearance(face, globalDef);
253
381
  const idx = STAGGER_ORDER.indexOf(face.name);
254
382
  const delay = oneAtATime ? (idx >= 0 ? idx : i) * transitionDuration : 0;
383
+ const cStyle = chainStyle(face.name);
384
+ const scaleAppend = cStyle.transform ? ` ${cStyle.transform}` : "";
385
+ const transform = baseTransform + scaleAppend;
386
+ const foldTransition = transitionCss(delay);
387
+ const combinedTransition = cStyle.transition ? `${foldTransition}, ${cStyle.transition}` : foldTransition;
255
388
  return /* @__PURE__ */ jsx(
256
389
  "div",
257
390
  {
258
391
  className: fCls,
259
392
  style: {
260
393
  ...fStyle,
394
+ ...cStyle,
261
395
  width: dims.width,
262
396
  height: dims.height,
263
397
  transform,
264
- transition: transitionCss(delay)
398
+ transition: combinedTransition,
399
+ backfaceVisibility: bfv
265
400
  },
266
401
  children: body
267
402
  },
@@ -291,19 +426,29 @@ var Obj = React.memo(
291
426
  className: fCls,
292
427
  body
293
428
  } = faceAppearance(face, globalDef);
429
+ const cStyle = chainStyle(face.name);
430
+ const baseTransform = extra.transform ?? "";
431
+ const scaleAppend = cStyle.transform ? ` ${cStyle.transform}` : "";
432
+ const mergedTransform = baseTransform ? `${baseTransform}${scaleAppend}` : scaleAppend || void 0;
433
+ const foldTransition = extra.transition ?? "";
434
+ const combinedTransition = cStyle.transition ? `${foldTransition}, ${cStyle.transition}` : foldTransition;
294
435
  return /* @__PURE__ */ jsx(
295
436
  "div",
296
437
  {
297
438
  className: fCls,
298
439
  style: {
299
440
  ...fStyle,
441
+ ...cStyle,
300
442
  width: dims.width,
301
443
  height: dims.height,
302
444
  display: "flex",
303
445
  alignItems: "center",
304
446
  justifyContent: "center",
305
447
  boxSizing: "border-box",
306
- ...extra
448
+ backfaceVisibility: bfv,
449
+ ...extra,
450
+ transform: mergedTransform ?? extra.transform,
451
+ transition: combinedTransition || extra.transition
307
452
  },
308
453
  children: body
309
454
  },
@@ -318,7 +463,7 @@ var Obj = React.memo(
318
463
  position: "absolute",
319
464
  left: "50%",
320
465
  top: "50%",
321
- transform: flat ? "translate(-50%, -50%)" : `translate(-50%, -50%) translateZ(${d / 2}px)`,
466
+ transform: isFlatNow ? "translate(-50%, -50%)" : `translate(-50%, -50%) translateZ(${d / 2}px)`,
322
467
  transition: transitionCss(0)
323
468
  },
324
469
  "front-j"
@@ -334,7 +479,7 @@ var Obj = React.memo(
334
479
  height: 0,
335
480
  transformOrigin: "0 0",
336
481
  transformStyle: "preserve-3d",
337
- transform: flat ? "none" : `translateZ(${d / 2}px) rotateY(90deg)`,
482
+ transform: isFlatNow ? "none" : `translateZ(${d / 2}px) rotateY(90deg)`,
338
483
  transition: transitionCss(step)
339
484
  },
340
485
  children: [
@@ -360,7 +505,7 @@ var Obj = React.memo(
360
505
  height: 0,
361
506
  transformOrigin: "0 0",
362
507
  transformStyle: "preserve-3d",
363
- transform: flat ? "none" : "rotateY(90deg)",
508
+ transform: isFlatNow ? "none" : "rotateY(90deg)",
364
509
  transition: transitionCss(step * 2)
365
510
  },
366
511
  children: [
@@ -386,7 +531,7 @@ var Obj = React.memo(
386
531
  height: 0,
387
532
  transformOrigin: "0 0",
388
533
  transformStyle: "preserve-3d",
389
- transform: flat ? "none" : "rotateY(90deg)",
534
+ transform: isFlatNow ? "none" : "rotateY(90deg)",
390
535
  transition: transitionCss(step * 3)
391
536
  },
392
537
  children: renderFaceEl(
@@ -410,7 +555,7 @@ var Obj = React.memo(
410
555
  ),
411
556
  otherFaces.map((face, i) => {
412
557
  const dims = faceDimensions(face.name, w, h, d);
413
- const xform = flat ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
558
+ const xform = isFlatNow ? faceTransformFlat(face.name, w, h, d) : faceTransform3D(face.name, w, h, d);
414
559
  const {
415
560
  style: fStyle,
416
561
  className: fCls,
@@ -425,7 +570,8 @@ var Obj = React.memo(
425
570
  width: dims.width,
426
571
  height: dims.height,
427
572
  transform: xform,
428
- transition: transitionCss(0)
573
+ transition: transitionCss(0),
574
+ backfaceVisibility: bfv
429
575
  },
430
576
  children: body
431
577
  },
@@ -465,7 +611,7 @@ var Obj = React.memo(
465
611
  className: "anim3d-wrapper",
466
612
  style: {
467
613
  ...cssVars,
468
- animation: flat ? "none" : animation1,
614
+ animation: isFlatNow ? "none" : animation1,
469
615
  transformStyle: "preserve-3d",
470
616
  transition: transitionCss()
471
617
  },
@@ -475,7 +621,7 @@ var Obj = React.memo(
475
621
  className: "anim3d-wrapper",
476
622
  style: {
477
623
  ...cssVars,
478
- animation: flat ? "none" : animation2,
624
+ animation: isFlatNow ? "none" : animation2,
479
625
  transformStyle: "preserve-3d",
480
626
  transition: transitionCss()
481
627
  },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/keyframes.ts","../src/components/Obj.tsx"],"names":[],"mappings":";;;;;;AAGA,SAAS,cAAA,GAAmC;AACzC,EAAA,IAAI,MAAM,QAAA,CAAS,cAAA;AAAA,IAChB;AAAA,GACH;AACA,EAAA,IAAI,CAAC,GAAA,EAAK;AACP,IAAA,GAAA,GAAM,QAAA,CAAS,cAAc,OAAO,CAAA;AACpC,IAAA,GAAA,CAAI,EAAA,GAAK,kBAAA;AACT,IAAA,QAAA,CAAS,IAAA,CAAK,YAAY,GAAG,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,GAAA;AACV;AAEA,SAAS,OAAO,GAAA,EAAa;AAC1B,EAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AACrC,EAAA,MAAM,MAAM,cAAA,EAAe;AAC3B,EAAA,GAAA,CAAI,WAAA,CAAY,QAAA,CAAS,cAAA,CAAe,GAAG,CAAC,CAAA;AAC/C;AAGA,SAAS,gBAAA,CAAiB,MAAc,GAAA,EAAsB;AAC3D,EAAA,MAAM,EAAA,GAAK,IAAI,SAAA,IAAa,EAAA;AAC5B,EAAA,MAAM,EAAA,GAAK,IAAI,UAAA,IAAc,GAAA;AAC7B,EAAA,QAAQ,IAAA;AAAM,IACX,KAAK,MAAA;AACF,MAAA,OAAO,CAAA,uFAAA,CAAA;AAAA,IACV,KAAK,MAAA;AACF,MAAA,OAAO,CAAA,uFAAA,CAAA;AAAA,IACV,KAAK,MAAA;AACF,MAAA,OAAO,CAAA,uFAAA,CAAA;AAAA,IACV,KAAK,OAAA;AACF,MAAA,OAAO,CAAA,0CAAA,EAA6C,EAAE,CAAA,+BAAA,EAAkC,EAAE,mCAAmC,EAAE,CAAA,QAAA,CAAA;AAAA,IAClI,KAAK,OAAA;AACF,MAAA,OAAO,CAAA,0CAAA,EAA6C,EAAE,CAAA,+BAAA,EAAkC,EAAE,mCAAmC,EAAE,CAAA,QAAA,CAAA;AAAA,IAClI;AAEG,MAAA,OAAO,EAAA;AAAA;AAEhB;AAGO,SAAS,iBAAiB,GAAA,EAAsC;AACpE,EAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,EAAA,MAAM,OAAO,GAAA,CAAI,IAAA;AACjB,EAAA,MAAM,OAAA,GAAU,gBAAA,CAAiB,IAAA,EAAM,GAAG,CAAA;AAC1C,EAAA,IAAI,OAAA,EAAS;AAEV,IAAA,MAAM,MAAA,GAAS,QAAQ,IAAI,CAAA,EAAA,CAAA;AAC3B,IAAA,IAAI,OAAO,aAAa,WAAA,EAAa;AAClC,MAAA,MAAM,MAAM,cAAA,EAAe;AAC3B,MAAA,IAAI,CAAC,GAAA,CAAI,SAAA,CAAU,QAAA,CAAS,MAAM,CAAA,EAAG;AAClC,QAAA,MAAA,CAAO,GAAG,OAAO;AAAA,EAAK,MAAM,CAAA,CAAE,CAAA;AAAA,MACjC;AAAA,IACH;AACA,IAAA,OAAO,IAAA;AAAA,EACV;AAEA,EAAA,OAAO,IAAA;AACV;AAGO,SAAS,qBAAqB,GAAA,EAAsC;AACxE,EAAA,MAAM,IAAA,GAAO,iBAAiB,GAAG,CAAA;AACjC,EAAA,IAAI,CAAC,GAAA,IAAO,CAAC,IAAA,EAAM,OAAO,IAAA;AAC1B,EAAA,MAAM,GAAA,GAAA,CAAO,GAAA,CAAI,QAAA,IAAY,EAAA,IAAM,GAAA;AACnC,EAAA,MAAM,KAAA,GAAA,CAAS,GAAA,CAAI,KAAA,IAAS,CAAA,IAAK,GAAA;AACjC,EAAA,MAAM,IAAA,GAAO,IAAI,cAAA,IAAkB,UAAA;AACnC,EAAA,MAAM,GAAA,GAAM,IAAI,SAAA,IAAa,QAAA;AAC7B,EAAA,MAAM,MAAA,GAAS,IAAI,MAAA,IAAU,QAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,IAAI,QAAA,IAAY,UAAA;AAC7B,EAAA,MAAM,IAAA,GAAO,IAAI,kBAAA,IAAsB,SAAA;AAEvC,EAAA,OAAO,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,GAAG,IAAI,MAAM,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,EAAI,IAAI,IAAI,IAAI,CAAA,CAAA;AAC1E;AC1DA,SAAS,eAAA,CACN,IAAA,EACA,CAAA,EACA,CAAA,EACA,CAAA,EACO;AACP,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AACf,EAAA,MAAM,KAAK,CAAA,GAAI,CAAA;AAEf,EAAA,QAAQ,IAAA;AAAkB,IACvB,KAAK,OAAA;AACF,MAAA,OAAO,oCAAoC,EAAE,CAAA,GAAA,CAAA;AAAA,IAChD,KAAK,MAAA;AACF,MAAA,OAAO,oDAAoD,EAAE,CAAA,GAAA,CAAA;AAAA,IAChE,KAAK,MAAA;AACF,MAAA,OAAO,oDAAoD,EAAE,CAAA,GAAA,CAAA;AAAA,IAChE,KAAK,OAAA;AACF,MAAA,OAAO,mDAAmD,EAAE,CAAA,GAAA,CAAA;AAAA,IAC/D,KAAK,KAAA;AACF,MAAA,OAAO,mDAAmD,EAAE,CAAA,GAAA,CAAA;AAAA,IAC/D,KAAK,QAAA;AACF,MAAA,OAAO,oDAAoD,EAAE,CAAA,GAAA,CAAA;AAAA,IAChE,KAAK,WAAA;AACF,MAAA,OAAO,mDAAmD,EAAE,CAAA,GAAA,CAAA;AAAA,IAC/D,KAAK,UAAA;AACF,MAAA,OAAO,oDAAoD,EAAE,CAAA,GAAA,CAAA;AAAA,IAChE,KAAK,cAAA;AACF,MAAA,OAAO,oDAAoD,EAAE,CAAA,GAAA,CAAA;AAAA,IAChE,KAAK,aAAA;AACF,MAAA,OAAO,qDAAqD,EAAE,CAAA,GAAA,CAAA;AAAA,IACjE;AACG,MAAA,OAAO,oCAAoC,EAAE,CAAA,GAAA,CAAA;AAAA;AAEtD;AASA,SAAS,iBAAA,CACN,IAAA,EACA,CAAA,EACA,CAAA,EACA,CAAA,EACO;AACP,EAAA,MAAM,KAAA,GAAQ,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA;AAC1B,EAAA,MAAM,OAAO,KAAA,GAAQ,CAAA;AAErB,EAAA,IAAI,EAAA;AAEJ,EAAA,QAAQ,IAAA;AAAkB,IACvB,KAAK,OAAA;AACF,MAAA,EAAA,GAAK,CAAA,GAAI,CAAA;AACT,MAAA;AAAA,IACH,KAAK,OAAA;AACF,MAAA,EAAA,GAAK,IAAI,CAAA,GAAI,CAAA;AACb,MAAA;AAAA,IACH,KAAK,MAAA;AACF,MAAA,EAAA,GAAK,CAAA,GAAI,IAAI,CAAA,GAAI,CAAA;AACjB,MAAA;AAAA,IACH,KAAK,MAAA;AACF,MAAA,EAAA,GAAK,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA,GAAI,CAAA;AACrB,MAAA;AAAA,IACH,KAAK,KAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,UAAA;AACF,MAAA,EAAA,GAAK,CAAA,GAAI,CAAA;AACT,MAAA,OAAO,CAAA,iCAAA,EAAoC,EAAA,GAAK,IAAI,CAAA,gBAAA,EAAmB,CAAC,CAAA,GAAA,CAAA;AAAA,IAC3E,KAAK,QAAA;AAAA,IACL,KAAK,cAAA;AAAA,IACL,KAAK,aAAA;AACF,MAAA,EAAA,GAAK,CAAA,GAAI,CAAA;AACT,MAAA,OAAO,CAAA,iCAAA,EAAoC,EAAA,GAAK,IAAI,CAAA,eAAA,EAAkB,CAAC,CAAA,GAAA,CAAA;AAAA,IAC1E;AACG,MAAA,EAAA,GAAK,CAAA,GAAI,CAAA;AACT,MAAA;AAAA;AAGN,EAAA,OAAO,CAAA,iCAAA,EAAoC,KAAK,IAAI,CAAA,GAAA,CAAA;AACvD;AAMA,SAAS,aAAa,GAAA,EAAmC;AACtD,EAAA,IAAI,CAAC,GAAA,EAAK,OAAO,EAAC;AAClB,EAAA,MAAM,QAAgC,EAAC;AACvC,EAAA,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,OAAA,CAAQ,CAAC,IAAA,KAAS;AAC9B,IAAA,MAAM,CAAC,IAAA,EAAM,GAAG,IAAI,CAAA,GAAI,IAAA,CAAK,MAAM,GAAG,CAAA;AACtC,IAAA,IAAI,CAAC,IAAA,IAAQ,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG;AAChC,IAAA,MAAM,GAAA,GAAM,IAAA,CACR,IAAA,EAAK,CACL,OAAA,CAAQ,WAAA,EAAa,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,WAAA,EAAa,CAAA;AAClD,IAAA,KAAA,CAAM,GAAG,CAAA,GAAI,IAAA,CAAK,IAAA,CAAK,GAAG,EAAE,IAAA,EAAK;AAAA,EACpC,CAAC,CAAA;AACD,EAAA,OAAO,KAAA;AACV;AAMA,SAAS,cAAA,CACN,IAAA,EACA,CAAA,EACA,CAAA,EACA,CAAA,EACkC;AAClC,EAAA,QAAQ,IAAA;AAAkB,IACvB,KAAK,MAAA;AAAA,IACL,KAAK,OAAA;AACF,MAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,IAChC,KAAK,KAAA;AAAA,IACL,KAAK,QAAA;AAAA,IACL,KAAK,WAAA;AAAA,IACL,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AAAA,IACL,KAAK,aAAA;AACF,MAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,IAChC;AACG,MAAA,OAAO,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA;AAEtC;AAOA,SAAS,cAAA,CACN,MACA,SAAA,EAKD;AACC,EAAA,MAAM,WAAA,GAAc,YAAA,CAAa,SAAA,EAAW,GAAG,CAAA;AAC/C,EAAA,MAAM,eAAA,GAAkB,YAAA,CAAa,IAAA,CAAK,GAAG,CAAA;AAE7C,EAAA,MAAM,KAAA,GAA6B;AAAA,IAChC,GAAG,WAAA;AAAA,IACH,GAAI,SAAA,EAAW,KAAA,IAAS,EAAC;AAAA,IACzB,GAAG,eAAA;AAAA,IACH,GAAI,IAAA,CAAK,KAAA,IAAS;AAAC,GACtB;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,aAAA,EAAe,IAAA,CAAK,SAAS,EAC5C,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AAEZ,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,SAAA,EAAW,IAAA,IAAQ,IAAA;AAE7C,EAAA,OAAO,EAAE,KAAA,EAAO,SAAA,EAAW,IAAA,EAAK;AACnC;AAMA,IAAM,kBAAA,GAAiC;AAAA,EACpC,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA;AACH,CAAA;AAMA,IAAM,aAAA,GAA0B;AAAA,EAC7B,OAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,WAAA;AAAA,EACA,UAAA;AAAA,EACA,cAAA;AAAA,EACA;AACH,CAAA;AAMO,IAAM,GAAA,GAAgC,KAAA,CAAA,IAAA;AAAA,EAC1C,CAAC;AAAA,IACE,KAAA,GAAQ,GAAA;AAAA,IACR,MAAA,GAAS,GAAA;AAAA,IACT,KAAA,GAAQ,GAAA;AAAA,IACR,WAAA,GAAc,GAAA;AAAA,IACd,iBAAA,GAAoB,SAAA;AAAA,IACpB,KAAA;AAAA,IACA,MAAA,EAAQ,SAAA;AAAA,IACR,KAAA;AAAA,IACA,KAAA;AAAA,IACA,aAAA,GAAgB,KAAA;AAAA,IAChB,IAAA,GAAO,KAAA;AAAA,IACP,kBAAA,GAAqB,CAAA;AAAA,IACrB,UAAA,GAAa,KAAA;AAAA,IACb,YAAA,GAAe,KAAA;AAAA,IACf,KAAA,GAAQ,KAAA;AAAA,IACR,SAAA;AAAA,IACA;AAAA,GACH,KAAM;AACH,IAAA,MAAM,CAAA,GACH,OAAO,KAAA,KAAU,QAAA,GAAW,QAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAC/D,IAAA,MAAM,CAAA,GACH,OAAO,MAAA,KAAW,QAAA,GAAW,SAAS,UAAA,CAAW,MAAA,CAAO,MAAM,CAAC,CAAA;AAClE,IAAA,MAAM,CAAA,GACH,OAAO,KAAA,KAAU,QAAA,GAAW,QAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAC,CAAA;AAG/D,IAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,KAAK,CAAA,IAAK,MAAA;AAClD,IAAA,MAAM,UAAA,GAAa,oBAAA,CAAqB,KAAK,CAAA,IAAK,MAAA;AAGlD,IAAA,MAAM,QAAA,GACH,KAAA,IAAS,KAAA,CAAM,MAAA,GAAS,CAAA,GACnB,KAAA,GACA,kBAAA,CAAmB,GAAA,CAAI,CAAC,IAAA,MAAU,EAAE,IAAA,EAAK,CAAE,CAAA;AAEnD,IAAA,MAAM,gBAAgB,CAAC,KAAA,GAAQ,MAC5B,CAAA,UAAA,EAAa,kBAAkB,iBAAiB,KAAK,CAAA,CAAA,CAAA;AAQxD,IAAA,MAAM,SAAA,GAAkB,aAAO,CAAC,CAAA;AAChC,IAAA,MAAM,QAAA,GAAiB,aAAO,IAAI,CAAA;AAClC,IAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAU,eAEpC,MAAS,CAAA;AAEX,IAAM,gBAAU,MAAM;AACnB,MAAA,IAAI,IAAA,KAAS,SAAS,OAAA,EAAS;AAC5B,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AACnB,QAAA,IAAI,KAAA,EAAO;AACR,UAAA,SAAA,CAAU,OAAA,IAAW,CAAA;AACrB,UAAA,MAAM,YAAY,QAAA,CAAS,MAAA;AAAA,YAAO,CAAC,CAAA,KAChC,CAAC,SAAS,OAAA,EAAS,MAAA,EAAQ,MAAM,CAAA,CAAE,QAAA;AAAA,cAChC,CAAA,CAAE;AAAA;AACL,WACH,CAAE,MAAA;AACF,UAAA,MAAM,QAAA,GAAW,UAAA,GACZ,kBAAA,GAAqB,SAAA,GACrB,kBAAA;AACL,UAAA,MAAM,IAAA,GACH,SAAA,CAAU,OAAA,GAAU,CAAA,KAAM,IACrB,gBAAA,GACA,gBAAA;AACR,UAAA,WAAA;AAAA,YACG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,QAAQ,CAAA,wBAAA;AAAA,WACtB;AAEA,UAAA,MAAM,KAAA,GAAQ,UAAA;AAAA,YACX,MAAM,YAAY,MAAS,CAAA;AAAA,YAC3B,WAAW,GAAA,GAAO;AAAA,WACrB;AACA,UAAA,OAAO,MAAM,aAAa,KAAK,CAAA;AAAA,QAClC;AAAA,MACH;AAAA,IACH,GAAG,CAAC,IAAA,EAAM,OAAO,kBAAA,EAAoB,UAAA,EAAY,QAAQ,CAAC,CAAA;AAM1D,IAAA,MAAM,iBAAiB,MACpB,QAAA,CAAS,GAAA,CAAI,CAAC,MAAM,CAAA,KAAM;AACvB,MAAA,MAAM,OAAO,cAAA,CAAe,IAAA,CAAK,IAAA,EAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAC9C,MAAA,MAAM,SAAA,GAAY,IAAA,GACb,iBAAA,CAAkB,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GACpC,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAEvC,MAAA,MAAM;AAAA,QACH,KAAA,EAAO,MAAA;AAAA,QACP,SAAA,EAAW,IAAA;AAAA,QACX;AAAA,OACH,GAAI,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA;AAElC,MAAA,MAAM,GAAA,GAAM,aAAA,CAAc,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA;AAC3C,MAAA,MAAM,QAAQ,UAAA,GAAA,CACR,GAAA,IAAO,CAAA,GAAI,GAAA,GAAM,KAAK,kBAAA,GACvB,CAAA;AAEL,MAAA,uBACG,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UAEE,SAAA,EAAW,IAAA;AAAA,UACX,KAAA,EAAO;AAAA,YACJ,GAAG,MAAA;AAAA,YACH,OAAO,IAAA,CAAK,KAAA;AAAA,YACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,YACb,SAAA;AAAA,YACA,UAAA,EAAY,cAAc,KAAK;AAAA,WAClC;AAAA,UAEC,QAAA,EAAA;AAAA,SAAA;AAAA,QAVI,IAAA,CAAK,OAAO,GAAA,GAAM;AAAA,OAW1B;AAAA,IAEN,CAAC,CAAA;AAWJ,IAAA,MAAM,eAAe,MAAM;AACxB,MAAA,MAAM,QAAA,GAAW,CAAC,CAAA,KACf,QAAA,CAAS,KAAK,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,KAAS,CAAC,CAAA;AAEpC,MAAA,MAAM,SAAA,GAAY,SAAS,OAAO,CAAA;AAClC,MAAA,MAAM,SAAA,GAAY,SAAS,OAAO,CAAA;AAClC,MAAA,MAAM,QAAA,GAAW,SAAS,MAAM,CAAA;AAChC,MAAA,MAAM,QAAA,GAAW,SAAS,MAAM,CAAA;AAEhC,MAAA,MAAM,SAAA,uBAAgB,GAAA,CAAI;AAAA,QACvB,OAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF,CAAA;AACD,MAAA,MAAM,aAAa,QAAA,CAAS,MAAA;AAAA,QACzB,CAAC,CAAA,KAAM,CAAC,SAAA,CAAU,GAAA,CAAI,EAAE,IAAI;AAAA,OAC/B;AAEA,MAAA,MAAM,IAAA,GAAO,aAAa,kBAAA,GAAqB,CAAA;AAG/C,MAAA,MAAM,YAAA,GAAe,CAClB,IAAA,EACA,IAAA,EACA,OACA,GAAA,KACE;AACF,QAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,QAAA,MAAM;AAAA,UACH,KAAA,EAAO,MAAA;AAAA,UACP,SAAA,EAAW,IAAA;AAAA,UACX;AAAA,SACH,GAAI,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA;AAClC,QAAA,uBACG,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YAEE,SAAA,EAAW,IAAA;AAAA,YACX,KAAA,EAAO;AAAA,cACJ,GAAG,MAAA;AAAA,cACH,OAAO,IAAA,CAAK,KAAA;AAAA,cACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,cACb,OAAA,EAAS,MAAA;AAAA,cACT,UAAA,EAAY,QAAA;AAAA,cACZ,cAAA,EAAgB,QAAA;AAAA,cAChB,SAAA,EAAW,YAAA;AAAA,cACX,GAAG;AAAA,aACN;AAAA,YAEC,QAAA,EAAA;AAAA,WAAA;AAAA,UAbI;AAAA,SAcR;AAAA,MAEN,CAAA;AAEA,MAAA,uBACG,IAAA,CAAA,QAAA,EAAA,EAEI,QAAA,EAAA;AAAA,QAAA,YAAA;AAAA,UACE,SAAA;AAAA,UACA,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,UACtB;AAAA,YACG,QAAA,EAAU,UAAA;AAAA,YACV,IAAA,EAAM,KAAA;AAAA,YACN,GAAA,EAAK,KAAA;AAAA,YACL,SAAA,EAAW,IAAA,GACN,uBAAA,GACA,CAAA,iCAAA,EAAoC,IAAI,CAAC,CAAA,GAAA,CAAA;AAAA,YAC9C,UAAA,EAAY,cAAc,CAAC;AAAA,WAC9B;AAAA,UACA;AAAA,SACH;AAAA,wBAGA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACE,KAAA,EAAO;AAAA,cACJ,QAAA,EAAU,UAAA;AAAA,cACV,IAAA,EAAM,CAAA,WAAA,EAAc,CAAA,GAAI,CAAC,CAAA,GAAA,CAAA;AAAA,cACzB,GAAA,EAAK,KAAA;AAAA,cACL,KAAA,EAAO,CAAA;AAAA,cACP,MAAA,EAAQ,CAAA;AAAA,cACR,eAAA,EAAiB,KAAA;AAAA,cACjB,cAAA,EAAgB,aAAA;AAAA,cAChB,SAAA,EAAW,IAAA,GACN,MAAA,GACA,CAAA,WAAA,EAAc,IAAI,CAAC,CAAA,kBAAA,CAAA;AAAA,cACxB,UAAA,EAAY,cAAc,IAAI;AAAA,aACjC;AAAA,YAGC,QAAA,EAAA;AAAA,cAAA,YAAA;AAAA,gBACE,SAAA;AAAA,gBACA,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,gBACtB;AAAA,kBACG,QAAA,EAAU,UAAA;AAAA,kBACV,IAAA,EAAM,CAAA;AAAA,kBACN,GAAA,EAAK,CAAA;AAAA,kBACL,SAAA,EAAW;AAAA,iBACd;AAAA,gBACA;AAAA,eACH;AAAA,8BAGA,IAAA;AAAA,gBAAC,KAAA;AAAA,gBAAA;AAAA,kBACE,KAAA,EAAO;AAAA,oBACJ,QAAA,EAAU,UAAA;AAAA,oBACV,IAAA,EAAM,CAAA;AAAA,oBACN,GAAA,EAAK,CAAA;AAAA,oBACL,KAAA,EAAO,CAAA;AAAA,oBACP,MAAA,EAAQ,CAAA;AAAA,oBACR,eAAA,EAAiB,KAAA;AAAA,oBACjB,cAAA,EAAgB,aAAA;AAAA,oBAChB,SAAA,EAAW,OACN,MAAA,GACA,gBAAA;AAAA,oBACL,UAAA,EAAY,aAAA,CAAc,IAAA,GAAO,CAAC;AAAA,mBACrC;AAAA,kBAGC,QAAA,EAAA;AAAA,oBAAA,YAAA;AAAA,sBACE,QAAA;AAAA,sBACA,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,sBACtB;AAAA,wBACG,QAAA,EAAU,UAAA;AAAA,wBACV,IAAA,EAAM,CAAA;AAAA,wBACN,GAAA,EAAK,CAAA;AAAA,wBACL,SAAA,EAAW;AAAA,uBACd;AAAA,sBACA;AAAA,qBACH;AAAA,oCAGA,GAAA;AAAA,sBAAC,KAAA;AAAA,sBAAA;AAAA,wBACE,KAAA,EAAO;AAAA,0BACJ,QAAA,EAAU,UAAA;AAAA,0BACV,IAAA,EAAM,CAAA;AAAA,0BACN,GAAA,EAAK,CAAA;AAAA,0BACL,KAAA,EAAO,CAAA;AAAA,0BACP,MAAA,EAAQ,CAAA;AAAA,0BACR,eAAA,EAAiB,KAAA;AAAA,0BACjB,cAAA,EAAgB,aAAA;AAAA,0BAChB,SAAA,EAAW,OACN,MAAA,GACA,gBAAA;AAAA,0BACL,UAAA,EAAY,aAAA,CAAc,IAAA,GAAO,CAAC;AAAA,yBACrC;AAAA,wBAGC,QAAA,EAAA,YAAA;AAAA,0BACE,QAAA;AAAA,0BACA,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,CAAA,EAAE;AAAA,0BACtB;AAAA,4BACG,QAAA,EAAU,UAAA;AAAA,4BACV,IAAA,EAAM,CAAA;AAAA,4BACN,GAAA,EAAK,CAAA;AAAA,4BACL,SAAA,EAAW;AAAA,2BACd;AAAA,0BACA;AAAA;AACH;AAAA;AACH;AAAA;AAAA;AACH;AAAA;AAAA,SACH;AAAA,QAGC,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,EAAM,CAAA,KAAM;AAC1B,UAAA,MAAM,OAAO,cAAA,CAAe,IAAA,CAAK,IAAA,EAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AAC9C,UAAA,MAAM,KAAA,GAAQ,IAAA,GACT,iBAAA,CAAkB,IAAA,CAAK,MAAM,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA,GACpC,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,CAAA,EAAG,GAAG,CAAC,CAAA;AACvC,UAAA,MAAM;AAAA,YACH,KAAA,EAAO,MAAA;AAAA,YACP,SAAA,EAAW,IAAA;AAAA,YACX;AAAA,WACH,GAAI,cAAA,CAAe,IAAA,EAAM,SAAS,CAAA;AAClC,UAAA,uBACG,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cAEE,SAAA,EAAW,IAAA;AAAA,cACX,KAAA,EAAO;AAAA,gBACJ,GAAG,MAAA;AAAA,gBACH,OAAO,IAAA,CAAK,KAAA;AAAA,gBACZ,QAAQ,IAAA,CAAK,MAAA;AAAA,gBACb,SAAA,EAAW,KAAA;AAAA,gBACX,UAAA,EAAY,cAAc,CAAC;AAAA,eAC9B;AAAA,cAEC,QAAA,EAAA;AAAA,aAAA;AAAA,YAVI,IAAA,CAAK,OAAO,KAAA,GAAQ;AAAA,WAW5B;AAAA,QAEN,CAAC;AAAA,OAAA,EACJ,CAAA;AAAA,IAEN,CAAA;AAMA,IAAA,MAAM,OAAA,GAAU;AAAA,MACb,WAAW,CAAA,GAAI,IAAA;AAAA,MACf,WAAW,CAAA,GAAI,IAAA;AAAA,MACf,WAAW,CAAA,GAAI;AAAA,KAClB;AAEA,IAAA,uBACG,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACE,SAAA,EAAW,CAAC,cAAA,EAAgB,SAAS,EACjC,MAAA,CAAO,OAAO,CAAA,CACd,IAAA,CAAK,GAAG,CAAA;AAAA,QACZ,KAAA,EAAO;AAAA,UACJ,WAAA;AAAA,UACA,iBAAA;AAAA,UACA,GAAG,OAAA;AAAA,UACH,GAAG;AAAA,SACN;AAAA,QACA,kBAAA,EAAgB,IAAA;AAAA,QAChB,IAAA,EAAK,KAAA;AAAA,QACL,YAAA,EAAW,WAAA;AAAA,QAGX,QAAA,kBAAA,GAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACE,KAAA,EAAO;AAAA,cACJ,cAAA,EAAgB,aAAA;AAAA,cAChB,SAAA,EAAW;AAAA,aACd;AAAA,YAGA,QAAA,kBAAA,GAAA;AAAA,cAAC,KAAA;AAAA,cAAA;AAAA,gBACE,SAAA,EAAU,gBAAA;AAAA,gBACV,KAAA,EAAO;AAAA,kBACJ,GAAG,OAAA;AAAA,kBACH,SAAA,EAAW,OAAO,MAAA,GAAS,UAAA;AAAA,kBAC3B,cAAA,EAAgB,aAAA;AAAA,kBAChB,YAAY,aAAA;AAAc,iBAC7B;AAAA,gBAGA,QAAA,kBAAA,IAAA;AAAA,kBAAC,KAAA;AAAA,kBAAA;AAAA,oBACE,SAAA,EAAU,gBAAA;AAAA,oBACV,KAAA,EAAO;AAAA,sBACJ,GAAG,OAAA;AAAA,sBACH,SAAA,EAAW,OAAO,MAAA,GAAS,UAAA;AAAA,sBAC3B,cAAA,EAAgB,aAAA;AAAA,sBAChB,YAAY,aAAA;AAAc,qBAC7B;AAAA,oBAEC,QAAA,EAAA;AAAA,sBAAA,aAAA,oBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAU,eAAA,EAAgB,CAAA;AAAA,sBAEjC,YAAA,GACI,YAAA,EAAa,GACb,cAAA;AAAe;AAAA;AAAA;AACvB;AAAA;AACH;AAAA;AACH;AAAA,KACH;AAAA,EAEN;AACH;AAEA,GAAA,CAAI,WAAA,GAAc,KAAA","file":"index.js","sourcesContent":["import type { AnimationConfig } from \"./types\";\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n","import * as React from \"react\";\nimport type {\n ObjProps,\n FaceDef,\n FaceName,\n GlobalDef,\n} from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n// Re-export the canonical ObjProps from types.ts\nexport type { ObjProps } from \"../types\";\n\n/* ------------------------------------------------------------------ */\n/* Face transform — 3D cuboid positions */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransform3D(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const hw = w / 2;\n const hh = h / 2;\n const hd = d / 2;\n\n switch (name as FaceName) {\n case \"front\":\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n case \"back\":\n return `translate(-50%, -50%) rotateY(180deg) translateZ(${hd}px)`;\n case \"left\":\n return `translate(-50%, -50%) rotateY(-90deg) translateZ(${hw}px)`;\n case \"right\":\n return `translate(-50%, -50%) rotateY(90deg) translateZ(${hw}px)`;\n case \"top\":\n return `translate(-50%, -50%) rotateX(90deg) translateZ(${hh}px)`;\n case \"bottom\":\n return `translate(-50%, -50%) rotateX(-90deg) translateZ(${hh}px)`;\n case \"top_front\":\n return `translate(-50%, -50%) rotateX(45deg) translateZ(${hh}px)`;\n case \"top_rear\":\n return `translate(-50%, -50%) rotateX(135deg) translateZ(${hh}px)`;\n case \"bottom_front\":\n return `translate(-50%, -50%) rotateX(-45deg) translateZ(${hh}px)`;\n case \"bottom_rear\":\n return `translate(-50%, -50%) rotateX(-135deg) translateZ(${hh}px)`;\n default:\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Face transform — flat (unfolded) positions */\n/* */\n/* Flat order: front | right | back | left */\n/* Centred on the midpoint of the full row. */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransformFlat(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const total = 2 * w + 2 * d;\n const half = total / 2;\n\n let cx: number;\n\n switch (name as FaceName) {\n case \"front\":\n cx = w / 2;\n break;\n case \"right\":\n cx = w + d / 2;\n break;\n case \"back\":\n cx = w + d + w / 2;\n break;\n case \"left\":\n cx = w + d + w + d / 2;\n break;\n case \"top\":\n case \"top_front\":\n case \"top_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(-${h}px)`;\n case \"bottom\":\n case \"bottom_front\":\n case \"bottom_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(${h}px)`;\n default:\n cx = w / 2;\n break;\n }\n\n return `translate(-50%, -50%) translateX(${cx - half}px)`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a legacy CSS text string into a CSSProperties object */\n/* ------------------------------------------------------------------ */\n\nfunction parseCssText(css?: string): React.CSSProperties {\n if (!css) return {};\n const style: Record<string, string> = {};\n css.split(\";\").forEach((rule) => {\n const [prop, ...rest] = rule.split(\":\");\n if (!prop || rest.length === 0) return;\n const key = prop\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n style[key] = rest.join(\":\").trim();\n });\n return style as React.CSSProperties;\n}\n\n/* ------------------------------------------------------------------ */\n/* Resolve face dimensions for non-standard faces */\n/* ------------------------------------------------------------------ */\n\nfunction faceDimensions(\n name: string,\n w: number,\n h: number,\n d: number\n): { width: number; height: number } {\n switch (name as FaceName) {\n case \"left\":\n case \"right\":\n return { width: d, height: h };\n case \"top\":\n case \"bottom\":\n case \"top_front\":\n case \"top_rear\":\n case \"bottom_front\":\n case \"bottom_rear\":\n return { width: w, height: d };\n default:\n return { width: w, height: h };\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Build appearance style for a face (colours, borders, etc.) */\n/* Does NOT include position / transform / size. */\n/* ------------------------------------------------------------------ */\n\nfunction faceAppearance(\n face: FaceDef,\n globalDef?: GlobalDef\n): {\n style: React.CSSProperties;\n className: string;\n body: React.ReactNode;\n} {\n const globalStyle = parseCssText(globalDef?.css);\n const faceInlineStyle = parseCssText(face.css);\n\n const style: React.CSSProperties = {\n ...globalStyle,\n ...(globalDef?.style ?? {}),\n ...faceInlineStyle,\n ...(face.style ?? {}),\n };\n\n const className = [\"anim3d-face\", face.className]\n .filter(Boolean)\n .join(\" \");\n\n const body = face.body ?? globalDef?.body ?? null;\n\n return { style, className, body };\n}\n\n/* ------------------------------------------------------------------ */\n/* Default 6-sided cube when no faces are provided */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_FACE_NAMES: FaceName[] = [\n \"front\",\n \"back\",\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Stagger order for oneAtATime (standard mode) */\n/* ------------------------------------------------------------------ */\n\nconst STAGGER_ORDER: string[] = [\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n \"top\",\n \"bottom\",\n \"top_front\",\n \"top_rear\",\n \"bottom_front\",\n \"bottom_rear\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\nexport const Obj: React.FC<ObjProps> = React.memo(\n ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 600,\n perspectiveOrigin = \"50% 50%\",\n faces,\n global: globalDef,\n anim1,\n anim2,\n showCenterDiv = false,\n flat = false,\n transitionDuration = 1,\n oneAtATime = false,\n remainJoined = false,\n ytilt = false,\n className,\n style,\n }) => {\n const w =\n typeof width === \"number\" ? width : parseFloat(String(width));\n const h =\n typeof height === \"number\" ? height : parseFloat(String(height));\n const d =\n typeof depth === \"number\" ? depth : parseFloat(String(depth));\n\n // Resolve animation shorthands\n const animation1 = toAnimationShorthand(anim1) ?? undefined;\n const animation2 = toAnimationShorthand(anim2) ?? undefined;\n\n // Determine which faces to render\n const faceList: FaceDef[] =\n faces && faces.length > 0\n ? faces\n : DEFAULT_FACE_NAMES.map((name) => ({ name }));\n\n const transitionCss = (delay = 0) =>\n `transform ${transitionDuration}s ease-in-out ${delay}s`;\n\n /* ============================================================ */\n /* Y-tilt — fire a one-shot rotateX(0→45→0) each time */\n /* flat changes. We alternate between two identical keyframe */\n /* names (a/b) so the browser re-triggers the animation. */\n /* ============================================================ */\n\n const tiltCount = React.useRef(0);\n const prevFlat = React.useRef(flat);\n const [tiltAnim, setTiltAnim] = React.useState<\n string | undefined\n >(undefined);\n\n React.useEffect(() => {\n if (flat !== prevFlat.current) {\n prevFlat.current = flat;\n if (ytilt) {\n tiltCount.current += 1;\n const sideCount = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(\n f.name\n )\n ).length;\n const totalDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n const name =\n tiltCount.current % 2 === 0\n ? \"anim3d-ytilt-a\"\n : \"anim3d-ytilt-b\";\n setTiltAnim(\n `${name} ${totalDur}s ease-in-out 1 forwards`\n );\n // Clear animation after it completes so it can re-trigger\n const timer = setTimeout(\n () => setTiltAnim(undefined),\n totalDur * 1000 + 50\n );\n return () => clearTimeout(timer);\n }\n }\n }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);\n\n /* ============================================================ */\n /* Standard rendering (no remainJoined) */\n /* ============================================================ */\n\n const renderStandard = () =>\n faceList.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const transform = flat\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n const idx = STAGGER_ORDER.indexOf(face.name);\n const delay = oneAtATime\n ? (idx >= 0 ? idx : i) * transitionDuration\n : 0;\n\n return (\n <div\n key={face.name + \"-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform,\n transition: transitionCss(delay),\n }}\n >\n {body}\n </div>\n );\n });\n\n /* ============================================================ */\n /* Joined rendering — nested hinge structure */\n /* */\n /* Chain: front → right → back → left (hinged at shared edges) */\n /* The left–front edge is the break‑point. */\n /* */\n /* Flat order: front | right | back | left (left on far right) */\n /* ============================================================ */\n\n const renderJoined = () => {\n const findFace = (n: string) =>\n faceList.find((f) => f.name === n);\n\n const frontFace = findFace(\"front\");\n const rightFace = findFace(\"right\");\n const backFace = findFace(\"back\");\n const leftFace = findFace(\"left\");\n\n const sideNames = new Set([\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n ]);\n const otherFaces = faceList.filter(\n (f) => !sideNames.has(f.name)\n );\n\n const step = oneAtATime ? transitionDuration : 0;\n\n /* Helper: render a single face element with merged styles */\n const renderFaceEl = (\n face: FaceDef | undefined,\n dims: { width: number; height: number },\n extra: React.CSSProperties,\n key: string\n ) => {\n if (!face) return null;\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={key}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxSizing: \"border-box\",\n ...extra,\n }}\n >\n {body}\n </div>\n );\n };\n\n return (\n <>\n {/* ---- Front face (anchor) ---- */}\n {renderFaceEl(\n frontFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: \"50%\",\n top: \"50%\",\n transform: flat\n ? \"translate(-50%, -50%)\"\n : `translate(-50%, -50%) translateZ(${d / 2}px)`,\n transition: transitionCss(0),\n },\n \"front-j\"\n )}\n\n {/* ---- Right hinge (pivots at front's right edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: `calc(50% + ${w / 2}px)`,\n top: \"50%\",\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : `translateZ(${d / 2}px) rotateY(90deg)`,\n transition: transitionCss(step),\n }}\n >\n {/* Right face */}\n {renderFaceEl(\n rightFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"right-j\"\n )}\n\n {/* ---- Back hinge (pivots at right's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: d,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 2),\n }}\n >\n {/* Back face */}\n {renderFaceEl(\n backFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"back-j\"\n )}\n\n {/* ---- Left hinge (pivots at back's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: w,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: flat\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 3),\n }}\n >\n {/* Left face */}\n {renderFaceEl(\n leftFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"left-j\"\n )}\n </div>\n </div>\n </div>\n\n {/* ---- Non-side faces (top, bottom, etc.) ---- */}\n {otherFaces.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const xform = flat\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={face.name + \"-o-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform: xform,\n transition: transitionCss(0),\n }}\n >\n {body}\n </div>\n );\n })}\n </>\n );\n };\n\n /* ============================================================ */\n /* Render tree */\n /* ============================================================ */\n\n const cssVars = {\n \"--obj-w\": w + \"px\",\n \"--obj-h\": h + \"px\",\n \"--obj-d\": d + \"px\",\n } as React.CSSProperties;\n\n return (\n <div\n className={[\"anim3d-stage\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{\n perspective,\n perspectiveOrigin,\n ...cssVars,\n ...style,\n }}\n data-anim-3d-obj\n role=\"img\"\n aria-label=\"3D object\"\n >\n {/* Y-tilt wrapper — sits between stage and anim wrappers */}\n <div\n style={{\n transformStyle: \"preserve-3d\",\n animation: tiltAnim,\n }}\n >\n {/* Outer animation wrapper (anim1) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: flat ? \"none\" : animation1,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {/* Inner animation wrapper (anim2) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: flat ? \"none\" : animation2,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {showCenterDiv && (\n <div className=\"anim3d-center\" />\n )}\n {remainJoined\n ? renderJoined()\n : renderStandard()}\n </div>\n </div>\n </div>\n </div>\n );\n }\n);\n\nObj.displayName = \"Obj\";\n"]}
1
+ {"version":3,"sources":["../src/keyframes.ts","../src/components/Obj.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { AnimationConfig } from \"./types\";\n\n/** Create (or reuse) a <style> tag for dynamic keyframes */\nfunction ensureStyleTag(): HTMLStyleElement {\n let tag = document.getElementById(\n \"anim3d-keyframes\"\n ) as HTMLStyleElement | null;\n if (!tag) {\n tag = document.createElement(\"style\");\n tag.id = \"anim3d-keyframes\";\n document.head.appendChild(tag);\n }\n return tag;\n}\n\nfunction inject(css: string) {\n if (typeof document === \"undefined\") return; // SSR\n const tag = ensureStyleTag();\n tag.appendChild(document.createTextNode(css));\n}\n\n/** Keyframes text for built-ins */\nfunction builtInKeyframes(name: string, cfg: AnimationConfig) {\n const hi = cfg.degreesHi ?? 15;\n const lo = cfg.degreesLow ?? -15;\n switch (name) {\n case \"Y360\":\n return `@keyframes Y360 { from { transform: rotateY(0deg) } to { transform: rotateY(360deg) } }`;\n case \"X360\":\n return `@keyframes X360 { from { transform: rotateX(0deg) } to { transform: rotateX(360deg) } }`;\n case \"Z360\":\n return `@keyframes Z360 { from { transform: rotateZ(0deg) } to { transform: rotateZ(360deg) } }`;\n case \"rockY\":\n return `@keyframes rockY { 0%{ transform: rotateY(${lo}deg) } 50%{ transform: rotateY(${hi}deg) } 100%{ transform: rotateY(${lo}deg) } }`;\n case \"rockX\":\n return `@keyframes rockX { 0%{ transform: rotateX(${lo}deg) } 50%{ transform: rotateX(${hi}deg) } 100%{ transform: rotateX(${lo}deg) } }`;\n default:\n // Custom names: let authors supply their own @keyframes in global CSS with that name.\n return \"\";\n }\n}\n\n/** Returns a concrete animation-name and ensures keyframes exist (for built-ins) */\nexport function resolveAnimation(cfg?: AnimationConfig): string | null {\n if (!cfg) return null;\n const name = cfg.name;\n const builtIn = builtInKeyframes(name, cfg);\n if (builtIn) {\n // Ensure single injection per built-in name\n const marker = `/*kf-${name}*/`;\n if (typeof document !== \"undefined\") {\n const tag = ensureStyleTag();\n if (!tag.innerHTML.includes(marker)) {\n inject(`${builtIn}\\n${marker}`);\n }\n }\n return name; // use built-in name as animation-name\n }\n // custom: use author-provided @keyframes by name\n return name;\n}\n\n/** Build the full CSS animation shorthand from a config and resolved name */\nexport function toAnimationShorthand(cfg?: AnimationConfig): string | null {\n const name = resolveAnimation(cfg);\n if (!cfg || !name) return null;\n const dur = (cfg.duration ?? 10) + \"s\";\n const delay = (cfg.delay ?? 0) + \"s\";\n const iter = cfg.iterationCount ?? \"infinite\";\n const dir = cfg.direction ?? \"normal\";\n const timing = cfg.timing ?? \"linear\";\n const fill = cfg.fillMode ?? \"forwards\";\n const play = cfg.animationPlayState ?? \"running\";\n // name duration timing delay iteration-count direction fill-mode play-state\n return `${name} ${dur} ${timing} ${delay} ${iter} ${dir} ${fill} ${play}`;\n}\n","import * as React from \"react\";\nimport type {\n ObjProps,\n FaceDef,\n FaceName,\n FaceChainEffect,\n GlobalDef,\n} from \"../types\";\nimport { toAnimationShorthand } from \"../keyframes\";\nimport \"../styles/obj.css\";\n\n// Re-export the canonical ObjProps from types.ts\nexport type { ObjProps } from \"../types\";\n\n/* ------------------------------------------------------------------ */\n/* Face transform — 3D cuboid positions */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransform3D(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const hw = w / 2;\n const hh = h / 2;\n const hd = d / 2;\n\n switch (name as FaceName) {\n case \"front\":\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n case \"back\":\n return `translate(-50%, -50%) rotateY(180deg) translateZ(${hd}px)`;\n case \"left\":\n return `translate(-50%, -50%) rotateY(-90deg) translateZ(${hw}px)`;\n case \"right\":\n return `translate(-50%, -50%) rotateY(90deg) translateZ(${hw}px)`;\n case \"top\":\n return `translate(-50%, -50%) rotateX(90deg) translateZ(${hh}px)`;\n case \"bottom\":\n return `translate(-50%, -50%) rotateX(-90deg) translateZ(${hh}px)`;\n case \"top_front\":\n return `translate(-50%, -50%) rotateX(45deg) translateZ(${hh}px)`;\n case \"top_rear\":\n return `translate(-50%, -50%) rotateX(135deg) translateZ(${hh}px)`;\n case \"bottom_front\":\n return `translate(-50%, -50%) rotateX(-45deg) translateZ(${hh}px)`;\n case \"bottom_rear\":\n return `translate(-50%, -50%) rotateX(-135deg) translateZ(${hh}px)`;\n default:\n return `translate(-50%, -50%) translateZ(${hd}px)`;\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Face transform — flat (unfolded) positions */\n/* */\n/* Flat order: front | right | back | left */\n/* Centred on the midpoint of the full row. */\n/* ------------------------------------------------------------------ */\n\nfunction faceTransformFlat(\n name: string,\n w: number,\n h: number,\n d: number\n): string {\n const total = 2 * w + 2 * d;\n const half = total / 2;\n\n let cx: number;\n\n switch (name as FaceName) {\n case \"front\":\n cx = w / 2;\n break;\n case \"right\":\n cx = w + d / 2;\n break;\n case \"back\":\n cx = w + d + w / 2;\n break;\n case \"left\":\n cx = w + d + w + d / 2;\n break;\n case \"top\":\n case \"top_front\":\n case \"top_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(-${h}px)`;\n case \"bottom\":\n case \"bottom_front\":\n case \"bottom_rear\":\n cx = w / 2;\n return `translate(-50%, -50%) translateX(${cx - half}px) translateY(${h}px)`;\n default:\n cx = w / 2;\n break;\n }\n\n return `translate(-50%, -50%) translateX(${cx - half}px)`;\n}\n\n/* ------------------------------------------------------------------ */\n/* Parse a legacy CSS text string into a CSSProperties object */\n/* ------------------------------------------------------------------ */\n\nfunction parseCssText(css?: string): React.CSSProperties {\n if (!css) return {};\n const style: Record<string, string> = {};\n css.split(\";\").forEach((rule) => {\n const [prop, ...rest] = rule.split(\":\");\n if (!prop || rest.length === 0) return;\n const key = prop\n .trim()\n .replace(/-([a-z])/g, (_, c) => c.toUpperCase());\n style[key] = rest.join(\":\").trim();\n });\n return style as React.CSSProperties;\n}\n\n/* ------------------------------------------------------------------ */\n/* Resolve face dimensions for non-standard faces */\n/* ------------------------------------------------------------------ */\n\nfunction faceDimensions(\n name: string,\n w: number,\n h: number,\n d: number\n): { width: number; height: number } {\n switch (name as FaceName) {\n case \"left\":\n case \"right\":\n return { width: d, height: h };\n case \"top\":\n case \"bottom\":\n case \"top_front\":\n case \"top_rear\":\n case \"bottom_front\":\n case \"bottom_rear\":\n return { width: w, height: d };\n default:\n return { width: w, height: h };\n }\n}\n\n/* ------------------------------------------------------------------ */\n/* Build appearance style for a face (colours, borders, etc.) */\n/* Does NOT include position / transform / size. */\n/* ------------------------------------------------------------------ */\n\nfunction faceAppearance(\n face: FaceDef,\n globalDef?: GlobalDef\n): {\n style: React.CSSProperties;\n className: string;\n body: React.ReactNode;\n} {\n const globalStyle = parseCssText(globalDef?.css);\n const faceInlineStyle = parseCssText(face.css);\n\n const style: React.CSSProperties = {\n ...globalStyle,\n ...(globalDef?.style ?? {}),\n ...faceInlineStyle,\n ...(face.style ?? {}),\n };\n\n const className = [\"anim3d-face\", face.className]\n .filter(Boolean)\n .join(\" \");\n\n const body = face.body ?? globalDef?.body ?? null;\n\n return { style, className, body };\n}\n\n/* ------------------------------------------------------------------ */\n/* Default 6-sided cube when no faces are provided */\n/* ------------------------------------------------------------------ */\n\nconst DEFAULT_FACE_NAMES: FaceName[] = [\n \"front\",\n \"back\",\n \"left\",\n \"right\",\n \"top\",\n \"bottom\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Stagger order for oneAtATime (standard mode) */\n/* ------------------------------------------------------------------ */\n\nconst STAGGER_ORDER: string[] = [\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n \"top\",\n \"bottom\",\n \"top_front\",\n \"top_rear\",\n \"bottom_front\",\n \"bottom_rear\",\n];\n\n/* ------------------------------------------------------------------ */\n/* Component */\n/* ------------------------------------------------------------------ */\n\n/**\n * Animation phase state machine:\n *\n * folded ──(flat=true)──► unfolding ──(done)──► chaining ──(done)──► chained\n * ▲ │\n * └──(done)── folding ◄──(done)── unchaining ◄──(flat=false)──────────┘\n *\n * When there are no chainEffects the chaining/unchaining phases are\n * zero-duration and effectively skipped.\n */\ntype AnimPhase =\n | \"folded\"\n | \"unfolding\"\n | \"chaining\"\n | \"chained\"\n | \"unchaining\"\n | \"folding\";\n\nexport const Obj: React.FC<ObjProps> = React.memo(\n ({\n width = 160,\n height = 160,\n depth = 150,\n perspective = 600,\n perspectiveOrigin = \"50% 50%\",\n faces,\n global: globalDef,\n anim1,\n anim2,\n showCenterDiv = false,\n flat = false,\n transitionDuration = 1,\n oneAtATime = false,\n remainJoined = false,\n ytilt = false,\n backfaceHidden = false,\n chainEffects,\n onChainComplete,\n onChainReverseComplete,\n className,\n style,\n }) => {\n const w =\n typeof width === \"number\" ? width : parseFloat(String(width));\n const h =\n typeof height === \"number\" ? height : parseFloat(String(height));\n const d =\n typeof depth === \"number\" ? depth : parseFloat(String(depth));\n\n // Resolve animation shorthands\n const animation1 = toAnimationShorthand(anim1) ?? undefined;\n const animation2 = toAnimationShorthand(anim2) ?? undefined;\n\n /* ============================================================ */\n /* Chain-phase state machine */\n /* ============================================================ */\n\n const [phase, setPhase] = React.useState<AnimPhase>(\n flat ? \"chained\" : \"folded\"\n );\n\n const hasChain =\n Array.isArray(chainEffects) && chainEffects.length > 0;\n\n // Compute total unfold duration (includes stagger)\n const sideCountRef = React.useRef(0);\n\n // Max chain-effect duration (effect duration + effect delay)\n const chainDur = React.useMemo(() => {\n if (!hasChain) return 0;\n return Math.max(\n 0,\n ...chainEffects!.map(\n (e) => (e.duration ?? 0.5) + (e.delay ?? 0)\n )\n );\n }, [chainEffects, hasChain]);\n\n // React to `flat` prop changes\n const prevFlatForChain = React.useRef(flat);\n React.useEffect(() => {\n if (flat === prevFlatForChain.current) return;\n prevFlatForChain.current = flat;\n\n if (flat) {\n // Forward: start unfolding\n setPhase(\"unfolding\");\n } else {\n // Reverse: if chained, undo chain effects first\n if (hasChain && (phase === \"chained\" || phase === \"chaining\")) {\n setPhase(\"unchaining\");\n } else {\n setPhase(\"folding\");\n }\n }\n }, [flat]); // intentionally minimal deps — phase is read, not a dep\n\n // Phase transition timers\n React.useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n if (phase === \"unfolding\") {\n // Wait for unfold CSS transitions to finish, then chain\n const sideCount = sideCountRef.current;\n const unfoldDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n timer = setTimeout(() => {\n if (hasChain) {\n setPhase(\"chaining\");\n } else {\n setPhase(\"chained\");\n onChainComplete?.();\n }\n }, unfoldDur * 1000 + 60);\n }\n\n if (phase === \"chaining\") {\n timer = setTimeout(() => {\n setPhase(\"chained\");\n onChainComplete?.();\n }, chainDur * 1000 + 60);\n }\n\n if (phase === \"unchaining\") {\n timer = setTimeout(() => {\n setPhase(\"folding\");\n }, chainDur * 1000 + 60);\n }\n\n if (phase === \"folding\") {\n const sideCount = sideCountRef.current;\n const foldDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n timer = setTimeout(() => {\n setPhase(\"folded\");\n onChainReverseComplete?.();\n }, foldDur * 1000 + 60);\n }\n\n return () => {\n if (timer) clearTimeout(timer);\n };\n }, [\n phase,\n hasChain,\n chainDur,\n transitionDuration,\n oneAtATime,\n onChainComplete,\n onChainReverseComplete,\n ]);\n\n // Derived booleans for rendering\n const isFlatNow =\n phase === \"unfolding\" ||\n phase === \"chaining\" ||\n phase === \"chained\" ||\n phase === \"unchaining\";\n const chainActive = phase === \"chaining\" || phase === \"chained\";\n\n // Build a map of chain effects by face name for quick lookup\n const chainMap = React.useMemo(() => {\n const map = new Map<string, FaceChainEffect>();\n if (chainEffects) {\n for (const e of chainEffects) {\n map.set(e.faceName, e);\n }\n }\n return map;\n }, [chainEffects]);\n\n /** Merge chain-effect styles onto a face when chain is active */\n function chainStyle(\n faceName: string\n ): React.CSSProperties {\n const eff = chainMap.get(faceName);\n if (!eff) return {};\n\n const dur = (eff.duration ?? 0.5) + \"s\";\n const delay = (eff.delay ?? 0) + \"s\";\n const timing = eff.timing ?? \"ease-in-out\";\n\n const props: string[] = [];\n const styles: React.CSSProperties = {};\n\n if (eff.scaleX !== undefined || eff.scaleY !== undefined) {\n const sx = eff.scaleX ?? 1;\n const sy = eff.scaleY ?? 1;\n if (chainActive) {\n styles.transform =\n (styles.transform ?? \"\") + ` scaleX(${sx}) scaleY(${sy})`;\n }\n props.push(\"transform\");\n }\n\n if (eff.background !== undefined) {\n if (chainActive) {\n styles.background = eff.background;\n }\n props.push(\"background\");\n }\n\n if (eff.opacity !== undefined) {\n if (chainActive) {\n styles.opacity = eff.opacity;\n }\n props.push(\"opacity\");\n }\n\n // Build transition string for chain properties\n if (props.length > 0) {\n const transitionParts = props.map(\n (p) => `${p} ${dur} ${timing} ${delay}`\n );\n styles.transition = transitionParts.join(\", \");\n }\n\n return styles;\n }\n\n // Determine which faces to render\n const faceList: FaceDef[] =\n faces && faces.length > 0\n ? faces\n : DEFAULT_FACE_NAMES.map((name) => ({ name }));\n\n // Keep sideCountRef up to date for phase timer calculations\n sideCountRef.current = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(f.name)\n ).length;\n\n const bfv: React.CSSProperties[\"backfaceVisibility\"] =\n backfaceHidden ? \"hidden\" : \"visible\";\n\n const transitionCss = (delay = 0) =>\n `transform ${transitionDuration}s ease-in-out ${delay}s`;\n\n /* ============================================================ */\n /* Y-tilt — fire a one-shot rotateX(0→45→0) each time */\n /* flat changes. We alternate between two identical keyframe */\n /* names (a/b) so the browser re-triggers the animation. */\n /* ============================================================ */\n\n const tiltCount = React.useRef(0);\n const prevFlat = React.useRef(flat);\n const [tiltAnim, setTiltAnim] = React.useState<\n string | undefined\n >(undefined);\n\n React.useEffect(() => {\n if (flat !== prevFlat.current) {\n prevFlat.current = flat;\n if (ytilt) {\n tiltCount.current += 1;\n const sideCount = faceList.filter((f) =>\n [\"front\", \"right\", \"back\", \"left\"].includes(\n f.name\n )\n ).length;\n const totalDur = oneAtATime\n ? transitionDuration * sideCount\n : transitionDuration;\n const name =\n tiltCount.current % 2 === 0\n ? \"anim3d-ytilt-a\"\n : \"anim3d-ytilt-b\";\n setTiltAnim(\n `${name} ${totalDur}s ease-in-out 1 forwards`\n );\n // Clear animation after it completes so it can re-trigger\n const timer = setTimeout(\n () => setTiltAnim(undefined),\n totalDur * 1000 + 50\n );\n return () => clearTimeout(timer);\n }\n }\n }, [flat, ytilt, transitionDuration, oneAtATime, faceList]);\n\n /* ============================================================ */\n /* Standard rendering (no remainJoined) */\n /* ============================================================ */\n\n const renderStandard = () =>\n faceList.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const baseTransform = isFlatNow\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n const idx = STAGGER_ORDER.indexOf(face.name);\n const delay = oneAtATime\n ? (idx >= 0 ? idx : i) * transitionDuration\n : 0;\n\n // Merge chain-effect styles\n const cStyle = chainStyle(face.name);\n // Chain scale is appended to the flat transform\n const scaleAppend =\n cStyle.transform\n ? ` ${cStyle.transform}`\n : \"\";\n const transform = baseTransform + scaleAppend;\n // Build combined transition: fold transition + chain transitions\n const foldTransition = transitionCss(delay);\n const combinedTransition = cStyle.transition\n ? `${foldTransition}, ${cStyle.transition}`\n : foldTransition;\n\n return (\n <div\n key={face.name + \"-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n ...cStyle,\n width: dims.width,\n height: dims.height,\n transform,\n transition: combinedTransition,\n backfaceVisibility: bfv,\n }}\n >\n {body}\n </div>\n );\n });\n\n /* ============================================================ */\n /* Joined rendering — nested hinge structure */\n /* */\n /* Chain: front → right → back → left (hinged at shared edges) */\n /* The left–front edge is the break‑point. */\n /* */\n /* Flat order: front | right | back | left (left on far right) */\n /* ============================================================ */\n\n const renderJoined = () => {\n const findFace = (n: string) =>\n faceList.find((f) => f.name === n);\n\n const frontFace = findFace(\"front\");\n const rightFace = findFace(\"right\");\n const backFace = findFace(\"back\");\n const leftFace = findFace(\"left\");\n\n const sideNames = new Set([\n \"front\",\n \"right\",\n \"back\",\n \"left\",\n ]);\n const otherFaces = faceList.filter(\n (f) => !sideNames.has(f.name)\n );\n\n const step = oneAtATime ? transitionDuration : 0;\n\n /* Helper: render a single face element with merged styles */\n const renderFaceEl = (\n face: FaceDef | undefined,\n dims: { width: number; height: number },\n extra: React.CSSProperties,\n key: string\n ) => {\n if (!face) return null;\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n\n // Chain effect styles\n const cStyle = chainStyle(face.name);\n // If chain has a scale transform, append it to existing transform\n const baseTransform = extra.transform ?? \"\";\n const scaleAppend = cStyle.transform\n ? ` ${cStyle.transform}`\n : \"\";\n const mergedTransform = baseTransform\n ? `${baseTransform}${scaleAppend}`\n : scaleAppend || undefined;\n\n const foldTransition =\n (extra.transition as string) ?? \"\";\n const combinedTransition = cStyle.transition\n ? `${foldTransition}, ${cStyle.transition}`\n : foldTransition;\n\n return (\n <div\n key={key}\n className={fCls}\n style={{\n ...fStyle,\n ...cStyle,\n width: dims.width,\n height: dims.height,\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n boxSizing: \"border-box\",\n backfaceVisibility: bfv,\n ...extra,\n transform: mergedTransform ?? extra.transform,\n transition: combinedTransition || extra.transition,\n }}\n >\n {body}\n </div>\n );\n };\n\n return (\n <>\n {/* ---- Front face (anchor) ---- */}\n {renderFaceEl(\n frontFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: \"50%\",\n top: \"50%\",\n transform: isFlatNow\n ? \"translate(-50%, -50%)\"\n : `translate(-50%, -50%) translateZ(${d / 2}px)`,\n transition: transitionCss(0),\n },\n \"front-j\"\n )}\n\n {/* ---- Right hinge (pivots at front's right edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: `calc(50% + ${w / 2}px)`,\n top: \"50%\",\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : `translateZ(${d / 2}px) rotateY(90deg)`,\n transition: transitionCss(step),\n }}\n >\n {/* Right face */}\n {renderFaceEl(\n rightFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"right-j\"\n )}\n\n {/* ---- Back hinge (pivots at right's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: d,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 2),\n }}\n >\n {/* Back face */}\n {renderFaceEl(\n backFace,\n { width: w, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"back-j\"\n )}\n\n {/* ---- Left hinge (pivots at back's far edge) ---- */}\n <div\n style={{\n position: \"absolute\",\n left: w,\n top: 0,\n width: 0,\n height: 0,\n transformOrigin: \"0 0\",\n transformStyle: \"preserve-3d\",\n transform: isFlatNow\n ? \"none\"\n : \"rotateY(90deg)\",\n transition: transitionCss(step * 3),\n }}\n >\n {/* Left face */}\n {renderFaceEl(\n leftFace,\n { width: d, height: h },\n {\n position: \"absolute\",\n left: 0,\n top: 0,\n transform: \"translateY(-50%)\",\n },\n \"left-j\"\n )}\n </div>\n </div>\n </div>\n\n {/* ---- Non-side faces (top, bottom, etc.) ---- */}\n {otherFaces.map((face, i) => {\n const dims = faceDimensions(face.name, w, h, d);\n const xform = isFlatNow\n ? faceTransformFlat(face.name, w, h, d)\n : faceTransform3D(face.name, w, h, d);\n const {\n style: fStyle,\n className: fCls,\n body,\n } = faceAppearance(face, globalDef);\n return (\n <div\n key={face.name + \"-o-\" + i}\n className={fCls}\n style={{\n ...fStyle,\n width: dims.width,\n height: dims.height,\n transform: xform,\n transition: transitionCss(0),\n backfaceVisibility: bfv,\n }}\n >\n {body}\n </div>\n );\n })}\n </>\n );\n };\n\n /* ============================================================ */\n /* Render tree */\n /* ============================================================ */\n\n const cssVars = {\n \"--obj-w\": w + \"px\",\n \"--obj-h\": h + \"px\",\n \"--obj-d\": d + \"px\",\n } as React.CSSProperties;\n\n return (\n <div\n className={[\"anim3d-stage\", className]\n .filter(Boolean)\n .join(\" \")}\n style={{\n perspective,\n perspectiveOrigin,\n ...cssVars,\n ...style,\n }}\n data-anim-3d-obj\n role=\"img\"\n aria-label=\"3D object\"\n >\n {/* Y-tilt wrapper — sits between stage and anim wrappers */}\n <div\n style={{\n transformStyle: \"preserve-3d\",\n animation: tiltAnim,\n }}\n >\n {/* Outer animation wrapper (anim1) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: isFlatNow ? \"none\" : animation1,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {/* Inner animation wrapper (anim2) */}\n <div\n className=\"anim3d-wrapper\"\n style={{\n ...cssVars,\n animation: isFlatNow ? \"none\" : animation2,\n transformStyle: \"preserve-3d\",\n transition: transitionCss(),\n }}\n >\n {showCenterDiv && (\n <div className=\"anim3d-center\" />\n )}\n {remainJoined\n ? renderJoined()\n : renderStandard()}\n </div>\n </div>\n </div>\n </div>\n );\n }\n);\n\nObj.displayName = \"Obj\";\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "anim-3d-obj",
3
- "version": "2.0.8",
3
+ "version": "2.0.10",
4
4
  "description": "Configurable 3D object with animated rotations and face content",
5
5
  "license": "MIT",
6
6
  "author": "mdnelles",