react-holographic-cube 1.0.6 → 1.0.7

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.css CHANGED
@@ -1,2 +1,2 @@
1
- .scene{align-items:center;display:flex;height:100%;justify-content:center;perspective:1000px;position:relative;transform-style:preserve-3d;width:100%}.light-pillar{filter:blur(20px);pointer-events:none;transform:translate(-50%,-50%) translateZ(-250px);z-index:0}.cube-shadow,.light-pillar{left:50%;position:absolute;top:50%}.cube-shadow{background:rgba(0,247,255,.2);box-shadow:0 0 50px rgba(0,247,255,.5);filter:blur(15px);height:160px;margin-top:130px;transform:translate(-50%,-50%) rotateX(90deg) translateZ(-128px);width:160px;z-index:2}.cube-wrapper{height:200px;position:relative;transform-style:preserve-3d;transition:transform 4s ease-in-out;width:200px}.cube-wrapper.locked{transform:translateZ(0) rotateX(0) rotateY(0) rotate(0)!important;transition:transform .5s cubic-bezier(.2,.8,.2,1)}.cube{height:100%;position:relative;transform-style:preserve-3d;transition:none;width:100%;will-change:transform;z-index:10}.face{align-items:center;backdrop-filter:blur(8px);backface-visibility:hidden;background:rgba(0,20,40,.6);border:2px solid #00db46;border-radius:1.25rem;box-shadow:0 0 15px rgba(0,247,255,.3),inset 0 0 30px rgba(0,247,255,.1);display:flex;font-size:80px;height:200px;justify-content:center;position:absolute;text-shadow:0 0 20px rgba(0,219,70,.95);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:200px}.front{transform:rotateX(0deg) translateZ(100px)}.bottom{transform:rotateX(-90deg) translateZ(100px)}.back{transform:rotateX(-180deg) translateZ(100px)}.top{transform:rotateX(-270deg) translateZ(100px)}.left{transform:rotateY(-90deg) translateZ(100px)}.right{transform:rotateY(90deg) translateZ(100px)}.cube.is-spinning .face{animation:energyPulse .1s infinite alternate;border-color:#afffd3;box-shadow:0 0 40px rgba(0,219,70,.6),inset 0 0 60px rgba(0,219,70,.4)}@keyframes energyPulse{0%{box-shadow:0 0 30px rgba(0,219,70,.5),inset 0 0 40px rgba(0,219,70,.3)}to{background:rgba(0,219,70,.2);box-shadow:0 0 60px #00db46,inset 0 0 70px rgba(0,219,70,.6)}}.controls{display:flex;gap:20px;justify-content:center;margin-top:20px;position:relative;z-index:20}.winner-text{color:#fff;font-size:2rem;font-weight:800;letter-spacing:1px;margin-top:2rem;min-height:50px;text-align:center;text-shadow:0 0 15px rgba(0,219,70,.95)}.cyber-button{background:transparent;border:2px solid #00db46;box-shadow:0 0 10px rgba(0,247,255,.2);color:#00db46;cursor:pointer;font-size:16px;font-weight:700;letter-spacing:2px;outline:none;padding:12px 36px;text-transform:uppercase;transition:all .2s ease}.cyber-button:hover:not(:disabled){background:#00db46;box-shadow:0 0 25px rgba(0,219,70,.8);color:#000}.cyber-button:disabled{border-color:#555;box-shadow:none;color:#555;cursor:not-allowed;opacity:.3}.stop-btn{border-color:#7f63f5;box-shadow:0 0 10px rgba(127,99,245,.5);color:#7f63f5}.stop-btn:hover:not(:disabled){background:#7f63f5;box-shadow:0 0 25px rgba(127,99,245,.8);color:#fff}
1
+ .scene{align-items:center;display:flex;height:100%;justify-content:center;perspective:1000px;position:relative;transform-style:preserve-3d;width:100%}.light-pillar{filter:blur(20px);pointer-events:none;transform:translate(-50%,-50%) translateZ(-250px);z-index:0}.cube-shadow,.light-pillar{left:50%;position:absolute;top:50%}.cube-shadow{background:rgba(0,247,255,.2);box-shadow:0 0 50px rgba(0,247,255,.5);filter:blur(15px);height:160px;margin-top:130px;transform:translate(-50%,-50%) rotateX(90deg) translateZ(-128px);width:160px;z-index:2}.cube-wrapper{height:200px;position:relative;transform-style:preserve-3d;transition:transform 4s ease-in-out;width:200px}.cube-wrapper.locked{transform:translateZ(0) rotateX(0) rotateY(0) rotate(0)!important;transition:transform .5s cubic-bezier(.2,.8,.2,1)}.cube{height:100%;position:relative;transform-style:preserve-3d;transition:none;width:100%;will-change:transform;z-index:10}.face{align-items:center;backdrop-filter:blur(8px);backface-visibility:hidden;background:rgba(0,20,40,.6);border:2px solid #00db46;border-radius:1.25rem;box-shadow:0 0 15px rgba(0,247,255,.3),inset 0 0 30px rgba(0,247,255,.1);display:flex;font-size:80px;height:200px;justify-content:center;position:absolute;text-shadow:0 0 20px rgba(0,219,70,.95);-webkit-user-select:none;-moz-user-select:none;user-select:none;width:200px}.front{transform:rotateX(0deg) translateZ(100px)}.bottom{transform:rotateX(-90deg) translateZ(100px)}.back{transform:rotateX(-180deg) translateZ(100px)}.top{transform:rotateX(-270deg) translateZ(100px)}.left{transform:rotateY(-90deg) translateZ(100px)}.right{transform:rotateY(90deg) translateZ(100px)}.cube.is-spinning .face{animation:energyPulse .1s infinite alternate;border-color:#afffd3;box-shadow:0 0 40px rgba(0,219,70,.6),inset 0 0 60px rgba(0,219,70,.4)}@keyframes energyPulse{0%{box-shadow:0 0 30px rgba(0,219,70,.5),inset 0 0 40px rgba(0,219,70,.3)}to{background:rgba(0,219,70,.2);box-shadow:0 0 60px #00db46,inset 0 0 70px rgba(0,219,70,.6)}}.controls-container{bottom:10%;pointer-events:none;position:absolute;text-align:center;width:100%;z-index:30}.controls{display:flex;gap:20px;justify-content:center;margin-top:20px;pointer-events:auto}.winner-text{color:#fff;font-size:2rem;font-weight:800;letter-spacing:1px;margin-top:2rem;min-height:50px;text-shadow:0 0 15px rgba(0,219,70,.95)}.cyber-button{background:transparent;border:2px solid #00db46;box-shadow:0 0 10px rgba(0,247,255,.2);color:#00db46;cursor:pointer;font-size:16px;font-weight:700;letter-spacing:2px;outline:none;padding:12px 36px;pointer-events:auto;text-transform:uppercase;transition:all .2s ease}.cyber-button:hover:not(:disabled){background:#00db46;box-shadow:0 0 25px rgba(0,219,70,.8);color:#000}.cyber-button:disabled{border-color:#555;box-shadow:none;color:#555;cursor:not-allowed;opacity:.3}.stop-btn{border-color:#7f63f5;box-shadow:0 0 10px rgba(127,99,245,.5);color:#7f63f5}.stop-btn:hover:not(:disabled){background:#7f63f5;box-shadow:0 0 25px rgba(127,99,245,.8);color:#fff}
2
2
  /*# sourceMappingURL=index.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["styles.css"],"names":[],"mappings":"AAQA,OASE,kBAAmB,CADnB,YAAa,CANb,WAAY,CAQZ,sBAAuB,CAPvB,kBAAmB,CACnB,iBAAkB,CAClB,2BAA4B,CAJ5B,UAUF,CAIA,cAKE,iBAAkB,CAClB,mBAAoB,CAFpB,iDAAmD,CAGnD,SACF,CAGA,2BATE,QAAS,CADT,iBAAkB,CAElB,OAsBF,CAdA,aAIE,6BAAkC,CAClC,sCAA2C,CAI3C,iBAAkB,CANlB,YAAa,CAUb,gBAAiB,CALjB,gEAAkE,CANlE,WAAY,CAQZ,SAIF,CAMA,cAEE,YAAa,CACb,iBAAkB,CAClB,2BAA4B,CAC5B,mCAAoC,CAJpC,WAKF,CAEA,qBAEE,iEAA2E,CAD3E,iDAEF,CAGA,MAEE,WAAY,CACZ,iBAAkB,CAClB,2BAA4B,CAE5B,eAAgB,CALhB,UAAW,CAMX,qBAAsB,CAFtB,UAGF,CAMA,MAUE,kBAAmB,CALnB,yBAA0B,CAS1B,0BAA2B,CAV3B,2BAAgC,CAEhC,wBAAyB,CACzB,qBAAsB,CACtB,wEAAkF,CAClF,YAAa,CAGb,cAAe,CATf,YAAa,CAQb,sBAAuB,CAVvB,iBAAkB,CAYlB,uCAA4C,CAE5C,wBAAiB,CAAjB,qBAAiB,CAAjB,gBAAiB,CAbjB,WAcF,CAGA,OAAU,yCAA4C,CACtD,QAAU,2CAA8C,CACxD,MAAU,4CAA+C,CACzD,KAAU,4CAA+C,CACzD,MAAU,2CAA8C,CACxD,OAAU,0CAA6C,CAMvD,wBAGE,4CAA8C,CAF9C,oBAAqB,CACrB,sEAEF,CAEA,uBACE,GAAK,sEAAkF,CACvF,GAAuF,4BAAiC,CAAjH,4DAAmH,CAC5H,CAMA,UAEE,YAAa,CAEb,QAAS,CADT,sBAAuB,CAFvB,eAAgB,CAIhB,iBAAkB,CAClB,UACF,CAEA,aAIE,UAAc,CAFd,cAAe,CACf,eAAgB,CAIhB,kBAAmB,CANnB,eAAgB,CAKhB,eAAgB,CAEhB,iBAAkB,CAHlB,uCAIF,CAEA,cACE,sBAAuB,CACvB,wBAAyB,CAQzB,sCAA2C,CAP3C,aAAc,CAMd,cAAe,CAJf,cAAe,CACf,eAAiB,CAEjB,kBAAmB,CAInB,YAAa,CARb,iBAAkB,CAGlB,wBAAyB,CAIzB,uBAEF,CAEA,mCACE,kBAAmB,CAEnB,qCAA0C,CAD1C,UAEF,CAEA,uBAGE,iBAAkB,CAElB,eAAgB,CADhB,UAAW,CAFX,kBAAmB,CADnB,UAKF,CAEA,UACE,oBAAqB,CAErB,uCAA4C,CAD5C,aAEF,CAEA,+BACE,kBAAmB,CAEnB,uCAA4C,CAD5C,UAEF","file":"index.css","sourcesContent":["/* =========================================\n 1. The 3D Scene & Environment\n ========================================= */\n\n/* UPDATED SCENE:\n - Uses Flexbox to perfectly center the cube.\n - Defaults to 100% size of its parent.\n*/\n.scene {\n width: 100%;\n height: 100%;\n perspective: 1000px;\n position: relative;\n transform-style: preserve-3d;\n \n /* Centering Magic */\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* The Background Light Pillar */\n/* Note: We removed the hardcoded sizing here to let JS handle it */\n.light-pillar {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%) translateZ(-250px);\n filter: blur(20px);\n pointer-events: none;\n z-index: 0;\n}\n\n/* The Shadow underneath the floating cube */\n.cube-shadow {\n position: absolute;\n width: 160px;\n height: 160px;\n background: rgba(0, 247, 255, 0.2);\n box-shadow: 0 0 50px rgba(0, 247, 255, 0.5);\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%) rotateX(90deg) translateZ(-128px);\n filter: blur(15px);\n z-index: 2;\n \n /* Ensure shadow stays centered regardless of pillar */\n margin-top: 130px; /* Offset to sit below the cube */\n}\n\n/* =========================================\n 2. The Cube & Wrapper\n ========================================= */\n\n.cube-wrapper {\n width: 200px; /* Fixed width prevents layout shifting */\n height: 200px;\n position: relative;\n transform-style: preserve-3d;\n transition: transform 4s ease-in-out; \n}\n\n.cube-wrapper.locked {\n transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);\n transform: translate3d(0, 0, 0) rotateX(0) rotateY(0) rotateZ(0) !important;\n}\n\n/* The Inner Cube */\n.cube {\n width: 100%;\n height: 100%;\n position: relative;\n transform-style: preserve-3d;\n z-index: 10;\n transition: none; \n will-change: transform;\n}\n\n/* =========================================\n 3. The Faces (Holographic Style)\n ========================================= */\n\n.face {\n position: absolute;\n width: 200px;\n height: 200px;\n background: rgba(0, 20, 40, 0.6);\n backdrop-filter: blur(8px);\n border: 2px solid #00db46;\n border-radius: 1.25rem;\n box-shadow: 0 0 15px rgba(0, 247, 255, 0.3), inset 0 0 30px rgba(0, 247, 255, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 80px;\n text-shadow: 0 0 20px rgba(0, 219, 70, 0.95);\n backface-visibility: hidden;\n user-select: none;\n}\n\n/* Face Positions */\n.front { transform: rotateX(0deg) translateZ(100px); }\n.bottom { transform: rotateX(-90deg) translateZ(100px); }\n.back { transform: rotateX(-180deg) translateZ(100px); }\n.top { transform: rotateX(-270deg) translateZ(100px); }\n.left { transform: rotateY(-90deg) translateZ(100px); }\n.right { transform: rotateY(90deg) translateZ(100px); }\n\n/* =========================================\n 4. High Energy Spin Effects\n ========================================= */\n\n.cube.is-spinning .face {\n border-color: #afffd3;\n box-shadow: 0 0 40px rgba(0, 219, 70, 0.6), inset 0 0 60px rgba(0, 219, 70, 0.4);\n animation: energyPulse 0.1s infinite alternate;\n}\n\n@keyframes energyPulse {\n 0% { box-shadow: 0 0 30px rgba(0, 219, 70, 0.5), inset 0 0 40px rgba(0, 219, 70, 0.3); }\n 100% { box-shadow: 0 0 60px rgba(0, 219, 70, 1), inset 0 0 70px rgba(0, 219, 70, 0.6); background: rgba(0, 219, 70, 0.2); }\n}\n\n/* =========================================\n 5. UI Controls\n ========================================= */\n\n.controls {\n margin-top: 20px;\n display: flex;\n justify-content: center;\n gap: 20px;\n position: relative;\n z-index: 20;\n}\n\n.winner-text {\n margin-top: 2rem;\n font-size: 2rem;\n font-weight: 800;\n color: #ffffff;\n text-shadow: 0 0 15px rgba(0, 219, 70, 0.95);\n min-height: 50px;\n letter-spacing: 1px;\n text-align: center;\n}\n\n.cyber-button {\n background: transparent;\n border: 2px solid #00db46;\n color: #00db46;\n padding: 12px 36px;\n font-size: 16px;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 2px;\n cursor: pointer;\n box-shadow: 0 0 10px rgba(0, 247, 255, 0.2);\n transition: all 0.2s ease;\n outline: none;\n}\n\n.cyber-button:hover:not(:disabled) {\n background: #00db46;\n color: #000;\n box-shadow: 0 0 25px rgba(0, 219, 70, 0.8);\n}\n\n.cyber-button:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n border-color: #555;\n color: #555;\n box-shadow: none;\n}\n\n.stop-btn {\n border-color: #7f63f5;\n color: #7f63f5;\n box-shadow: 0 0 10px rgba(127, 99, 245, 0.5);\n}\n\n.stop-btn:hover:not(:disabled) {\n background: #7f63f5;\n color: #fff;\n box-shadow: 0 0 25px rgba(127, 99, 245, 0.8);\n}\n"]}
1
+ {"version":3,"sources":["styles.css"],"names":[],"mappings":"AAKA,OAOE,kBAAmB,CADnB,YAAa,CAJb,WAAY,CAMZ,sBAAuB,CALvB,kBAAmB,CACnB,iBAAkB,CAClB,2BAA4B,CAJ5B,UAQF,CAIA,cAKE,iBAAkB,CAClB,mBAAoB,CAFpB,iDAAmD,CAGnD,SACF,CAGA,2BATE,QAAS,CADT,iBAAkB,CAElB,OAqBF,CAbA,aAIE,6BAAkC,CAClC,sCAA2C,CAI3C,iBAAkB,CANlB,YAAa,CASb,gBAAiB,CAJjB,gEAAkE,CANlE,WAAY,CAQZ,SAGF,CAMA,cAEE,YAAa,CACb,iBAAkB,CAClB,2BAA4B,CAC5B,mCAAoC,CAJpC,WAKF,CAEA,qBAEE,iEAA2E,CAD3E,iDAEF,CAEA,MAEE,WAAY,CACZ,iBAAkB,CAClB,2BAA4B,CAE5B,eAAgB,CALhB,UAAW,CAMX,qBAAsB,CAFtB,UAGF,CAMA,MAUE,kBAAmB,CALnB,yBAA0B,CAS1B,0BAA2B,CAV3B,2BAAgC,CAEhC,wBAAyB,CACzB,qBAAsB,CACtB,wEAAkF,CAClF,YAAa,CAGb,cAAe,CATf,YAAa,CAQb,sBAAuB,CAVvB,iBAAkB,CAYlB,uCAA4C,CAE5C,wBAAiB,CAAjB,qBAAiB,CAAjB,gBAAiB,CAbjB,WAcF,CAGA,OAAU,yCAA4C,CACtD,QAAU,2CAA8C,CACxD,MAAU,4CAA+C,CACzD,KAAU,4CAA+C,CACzD,MAAU,2CAA8C,CACxD,OAAU,0CAA6C,CAMvD,wBAGE,4CAA8C,CAF9C,oBAAqB,CACrB,sEAEF,CAEA,uBACE,GAAK,sEAAkF,CACvF,GAAuF,4BAAiC,CAAjH,4DAAmH,CAC5H,CAOA,oBAEE,UAAW,CAIX,mBAAoB,CALpB,iBAAkB,CAGlB,iBAAkB,CADlB,UAAW,CAEX,UAEF,CAEA,UAEE,YAAa,CAEb,QAAS,CADT,sBAAuB,CAFvB,eAAgB,CAIhB,mBACF,CAEA,aAIE,UAAc,CAFd,cAAe,CACf,eAAgB,CAIhB,kBAAmB,CANnB,eAAgB,CAKhB,eAAgB,CADhB,uCAGF,CAEA,cACE,sBAAuB,CACvB,wBAAyB,CAQzB,sCAA2C,CAP3C,aAAc,CAMd,cAAe,CAJf,cAAe,CACf,eAAiB,CAEjB,kBAAmB,CAInB,YAAa,CARb,iBAAkB,CASlB,mBAAoB,CANpB,wBAAyB,CAIzB,uBAGF,CAEA,mCACE,kBAAmB,CAEnB,qCAA0C,CAD1C,UAEF,CAEA,uBAGE,iBAAkB,CAElB,eAAgB,CADhB,UAAW,CAFX,kBAAmB,CADnB,UAKF,CAEA,UACE,oBAAqB,CAErB,uCAA4C,CAD5C,aAEF,CAEA,+BACE,kBAAmB,CAEnB,uCAA4C,CAD5C,UAEF","file":"index.css","sourcesContent":["/* =========================================\n 1. The 3D Scene & Environment\n ========================================= */\n\n/* The Scene now uses Flexbox to center the cube inside whatever container you put it in */\n.scene {\n width: 100%;\n height: 100%;\n perspective: 1000px;\n position: relative;\n transform-style: preserve-3d;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* The Background Light Pillar */\n/* We removed fixed sizes here so JS can control them via props */\n.light-pillar {\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%) translateZ(-250px);\n filter: blur(20px);\n pointer-events: none;\n z-index: 0;\n}\n\n/* The Shadow underneath the floating cube */\n.cube-shadow {\n position: absolute;\n width: 160px;\n height: 160px;\n background: rgba(0, 247, 255, 0.2);\n box-shadow: 0 0 50px rgba(0, 247, 255, 0.5);\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%) rotateX(90deg) translateZ(-128px);\n filter: blur(15px);\n z-index: 2;\n /* Push shadow down so it sits below the cube */\n margin-top: 130px; \n}\n\n/* =========================================\n 2. The Cube & Wrapper\n ========================================= */\n\n.cube-wrapper {\n width: 200px; \n height: 200px;\n position: relative;\n transform-style: preserve-3d;\n transition: transform 4s ease-in-out; \n}\n\n.cube-wrapper.locked {\n transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);\n transform: translate3d(0, 0, 0) rotateX(0) rotateY(0) rotateZ(0) !important;\n}\n\n.cube {\n width: 100%;\n height: 100%;\n position: relative;\n transform-style: preserve-3d;\n z-index: 10;\n transition: none; \n will-change: transform;\n}\n\n/* =========================================\n 3. The Faces (Holographic Style)\n ========================================= */\n\n.face {\n position: absolute;\n width: 200px;\n height: 200px;\n background: rgba(0, 20, 40, 0.6);\n backdrop-filter: blur(8px);\n border: 2px solid #00db46;\n border-radius: 1.25rem;\n box-shadow: 0 0 15px rgba(0, 247, 255, 0.3), inset 0 0 30px rgba(0, 247, 255, 0.1);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 80px;\n text-shadow: 0 0 20px rgba(0, 219, 70, 0.95);\n backface-visibility: hidden;\n user-select: none;\n}\n\n/* Face Positions */\n.front { transform: rotateX(0deg) translateZ(100px); }\n.bottom { transform: rotateX(-90deg) translateZ(100px); }\n.back { transform: rotateX(-180deg) translateZ(100px); }\n.top { transform: rotateX(-270deg) translateZ(100px); }\n.left { transform: rotateY(-90deg) translateZ(100px); }\n.right { transform: rotateY(90deg) translateZ(100px); }\n\n/* =========================================\n 4. High Energy Spin Effects\n ========================================= */\n\n.cube.is-spinning .face {\n border-color: #afffd3;\n box-shadow: 0 0 40px rgba(0, 219, 70, 0.6), inset 0 0 60px rgba(0, 219, 70, 0.4);\n animation: energyPulse 0.1s infinite alternate;\n}\n\n@keyframes energyPulse {\n 0% { box-shadow: 0 0 30px rgba(0, 219, 70, 0.5), inset 0 0 40px rgba(0, 219, 70, 0.3); }\n 100% { box-shadow: 0 0 60px rgba(0, 219, 70, 1), inset 0 0 70px rgba(0, 219, 70, 0.6); background: rgba(0, 219, 70, 0.2); }\n}\n\n/* =========================================\n 5. UI Controls (Winner Text & Buttons)\n ========================================= */\n\n/* The container for buttons and text */\n.controls-container {\n position: absolute;\n bottom: 10%;\n width: 100%;\n text-align: center;\n z-index: 30;\n pointer-events: none; /* Let clicks pass through empty areas */\n}\n\n.controls {\n margin-top: 20px;\n display: flex;\n justify-content: center;\n gap: 20px;\n pointer-events: auto; /* Re-enable clicks on buttons */\n}\n\n.winner-text {\n margin-top: 2rem;\n font-size: 2rem;\n font-weight: 800;\n color: #ffffff;\n text-shadow: 0 0 15px rgba(0, 219, 70, 0.95);\n min-height: 50px;\n letter-spacing: 1px;\n}\n\n.cyber-button {\n background: transparent;\n border: 2px solid #00db46;\n color: #00db46;\n padding: 12px 36px;\n font-size: 16px;\n font-weight: bold;\n text-transform: uppercase;\n letter-spacing: 2px;\n cursor: pointer;\n box-shadow: 0 0 10px rgba(0, 247, 255, 0.2);\n transition: all 0.2s ease;\n outline: none;\n pointer-events: auto;\n}\n\n.cyber-button:hover:not(:disabled) {\n background: #00db46;\n color: #000;\n box-shadow: 0 0 25px rgba(0, 219, 70, 0.8);\n}\n\n.cyber-button:disabled {\n opacity: 0.3;\n cursor: not-allowed;\n border-color: #555;\n color: #555;\n box-shadow: none;\n}\n\n.stop-btn {\n border-color: #7f63f5;\n color: #7f63f5;\n box-shadow: 0 0 10px rgba(127, 99, 245, 0.5);\n}\n\n.stop-btn:hover:not(:disabled) {\n background: #7f63f5;\n color: #fff;\n box-shadow: 0 0 25px rgba(127, 99, 245, 0.8);\n}"]}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/t(e);function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}var a=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}];module.exports=function(t){var o=t.items,l=void 0===o?a:o,c=t.onWinner,i=t.perspective,u=void 0===i?"1000px":i,s=t.initialSpeed,d=void 0===s?30:s,f=t.friction,m=void 0===f?.98:f,p=t.showResult,v=void 0===p||p,g=t.resultStyle,b=void 0===g?{}:g,h=t.cubeStyle,y=void 0===h?{}:h,x=t.showPillar,E=void 0===x||x,w=t.pillarColor,N=void 0===w?"rgba(0, 247, 255, 0.1)":w,S=t.pillarSize,R=void 0===S?{width:"120px",height:"2000px"}:S,k=t.rootStyle,C=void 0===k?{}:k,M=e.useState("idle"),X=M[0],j=M[1],T=e.useState(null),z=T[0],A=T[1],I=e.useState({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),O=I[0],Y=I[1],Z=e.useRef(null),q=e.useRef([]),F=e.useRef(null),P=e.useRef(0),D=e.useRef(0),W=e.useRef(0),B=e.useRef("idle"),G=function(e){var t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};e.useEffect(function(){return function(){return cancelAnimationFrame(F.current)}},[]),e.useEffect(function(){J(0)},[l]),e.useEffect(function(){var e,t=function(){if("idle"===B.current){var n=30*(Math.random()-.5),r=30*(Math.random()-.5),a=10*(Math.random()-.5),o=30*(Math.random()-.5)-5;Y({transform:"translate3d(0px, "+o+"px, 0px) rotateX("+n+"deg) rotateY("+r+"deg) rotateZ("+a+"deg)"});var l=4e3+1e3*Math.random();e=setTimeout(t,l)}};return"idle"===X?t():(clearTimeout(e),Y({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[X]);var H=function(){P.current+=D.current,P.current>=90&&(P.current%=90,W.current=(W.current+1)%l.length,J(W.current)),Z.current&&(Z.current.style.transform="rotateX("+P.current+"deg)"),"stopping"===B.current&&(D.current*=m,D.current<.5&&(D.current=.5),D.current<=.5&&P.current<1)?K():F.current=requestAnimationFrame(H)},J=function(e){for(var t=0;t<4;t++){var n=G((e+t)%l.length),r=q.current[t];r&&(r.innerText=n.content,r.style.borderColor=n.color,r.style.boxShadow="0 0 15px "+n.color+"4d, inset 0 0 30px "+n.color+"1a",r.style.textShadow="0 0 20px "+n.color)}},K=function(){Z.current&&(Z.current.style.transform="rotateX(0deg)");var e=G(W.current);j("idle"),B.current="idle",A(e.content),c&&c(e.content)};/*#__PURE__*/return n.default.createElement("div",{style:r({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},C)},/*#__PURE__*/n.default.createElement("div",{className:"scene",style:{perspective:u}},E&&/*#__PURE__*/n.default.createElement("div",{className:"light-pillar",style:{width:R.width,height:R.height,background:"linear-gradient(to bottom, transparent 0%, "+N+" 50%, transparent 100%)"}}),/*#__PURE__*/n.default.createElement("div",{className:"cube-wrapper "+("idle"!==X?"locked":""),style:"idle"===X?O:{}},/*#__PURE__*/n.default.createElement("div",{ref:Z,className:"cube "+("idle"!==X?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(e){/*#__PURE__*/return n.default.createElement("div",{key:e,className:"face "+["front","bottom","back","top"][e],ref:function(t){return q.current[e]=t},style:y})}),/*#__PURE__*/n.default.createElement("div",{className:"face left",style:y}),/*#__PURE__*/n.default.createElement("div",{className:"face right",style:y}))),/*#__PURE__*/n.default.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/n.default.createElement("div",{style:{position:"absolute",bottom:"10%",width:"100%",textAlign:"center",zIndex:30}},v&&/*#__PURE__*/n.default.createElement("div",{className:"winner-text",style:b},z?"Result: "+z:"..."),/*#__PURE__*/n.default.createElement("div",{className:"controls"},/*#__PURE__*/n.default.createElement("button",{className:"cyber-button",onClick:function(){"idle"===B.current&&(A(null),j("spinning"),B.current="spinning",D.current=d,W.current=0,P.current=0,J(0),H())},disabled:"idle"!==X},"Spin"),/*#__PURE__*/n.default.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===B.current&&(j("stopping"),B.current="stopping")},disabled:"spinning"!==X},"Stop"))))};
1
+ var e=require("react");function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var r=/*#__PURE__*/t(e);function n(){return n=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},n.apply(null,arguments)}var a=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}];module.exports=function(t){var o=t.items,l=void 0===o?a:o,c=t.onWinner,i=t.perspective,u=void 0===i?"1000px":i,s=t.initialSpeed,d=void 0===s?30:s,f=t.friction,m=void 0===f?.98:f,p=t.showResult,v=void 0===p||p,g=t.resultStyle,h=void 0===g?{}:g,b=t.cubeStyle,y=void 0===b?{}:b,x=t.showPillar,E=void 0===x||x,N=t.pillarColor,w=void 0===N?"rgba(0, 247, 255, 0.1)":N,S=t.pillarSize,R=void 0===S?{width:"120px",height:"2000px"}:S,k=t.rootStyle,C=void 0===k?{}:k,M=e.useState("idle"),X=M[0],j=M[1],T=e.useState(null),O=T[0],Y=T[1],Z=e.useState({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),q=Z[0],z=Z[1],A=e.useRef(null),F=e.useRef([]),I=e.useRef(null),P=e.useRef(0),D=e.useRef(0),W=e.useRef(0),B=e.useRef("idle"),G=function(e){var t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};e.useEffect(function(){return function(){return cancelAnimationFrame(I.current)}},[]),e.useEffect(function(){J(0)},[l]),e.useEffect(function(){var e,t=function(){if("idle"===B.current){var r=30*(Math.random()-.5),n=30*(Math.random()-.5),a=10*(Math.random()-.5),o=30*(Math.random()-.5)-5;z({transform:"translate3d(0px, "+o+"px, 0px) rotateX("+r+"deg) rotateY("+n+"deg) rotateZ("+a+"deg)"});var l=4e3+1e3*Math.random();e=setTimeout(t,l)}};return"idle"===X?t():(clearTimeout(e),z({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[X]);var H=function(){P.current+=D.current,P.current>=90&&(P.current%=90,W.current=(W.current+1)%l.length,J(W.current)),A.current&&(A.current.style.transform="rotateX("+P.current+"deg)"),"stopping"===B.current&&(D.current*=m,D.current<.5&&(D.current=.5),D.current<=.5&&P.current<1)?K():I.current=requestAnimationFrame(H)},J=function(e){for(var t=0;t<4;t++){var r=G((e+t)%l.length),n=F.current[t];n&&(n.innerText=r.content,n.style.borderColor=r.color,n.style.boxShadow="0 0 15px "+r.color+"4d, inset 0 0 30px "+r.color+"1a",n.style.textShadow="0 0 20px "+r.color)}},K=function(){A.current&&(A.current.style.transform="rotateX(0deg)");var e=G(W.current);j("idle"),B.current="idle",Y(e.content),c&&c(e.content)};/*#__PURE__*/return r.default.createElement("div",{style:n({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},C)},/*#__PURE__*/r.default.createElement("div",{className:"scene",style:{perspective:u}},E&&/*#__PURE__*/r.default.createElement("div",{className:"light-pillar",style:{width:R.width,height:R.height,background:"linear-gradient(to bottom, transparent 0%, "+w+" 50%, transparent 100%)"}}),/*#__PURE__*/r.default.createElement("div",{className:"cube-wrapper "+("idle"!==X?"locked":""),style:"idle"===X?q:{}},/*#__PURE__*/r.default.createElement("div",{ref:A,className:"cube "+("idle"!==X?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(e){/*#__PURE__*/return r.default.createElement("div",{key:e,className:"face "+["front","bottom","back","top"][e],ref:function(t){return F.current[e]=t},style:y})}),/*#__PURE__*/r.default.createElement("div",{className:"face left",style:y}),/*#__PURE__*/r.default.createElement("div",{className:"face right",style:y}))),/*#__PURE__*/r.default.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/r.default.createElement("div",{className:"controls-container"},v&&/*#__PURE__*/r.default.createElement("div",{className:"winner-text",style:h},O?"Result: "+O:"..."),/*#__PURE__*/r.default.createElement("div",{className:"controls"},/*#__PURE__*/r.default.createElement("button",{className:"cyber-button",onClick:function(){"idle"===B.current&&(Y(null),j("spinning"),B.current="spinning",D.current=d,W.current=0,P.current=0,J(0),H())},disabled:"idle"!==X},"Spin"),/*#__PURE__*/r.default.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===B.current&&(j("stopping"),B.current="stopping")},disabled:"spinning"!==X},"Stop"))))};
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- NEW PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Ensure it fills parent */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\" /* Vertically center content */,\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n <div\n style={{\n position: \"absolute\",\n bottom: \"10%\",\n width: \"100%\",\n textAlign: \"center\",\n zIndex: 30,\n }}\n >\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","bottom","textAlign","onClick","disabled"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- ENVIRONMENT PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n // --- Helper: Normalize Item Data ---\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n // --- Random Float Logic (Drift) ---\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n // Treadmill Logic: Keep rotation between 0-90 visually, but swap content\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n // Physics Engine\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n // Snap to stop\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n // Apply dynamic color from the item object\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Fills the parent container */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n {/* Floating Wrapper */}\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n {/* Spinning Cube */}\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {/* The 4 active faces */}\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n {/* The side caps */}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n {/* UI Controls (Result + Buttons) */}\n <div className=\"controls-container\">\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","onClick","disabled"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e,{useState as t,useRef as r,useEffect as n}from"react";function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},o.apply(null,arguments)}const l=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}],c=({items:c=l,onWinner:a,perspective:i="1000px",initialSpeed:s=30,friction:u=.98,showResult:d=!0,resultStyle:m={},cubeStyle:p={},showPillar:f=!0,pillarColor:g="rgba(0, 247, 255, 0.1)",pillarSize:h={width:"120px",height:"2000px"},rootStyle:b={}})=>{const[y,x]=t("idle"),[v,E]=t(null),[w,N]=t({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),$=r(null),S=r([]),k=r(null),C=r(0),M=r(0),X=r(0),T=r("idle"),j=e=>{const t=c[e%c.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};n(()=>()=>cancelAnimationFrame(k.current),[]),n(()=>{A(0)},[c]),n(()=>{let e;const t=()=>{if("idle"!==T.current)return;const r=30*(Math.random()-.5),n=30*(Math.random()-.5),o=10*(Math.random()-.5),l=30*(Math.random()-.5)-5;N({transform:`translate3d(0px, ${l}px, 0px) rotateX(${r}deg) rotateY(${n}deg) rotateZ(${o}deg)`});const c=4e3+1e3*Math.random();e=setTimeout(t,c)};return"idle"===y?t():(clearTimeout(e),N({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),()=>clearTimeout(e)},[y]);const z=()=>{C.current+=M.current,C.current>=90&&(C.current%=90,X.current=(X.current+1)%c.length,A(X.current)),$.current&&($.current.style.transform=`rotateX(${C.current}deg)`),"stopping"===T.current&&(M.current*=u,M.current<.5&&(M.current=.5),M.current<=.5&&C.current<1)?I():k.current=requestAnimationFrame(z)},A=e=>{for(let t=0;t<4;t++){const r=j((e+t)%c.length),n=S.current[t];n&&(n.innerText=r.content,n.style.borderColor=r.color,n.style.boxShadow=`0 0 15px ${r.color}4d, inset 0 0 30px ${r.color}1a`,n.style.textShadow=`0 0 20px ${r.color}`)}},I=()=>{$.current&&($.current.style.transform="rotateX(0deg)");const e=j(X.current);x("idle"),T.current="idle",E(e.content),a&&a(e.content)};/*#__PURE__*/return e.createElement("div",{style:o({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},b)},/*#__PURE__*/e.createElement("div",{className:"scene",style:{perspective:i}},f&&/*#__PURE__*/e.createElement("div",{className:"light-pillar",style:{width:h.width,height:h.height,background:`linear-gradient(to bottom, transparent 0%, ${g} 50%, transparent 100%)`}}),/*#__PURE__*/e.createElement("div",{className:"cube-wrapper "+("idle"!==y?"locked":""),style:"idle"===y?w:{}},/*#__PURE__*/e.createElement("div",{ref:$,className:"cube "+("idle"!==y?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(t=>/*#__PURE__*/e.createElement("div",{key:t,className:`face ${["front","bottom","back","top"][t]}`,ref:e=>S.current[t]=e,style:p})),/*#__PURE__*/e.createElement("div",{className:"face left",style:p}),/*#__PURE__*/e.createElement("div",{className:"face right",style:p}))),/*#__PURE__*/e.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/e.createElement("div",{style:{position:"absolute",bottom:"10%",width:"100%",textAlign:"center",zIndex:30}},d&&/*#__PURE__*/e.createElement("div",{className:"winner-text",style:m},v?`Result: ${v}`:"..."),/*#__PURE__*/e.createElement("div",{className:"controls"},/*#__PURE__*/e.createElement("button",{className:"cyber-button",onClick:()=>{"idle"===T.current&&(E(null),x("spinning"),T.current="spinning",M.current=s,X.current=0,C.current=0,A(0),z())},disabled:"idle"!==y},"Spin"),/*#__PURE__*/e.createElement("button",{className:"cyber-button stop-btn",onClick:()=>{"spinning"===T.current&&(x("stopping"),T.current="stopping")},disabled:"spinning"!==y},"Stop"))))};export{c as default};
1
+ import e,{useState as t,useRef as r,useEffect as n}from"react";function c(){return c=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},c.apply(null,arguments)}const o=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}],l=({items:l=o,onWinner:a,perspective:i="1000px",initialSpeed:s=30,friction:u=.98,showResult:d=!0,resultStyle:m={},cubeStyle:p={},showPillar:f=!0,pillarColor:g="rgba(0, 247, 255, 0.1)",pillarSize:h={width:"120px",height:"2000px"},rootStyle:b={}})=>{const[y,v]=t("idle"),[x,E]=t(null),[N,w]=t({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),$=r(null),S=r([]),k=r(null),C=r(0),M=r(0),X=r(0),T=r("idle"),j=e=>{const t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};n(()=>()=>cancelAnimationFrame(k.current),[]),n(()=>{Y(0)},[l]),n(()=>{let e;const t=()=>{if("idle"!==T.current)return;const r=30*(Math.random()-.5),n=30*(Math.random()-.5),c=10*(Math.random()-.5),o=30*(Math.random()-.5)-5;w({transform:`translate3d(0px, ${o}px, 0px) rotateX(${r}deg) rotateY(${n}deg) rotateZ(${c}deg)`});const l=4e3+1e3*Math.random();e=setTimeout(t,l)};return"idle"===y?t():(clearTimeout(e),w({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),()=>clearTimeout(e)},[y]);const O=()=>{C.current+=M.current,C.current>=90&&(C.current%=90,X.current=(X.current+1)%l.length,Y(X.current)),$.current&&($.current.style.transform=`rotateX(${C.current}deg)`),"stopping"===T.current&&(M.current*=u,M.current<.5&&(M.current=.5),M.current<=.5&&C.current<1)?Z():k.current=requestAnimationFrame(O)},Y=e=>{for(let t=0;t<4;t++){const r=j((e+t)%l.length),n=S.current[t];n&&(n.innerText=r.content,n.style.borderColor=r.color,n.style.boxShadow=`0 0 15px ${r.color}4d, inset 0 0 30px ${r.color}1a`,n.style.textShadow=`0 0 20px ${r.color}`)}},Z=()=>{$.current&&($.current.style.transform="rotateX(0deg)");const e=j(X.current);v("idle"),T.current="idle",E(e.content),a&&a(e.content)};/*#__PURE__*/return e.createElement("div",{style:c({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},b)},/*#__PURE__*/e.createElement("div",{className:"scene",style:{perspective:i}},f&&/*#__PURE__*/e.createElement("div",{className:"light-pillar",style:{width:h.width,height:h.height,background:`linear-gradient(to bottom, transparent 0%, ${g} 50%, transparent 100%)`}}),/*#__PURE__*/e.createElement("div",{className:"cube-wrapper "+("idle"!==y?"locked":""),style:"idle"===y?N:{}},/*#__PURE__*/e.createElement("div",{ref:$,className:"cube "+("idle"!==y?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(t=>/*#__PURE__*/e.createElement("div",{key:t,className:`face ${["front","bottom","back","top"][t]}`,ref:e=>S.current[t]=e,style:p})),/*#__PURE__*/e.createElement("div",{className:"face left",style:p}),/*#__PURE__*/e.createElement("div",{className:"face right",style:p}))),/*#__PURE__*/e.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/e.createElement("div",{className:"controls-container"},d&&/*#__PURE__*/e.createElement("div",{className:"winner-text",style:m},x?`Result: ${x}`:"..."),/*#__PURE__*/e.createElement("div",{className:"controls"},/*#__PURE__*/e.createElement("button",{className:"cyber-button",onClick:()=>{"idle"===T.current&&(E(null),v("spinning"),T.current="spinning",M.current=s,X.current=0,C.current=0,Y(0),O())},disabled:"idle"!==y},"Spin"),/*#__PURE__*/e.createElement("button",{className:"cyber-button stop-btn",onClick:()=>{"spinning"===T.current&&(v("stopping"),T.current="stopping")},disabled:"spinning"!==y},"Stop"))))};export{l as default};
2
2
  //# sourceMappingURL=index.modern.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.modern.mjs","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- NEW PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Ensure it fills parent */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\" /* Vertically center content */,\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n <div\n style={{\n position: \"absolute\",\n bottom: \"10%\",\n width: \"100%\",\n textAlign: \"center\",\n zIndex: 30,\n }}\n >\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","InfiniteCube","items","onWinner","perspective","initialSpeed","friction","showResult","resultStyle","cubeStyle","showPillar","pillarColor","pillarSize","width","height","rootStyle","status","setStatus","useState","winner","setWinner","driftStyle","setDriftStyle","transform","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","bottom","textAlign","onClick","handleStart","disabled","handleStop"],"mappings":"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"}
1
+ {"version":3,"file":"index.modern.mjs","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- ENVIRONMENT PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n // --- Helper: Normalize Item Data ---\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n // --- Random Float Logic (Drift) ---\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n // Treadmill Logic: Keep rotation between 0-90 visually, but swap content\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n // Physics Engine\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n // Snap to stop\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n // Apply dynamic color from the item object\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Fills the parent container */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n {/* Floating Wrapper */}\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n {/* Spinning Cube */}\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {/* The 4 active faces */}\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n {/* The side caps */}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n {/* UI Controls (Result + Buttons) */}\n <div className=\"controls-container\">\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","InfiniteCube","items","onWinner","perspective","initialSpeed","friction","showResult","resultStyle","cubeStyle","showPillar","pillarColor","pillarSize","width","height","rootStyle","status","setStatus","useState","winner","setWinner","driftStyle","setDriftStyle","transform","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","onClick","handleStart","disabled","handleStop"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import e,{useState as t,useRef as n,useEffect as r}from"react";function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},o.apply(null,arguments)}var a=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}],c=function(c){var i=c.items,l=void 0===i?a:i,s=c.onWinner,u=c.perspective,d=void 0===u?"1000px":u,m=c.initialSpeed,f=void 0===m?30:m,p=c.friction,v=void 0===p?.98:p,g=c.showResult,h=void 0===g||g,b=c.resultStyle,y=void 0===b?{}:b,x=c.cubeStyle,E=void 0===x?{}:x,w=c.showPillar,N=void 0===w||w,S=c.pillarColor,k=void 0===S?"rgba(0, 247, 255, 0.1)":S,C=c.pillarSize,M=void 0===C?{width:"120px",height:"2000px"}:C,X=c.rootStyle,T=void 0===X?{}:X,j=t("idle"),z=j[0],A=j[1],I=t(null),O=I[0],Y=I[1],Z=t({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),F=Z[0],P=Z[1],R=n(null),q=n([]),D=n(null),W=n(0),B=n(0),G=n(0),H=n("idle"),J=function(e){var t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};r(function(){return function(){return cancelAnimationFrame(D.current)}},[]),r(function(){L(0)},[l]),r(function(){var e,t=function(){if("idle"===H.current){var n=30*(Math.random()-.5),r=30*(Math.random()-.5),o=10*(Math.random()-.5),a=30*(Math.random()-.5)-5;P({transform:"translate3d(0px, "+a+"px, 0px) rotateX("+n+"deg) rotateY("+r+"deg) rotateZ("+o+"deg)"});var c=4e3+1e3*Math.random();e=setTimeout(t,c)}};return"idle"===z?t():(clearTimeout(e),P({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[z]);var K=function(){W.current+=B.current,W.current>=90&&(W.current%=90,G.current=(G.current+1)%l.length,L(G.current)),R.current&&(R.current.style.transform="rotateX("+W.current+"deg)"),"stopping"===H.current&&(B.current*=v,B.current<.5&&(B.current=.5),B.current<=.5&&W.current<1)?Q():D.current=requestAnimationFrame(K)},L=function(e){for(var t=0;t<4;t++){var n=J((e+t)%l.length),r=q.current[t];r&&(r.innerText=n.content,r.style.borderColor=n.color,r.style.boxShadow="0 0 15px "+n.color+"4d, inset 0 0 30px "+n.color+"1a",r.style.textShadow="0 0 20px "+n.color)}},Q=function(){R.current&&(R.current.style.transform="rotateX(0deg)");var e=J(G.current);A("idle"),H.current="idle",Y(e.content),s&&s(e.content)};/*#__PURE__*/return e.createElement("div",{style:o({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},T)},/*#__PURE__*/e.createElement("div",{className:"scene",style:{perspective:d}},N&&/*#__PURE__*/e.createElement("div",{className:"light-pillar",style:{width:M.width,height:M.height,background:"linear-gradient(to bottom, transparent 0%, "+k+" 50%, transparent 100%)"}}),/*#__PURE__*/e.createElement("div",{className:"cube-wrapper "+("idle"!==z?"locked":""),style:"idle"===z?F:{}},/*#__PURE__*/e.createElement("div",{ref:R,className:"cube "+("idle"!==z?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(t){/*#__PURE__*/return e.createElement("div",{key:t,className:"face "+["front","bottom","back","top"][t],ref:function(e){return q.current[t]=e},style:E})}),/*#__PURE__*/e.createElement("div",{className:"face left",style:E}),/*#__PURE__*/e.createElement("div",{className:"face right",style:E}))),/*#__PURE__*/e.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/e.createElement("div",{style:{position:"absolute",bottom:"10%",width:"100%",textAlign:"center",zIndex:30}},h&&/*#__PURE__*/e.createElement("div",{className:"winner-text",style:y},O?"Result: "+O:"..."),/*#__PURE__*/e.createElement("div",{className:"controls"},/*#__PURE__*/e.createElement("button",{className:"cyber-button",onClick:function(){"idle"===H.current&&(Y(null),A("spinning"),H.current="spinning",B.current=f,G.current=0,W.current=0,L(0),K())},disabled:"idle"!==z},"Spin"),/*#__PURE__*/e.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===H.current&&(A("stopping"),H.current="stopping")},disabled:"spinning"!==z},"Stop"))))};export{c as default};
1
+ import e,{useState as t,useRef as r,useEffect as n}from"react";function o(){return o=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)({}).hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e},o.apply(null,arguments)}var a=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}],c=function(c){var i=c.items,l=void 0===i?a:i,s=c.onWinner,u=c.perspective,d=void 0===u?"1000px":u,m=c.initialSpeed,f=void 0===m?30:m,p=c.friction,v=void 0===p?.98:p,g=c.showResult,h=void 0===g||g,b=c.resultStyle,y=void 0===b?{}:b,x=c.cubeStyle,E=void 0===x?{}:x,N=c.showPillar,w=void 0===N||N,S=c.pillarColor,k=void 0===S?"rgba(0, 247, 255, 0.1)":S,C=c.pillarSize,M=void 0===C?{width:"120px",height:"2000px"}:C,X=c.rootStyle,T=void 0===X?{}:X,j=t("idle"),O=j[0],Y=j[1],Z=t(null),z=Z[0],A=Z[1],F=t({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),I=F[0],P=F[1],R=r(null),q=r([]),D=r(null),W=r(0),B=r(0),G=r(0),H=r("idle"),J=function(e){var t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};n(function(){return function(){return cancelAnimationFrame(D.current)}},[]),n(function(){L(0)},[l]),n(function(){var e,t=function(){if("idle"===H.current){var r=30*(Math.random()-.5),n=30*(Math.random()-.5),o=10*(Math.random()-.5),a=30*(Math.random()-.5)-5;P({transform:"translate3d(0px, "+a+"px, 0px) rotateX("+r+"deg) rotateY("+n+"deg) rotateZ("+o+"deg)"});var c=4e3+1e3*Math.random();e=setTimeout(t,c)}};return"idle"===O?t():(clearTimeout(e),P({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[O]);var K=function(){W.current+=B.current,W.current>=90&&(W.current%=90,G.current=(G.current+1)%l.length,L(G.current)),R.current&&(R.current.style.transform="rotateX("+W.current+"deg)"),"stopping"===H.current&&(B.current*=v,B.current<.5&&(B.current=.5),B.current<=.5&&W.current<1)?Q():D.current=requestAnimationFrame(K)},L=function(e){for(var t=0;t<4;t++){var r=J((e+t)%l.length),n=q.current[t];n&&(n.innerText=r.content,n.style.borderColor=r.color,n.style.boxShadow="0 0 15px "+r.color+"4d, inset 0 0 30px "+r.color+"1a",n.style.textShadow="0 0 20px "+r.color)}},Q=function(){R.current&&(R.current.style.transform="rotateX(0deg)");var e=J(G.current);Y("idle"),H.current="idle",A(e.content),s&&s(e.content)};/*#__PURE__*/return e.createElement("div",{style:o({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},T)},/*#__PURE__*/e.createElement("div",{className:"scene",style:{perspective:d}},w&&/*#__PURE__*/e.createElement("div",{className:"light-pillar",style:{width:M.width,height:M.height,background:"linear-gradient(to bottom, transparent 0%, "+k+" 50%, transparent 100%)"}}),/*#__PURE__*/e.createElement("div",{className:"cube-wrapper "+("idle"!==O?"locked":""),style:"idle"===O?I:{}},/*#__PURE__*/e.createElement("div",{ref:R,className:"cube "+("idle"!==O?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(t){/*#__PURE__*/return e.createElement("div",{key:t,className:"face "+["front","bottom","back","top"][t],ref:function(e){return q.current[t]=e},style:E})}),/*#__PURE__*/e.createElement("div",{className:"face left",style:E}),/*#__PURE__*/e.createElement("div",{className:"face right",style:E}))),/*#__PURE__*/e.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/e.createElement("div",{className:"controls-container"},h&&/*#__PURE__*/e.createElement("div",{className:"winner-text",style:y},z?"Result: "+z:"..."),/*#__PURE__*/e.createElement("div",{className:"controls"},/*#__PURE__*/e.createElement("button",{className:"cyber-button",onClick:function(){"idle"===H.current&&(A(null),Y("spinning"),H.current="spinning",B.current=f,G.current=0,W.current=0,L(0),K())},disabled:"idle"!==O},"Spin"),/*#__PURE__*/e.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===H.current&&(Y("stopping"),H.current="stopping")},disabled:"spinning"!==O},"Stop"))))};export{c as default};
2
2
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- NEW PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Ensure it fills parent */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\" /* Vertically center content */,\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n <div\n style={{\n position: \"absolute\",\n bottom: \"10%\",\n width: \"100%\",\n textAlign: \"center\",\n zIndex: 30,\n }}\n >\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","InfiniteCube","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","bottom","textAlign","onClick","disabled"],"mappings":"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"}
1
+ {"version":3,"file":"index.module.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- ENVIRONMENT PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n // --- Helper: Normalize Item Data ---\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n // --- Random Float Logic (Drift) ---\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n // Treadmill Logic: Keep rotation between 0-90 visually, but swap content\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n // Physics Engine\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n // Snap to stop\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n // Apply dynamic color from the item object\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Fills the parent container */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n {/* Floating Wrapper */}\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n {/* Spinning Cube */}\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {/* The 4 active faces */}\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n {/* The side caps */}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n {/* UI Controls (Result + Buttons) */}\n <div className=\"controls-container\">\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","InfiniteCube","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","onClick","disabled"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):(e||self).reactHolographicCube=t(e.react)}(this,function(e){function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/t(e);function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}var o=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}];return function(t){var a=t.items,l=void 0===a?o:a,c=t.onWinner,i=t.perspective,u=void 0===i?"1000px":i,s=t.initialSpeed,d=void 0===s?30:s,f=t.friction,m=void 0===f?.98:f,p=t.showResult,v=void 0===p||p,b=t.resultStyle,g=void 0===b?{}:b,h=t.cubeStyle,y=void 0===h?{}:h,x=t.showPillar,E=void 0===x||x,w=t.pillarColor,N=void 0===w?"rgba(0, 247, 255, 0.1)":w,S=t.pillarSize,R=void 0===S?{width:"120px",height:"2000px"}:S,k=t.rootStyle,C=void 0===k?{}:k,T=e.useState("idle"),j=T[0],M=T[1],X=e.useState(null),z=X[0],A=X[1],I=e.useState({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),O=I[0],Y=I[1],Z=e.useRef(null),q=e.useRef([]),F=e.useRef(null),P=e.useRef(0),D=e.useRef(0),H=e.useRef(0),W=e.useRef("idle"),B=function(e){var t=l[e%l.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};e.useEffect(function(){return function(){return cancelAnimationFrame(F.current)}},[]),e.useEffect(function(){J(0)},[l]),e.useEffect(function(){var e,t=function(){if("idle"===W.current){var n=30*(Math.random()-.5),r=30*(Math.random()-.5),o=10*(Math.random()-.5),a=30*(Math.random()-.5)-5;Y({transform:"translate3d(0px, "+a+"px, 0px) rotateX("+n+"deg) rotateY("+r+"deg) rotateZ("+o+"deg)"});var l=4e3+1e3*Math.random();e=setTimeout(t,l)}};return"idle"===j?t():(clearTimeout(e),Y({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[j]);var G=function(){P.current+=D.current,P.current>=90&&(P.current%=90,H.current=(H.current+1)%l.length,J(H.current)),Z.current&&(Z.current.style.transform="rotateX("+P.current+"deg)"),"stopping"===W.current&&(D.current*=m,D.current<.5&&(D.current=.5),D.current<=.5&&P.current<1)?K():F.current=requestAnimationFrame(G)},J=function(e){for(var t=0;t<4;t++){var n=B((e+t)%l.length),r=q.current[t];r&&(r.innerText=n.content,r.style.borderColor=n.color,r.style.boxShadow="0 0 15px "+n.color+"4d, inset 0 0 30px "+n.color+"1a",r.style.textShadow="0 0 20px "+n.color)}},K=function(){Z.current&&(Z.current.style.transform="rotateX(0deg)");var e=B(H.current);M("idle"),W.current="idle",A(e.content),c&&c(e.content)};/*#__PURE__*/return n.default.createElement("div",{style:r({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},C)},/*#__PURE__*/n.default.createElement("div",{className:"scene",style:{perspective:u}},E&&/*#__PURE__*/n.default.createElement("div",{className:"light-pillar",style:{width:R.width,height:R.height,background:"linear-gradient(to bottom, transparent 0%, "+N+" 50%, transparent 100%)"}}),/*#__PURE__*/n.default.createElement("div",{className:"cube-wrapper "+("idle"!==j?"locked":""),style:"idle"===j?O:{}},/*#__PURE__*/n.default.createElement("div",{ref:Z,className:"cube "+("idle"!==j?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(e){/*#__PURE__*/return n.default.createElement("div",{key:e,className:"face "+["front","bottom","back","top"][e],ref:function(t){return q.current[e]=t},style:y})}),/*#__PURE__*/n.default.createElement("div",{className:"face left",style:y}),/*#__PURE__*/n.default.createElement("div",{className:"face right",style:y}))),/*#__PURE__*/n.default.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/n.default.createElement("div",{style:{position:"absolute",bottom:"10%",width:"100%",textAlign:"center",zIndex:30}},v&&/*#__PURE__*/n.default.createElement("div",{className:"winner-text",style:g},z?"Result: "+z:"..."),/*#__PURE__*/n.default.createElement("div",{className:"controls"},/*#__PURE__*/n.default.createElement("button",{className:"cyber-button",onClick:function(){"idle"===W.current&&(A(null),M("spinning"),W.current="spinning",D.current=d,H.current=0,P.current=0,J(0),G())},disabled:"idle"!==j},"Spin"),/*#__PURE__*/n.default.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===W.current&&(M("stopping"),W.current="stopping")},disabled:"spinning"!==j},"Stop"))))}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("react")):"function"==typeof define&&define.amd?define(["react"],t):(e||self).reactHolographicCube=t(e.react)}(this,function(e){function t(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var n=/*#__PURE__*/t(e);function r(){return r=Object.assign?Object.assign.bind():function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)({}).hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e},r.apply(null,arguments)}var o=[{content:"1",color:"#00f7ff"},{content:"2",color:"#00db46"},{content:"3",color:"#ff00e6"},{content:"4",color:"#ffbd00"}];return function(t){var a=t.items,c=void 0===a?o:a,l=t.onWinner,i=t.perspective,u=void 0===i?"1000px":i,s=t.initialSpeed,d=void 0===s?30:s,f=t.friction,m=void 0===f?.98:f,p=t.showResult,v=void 0===p||p,g=t.resultStyle,h=void 0===g?{}:g,b=t.cubeStyle,y=void 0===b?{}:b,x=t.showPillar,E=void 0===x||x,N=t.pillarColor,w=void 0===N?"rgba(0, 247, 255, 0.1)":N,S=t.pillarSize,R=void 0===S?{width:"120px",height:"2000px"}:S,k=t.rootStyle,C=void 0===k?{}:k,T=e.useState("idle"),j=T[0],M=T[1],X=e.useState(null),O=X[0],Y=X[1],Z=e.useState({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"}),q=Z[0],z=Z[1],A=e.useRef(null),F=e.useRef([]),I=e.useRef(null),P=e.useRef(0),D=e.useRef(0),H=e.useRef(0),W=e.useRef("idle"),B=function(e){var t=c[e%c.length];return"string"==typeof t?{content:t,color:"#00db46"}:{content:t.content,color:t.color||"#00db46"}};e.useEffect(function(){return function(){return cancelAnimationFrame(I.current)}},[]),e.useEffect(function(){J(0)},[c]),e.useEffect(function(){var e,t=function(){if("idle"===W.current){var n=30*(Math.random()-.5),r=30*(Math.random()-.5),o=10*(Math.random()-.5),a=30*(Math.random()-.5)-5;z({transform:"translate3d(0px, "+a+"px, 0px) rotateX("+n+"deg) rotateY("+r+"deg) rotateZ("+o+"deg)"});var c=4e3+1e3*Math.random();e=setTimeout(t,c)}};return"idle"===j?t():(clearTimeout(e),z({transform:"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)"})),function(){return clearTimeout(e)}},[j]);var G=function(){P.current+=D.current,P.current>=90&&(P.current%=90,H.current=(H.current+1)%c.length,J(H.current)),A.current&&(A.current.style.transform="rotateX("+P.current+"deg)"),"stopping"===W.current&&(D.current*=m,D.current<.5&&(D.current=.5),D.current<=.5&&P.current<1)?K():I.current=requestAnimationFrame(G)},J=function(e){for(var t=0;t<4;t++){var n=B((e+t)%c.length),r=F.current[t];r&&(r.innerText=n.content,r.style.borderColor=n.color,r.style.boxShadow="0 0 15px "+n.color+"4d, inset 0 0 30px "+n.color+"1a",r.style.textShadow="0 0 20px "+n.color)}},K=function(){A.current&&(A.current.style.transform="rotateX(0deg)");var e=B(H.current);M("idle"),W.current="idle",Y(e.content),l&&l(e.content)};/*#__PURE__*/return n.default.createElement("div",{style:r({position:"relative",zIndex:10,width:"100%",height:"100%",display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"},C)},/*#__PURE__*/n.default.createElement("div",{className:"scene",style:{perspective:u}},E&&/*#__PURE__*/n.default.createElement("div",{className:"light-pillar",style:{width:R.width,height:R.height,background:"linear-gradient(to bottom, transparent 0%, "+w+" 50%, transparent 100%)"}}),/*#__PURE__*/n.default.createElement("div",{className:"cube-wrapper "+("idle"!==j?"locked":""),style:"idle"===j?q:{}},/*#__PURE__*/n.default.createElement("div",{ref:A,className:"cube "+("idle"!==j?"is-spinning":""),style:{transition:"none"}},[0,1,2,3].map(function(e){/*#__PURE__*/return n.default.createElement("div",{key:e,className:"face "+["front","bottom","back","top"][e],ref:function(t){return F.current[e]=t},style:y})}),/*#__PURE__*/n.default.createElement("div",{className:"face left",style:y}),/*#__PURE__*/n.default.createElement("div",{className:"face right",style:y}))),/*#__PURE__*/n.default.createElement("div",{className:"cube-shadow"})),/*#__PURE__*/n.default.createElement("div",{className:"controls-container"},v&&/*#__PURE__*/n.default.createElement("div",{className:"winner-text",style:h},O?"Result: "+O:"..."),/*#__PURE__*/n.default.createElement("div",{className:"controls"},/*#__PURE__*/n.default.createElement("button",{className:"cyber-button",onClick:function(){"idle"===W.current&&(Y(null),M("spinning"),W.current="spinning",D.current=d,H.current=0,P.current=0,J(0),G())},disabled:"idle"!==j},"Spin"),/*#__PURE__*/n.default.createElement("button",{className:"cyber-button stop-btn",onClick:function(){"spinning"===W.current&&(M("stopping"),W.current="stopping")},disabled:"spinning"!==j},"Stop"))))}});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- NEW PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Ensure it fills parent */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\" /* Vertically center content */,\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n <div\n style={{\n position: \"absolute\",\n bottom: \"10%\",\n width: \"100%\",\n textAlign: \"center\",\n zIndex: 30,\n }}\n >\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","bottom","textAlign","onClick","disabled"],"mappings":"ikBAGA,IAAMA,EAAa,CACjB,CAAEC,QAAS,IAAKC,MAAO,WACvB,CAAED,QAAS,IAAKC,MAAO,WACvB,CAAED,QAAS,IAAKC,MAAO,WACvB,CAAED,QAAS,IAAKC,MAAO,mBAGJ,SAAHC,OAeZC,EAAAD,EAdJE,MAAAA,OAAK,IAAAD,EAAGJ,EAAUI,EAClBE,EAAQH,EAARG,SAAQC,EAAAJ,EACRK,YAAAA,OAAc,IAAHD,EAAG,SAAQA,EAAAE,EAAAN,EACtBO,aAAAA,OAAe,IAAHD,EAAG,GAAEA,EAAAE,EAAAR,EACjBS,SAAAA,OAAQ,IAAAD,EAAG,IAAIA,EAAAE,EAAAV,EACfW,WAAAA,OAAU,IAAAD,GAAOA,EAAAE,EAAAZ,EACjBa,YAAAA,OAAW,IAAAD,EAAG,GAAEA,EAAAE,EAAAd,EAChBe,UAAAA,OAAY,IAAHD,EAAG,CAAA,EAAEA,EAAAE,EAAAhB,EAGdiB,WAAAA,WAAUD,GAAOA,EAAAE,EAAAlB,EACjBmB,YAAAA,WAAWD,EAAG,yBAAwBA,EAAAE,EAAApB,EACtCqB,WAAAA,OAAa,IAAHD,EAAG,CAAEE,MAAO,QAASC,OAAQ,UAAUH,EAAAI,EAAAxB,EACjDyB,UAAAA,OAAS,IAAAD,EAAG,GAAEA,EAEdE,EAA4BC,EAAQA,SAAC,QAA9BC,EAAMF,EAAA,GAAEG,EAASH,EACxB,GAAAI,EAA4BH,EAAQA,SAAC,MAA9BI,EAAMD,KAAEE,EAASF,EAExB,GAAAG,EAAoCN,WAAS,CAC3CO,UAAW,wDADNC,EAAUF,EAAEG,GAAAA,EAAaH,EAAA,GAI1BI,EAAUC,SAAO,MACjBC,EAAWD,EAAAA,OAAO,IAClBE,EAAeF,EAAAA,OAAO,MAEtBG,EAAcH,EAAMA,OAAC,GACrBI,EAAWJ,EAAMA,OAAC,GAClBK,EAAiBL,SAAO,GACxBM,EAAYN,SAAO,QAInBO,EAAc,SAACC,GACnB,IAAMC,EAAU7C,EAAM4C,EAAQ5C,EAAM8C,QACpC,MAAuB,iBAAZD,EACF,CAAEjD,QAASiD,EAAShD,MAAO,WAE7B,CACLD,QAASiD,EAAQjD,QACjBC,MAAOgD,EAAQhD,OAAS,UAE5B,EAEAkD,EAAAA,UAAU,WACR,OAAO,WAAA,OAAMC,qBAAqBV,EAAaW,QAAQ,CACzD,EAAG,IAEHF,YAAU,WACRG,EAAkB,EACpB,EAAG,CAAClD,IAEJ+C,EAASA,UAAC,WACR,IAAII,EACEC,EAAgB,WACpB,GAA0B,SAAtBV,EAAUO,QAAd,CAEA,IAAMI,EAA6B,IAAvBC,KAAKC,SAAW,IACtBC,EAA6B,IAAvBF,KAAKC,SAAW,IACtBE,EAA6B,IAAvBH,KAAKC,SAAW,IACtBG,EAA6B,IAAvBJ,KAAKC,SAAW,IAAY,EAExCrB,EAAc,CACZF,UAAS,oBAAsB0B,EAAsBL,oBAAAA,kBAAkBG,EAAE,gBAAgBC,EAC3F,SAEA,IAAME,EAAe,IAAuB,IAAhBL,KAAKC,SACjCJ,EAAYS,WAAWR,EAAeO,EAZJ,CAapC,EAUA,MARe,SAAXjC,EACF0B,KAEAS,aAAaV,GACbjB,EAAc,CACZF,UAAW,yDAGF,WAAA,OAAA6B,aAAaV,EAAU,CACtC,EAAG,CAACzB,IAEJ,IAmBMoC,EAAO,WACXvB,EAAYU,SAAWT,EAASS,QAE5BV,EAAYU,SAAW,KACzBV,EAAYU,SAAW,GACvBR,EAAeQ,SAAWR,EAAeQ,QAAU,GAAKjD,EAAM8C,OAC9DI,EAAkBT,EAAeQ,UAG/Bd,EAAQc,UACVd,EAAQc,QAAQc,MAAM/B,UAAS,WAAcO,EAAYU,gBAGjC,aAAtBP,EAAUO,UACZT,EAASS,SAAW1C,EAChBiC,EAASS,QApFO,KAqFlBT,EAASS,QArFS,IAuFhBT,EAASS,SAvFO,IAuFuBV,EAAYU,QAAU,GAC/De,IAIJ1B,EAAaW,QAAUgB,sBAAsBH,EAC/C,EAEMZ,EAAoB,SAACgB,GACzB,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,IACMC,EAAOzB,GADMuB,EAAaC,GAAKnE,EAAM8C,QAErCuB,EAAKhC,EAASY,QAAQkB,GAExBE,IACFA,EAAGC,UAAYF,EAAKxE,QACpByE,EAAGN,MAAMQ,YAAcH,EAAKvE,MAC5BwE,EAAGN,MAAMS,UAAS,YAAeJ,EAAKvE,MAA2BuE,sBAAAA,EAAKvE,MAAK,KAC3EwE,EAAGN,MAAMU,WAAyBL,YAAAA,EAAKvE,MAE3C,CACF,EAEMmE,EAAa,WACb7B,EAAQc,UAASd,EAAQc,QAAQc,MAAM/B,UAAS,iBACpD,IAAM0C,EAAc/B,EAAYF,EAAeQ,SAC/CtB,EAAU,QACVe,EAAUO,QAAU,OACpBnB,EAAU4C,EAAY9E,SAClBK,GAAUA,EAASyE,EAAY9E,QACrC,eAEA,OACE+E,UAAAC,cACEb,MAAAA,CAAAA,MAAKc,EAAA,CACHC,SAAU,WACVC,OAAQ,GACR3D,MAAO,OACPC,OAAQ,OACR2D,QAAS,OACTC,cAAe,SACfC,WAAY,SACZC,eAAgB,UACb5D,iBAGLoD,UAAAC,cAAKQ,MAAAA,CAAAA,UAAU,QAAQrB,MAAO,CAAE5D,YAAAA,IAE7BY,gBACC4D,UAAAC,cACEQ,MAAAA,CAAAA,UAAU,eACVrB,MAAO,CACL3C,MAAOD,EAAWC,MAClBC,OAAQF,EAAWE,OACnBgE,WAAU,8CAAgDpE,EAAW,0CAK3E0D,UAAAC,cACEQ,MAAAA,CAAAA,UAA2B1D,iBAAW,SAAXA,EAAoB,SAAW,IAC1DqC,MAAkB,SAAXrC,EAAoBO,EAAa,iBAExC0C,UAAAC,cACEU,MAAAA,CAAAA,IAAKnD,EACLiD,UAAmB1D,SAAW,SAAXA,EAAoB,cAAgB,IACvDqC,MAAO,CAAEwB,WAAY,SAEpB,CAAC,EAAG,EAAG,EAAG,GAAGC,IAAI,SAACrB,uBACjBQ,EAAAA,QAAAC,cAAA,MAAA,CACEa,IAAKtB,EACLiB,UAAS,QAAU,CAAC,QAAS,SAAU,OAAQ,OAAOjB,GACtDmB,IAAK,SAACjB,GAAE,OAAMhC,EAASY,QAAQkB,GAAKE,CAAE,EACtCN,MAAOlD,GACF,gBAET8D,UAAAC,qBAAKQ,UAAU,YAAYrB,MAAOlD,iBAClC8D,EAAA,QAAAC,cAAKQ,MAAAA,CAAAA,UAAU,aAAarB,MAAOlD,mBAIvC8D,EAAAA,QAAAC,qBAAKQ,UAAU,8BAGjBT,EAAAA,QAAAC,qBACEb,MAAO,CACLe,SAAU,WACVY,OAAQ,MACRtE,MAAO,OACPuE,UAAW,SACXZ,OAAQ,KAGTtE,gBACCkE,EAAAA,QAAAC,cAAKQ,MAAAA,CAAAA,UAAU,cAAcrB,MAAOpD,GACjCkB,aAAoBA,EAAW,oBAIpC8C,EAAAA,QAAAC,cAAKQ,MAAAA,CAAAA,UAAU,yBACbT,EAAAA,QAAAC,wBACEQ,UAAU,eACVQ,QA3IU,WACQ,SAAtBlD,EAAUO,UACdnB,EAAU,MACVH,EAAU,YACVe,EAAUO,QAAU,WACpBT,EAASS,QAAU5C,EACnBoC,EAAeQ,QAAU,EACzBV,EAAYU,QAAU,EACtBC,EAAkB,GAClBY,IACF,EAkIU+B,SAAqB,SAAXnE,GACX,qBAGDiD,EAAA,QAAAC,cAAA,SAAA,CACEQ,UAAU,wBACVQ,QAtIS,WACS,aAAtBlD,EAAUO,UACZtB,EAAU,YACVe,EAAUO,QAAU,WAExB,EAkIU4C,SAAqB,aAAXnE,GACX,UAOX"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/index.js"],"sourcesContent":["import React, { useState, useRef, useEffect } from \"react\";\nimport \"./styles.css\";\n\nconst DEMO_ITEMS = [\n { content: \"1\", color: \"#00f7ff\" },\n { content: \"2\", color: \"#00db46\" },\n { content: \"3\", color: \"#ff00e6\" },\n { content: \"4\", color: \"#ffbd00\" },\n];\n\nconst InfiniteCube = ({\n items = DEMO_ITEMS,\n onWinner,\n perspective = \"1000px\",\n initialSpeed = 30,\n friction = 0.98,\n showResult = true,\n resultStyle = {},\n cubeStyle = {},\n\n // --- ENVIRONMENT PROPS ---\n showPillar = true,\n pillarColor = \"rgba(0, 247, 255, 0.1)\", // Default cyan tint\n pillarSize = { width: \"120px\", height: \"2000px\" }, // Default massive beam\n rootStyle = {}, // Allows user to set background image here\n}) => {\n const [status, setStatus] = useState(\"idle\");\n const [winner, setWinner] = useState(null);\n\n const [driftStyle, setDriftStyle] = useState({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n\n const cubeRef = useRef(null);\n const faceRefs = useRef([]);\n const animationRef = useRef(null);\n\n const rotationRef = useRef(0);\n const speedRef = useRef(0);\n const listPointerRef = useRef(0);\n const statusRef = useRef(\"idle\");\n\n const MIN_CRAWL_SPEED = 0.5;\n\n // --- Helper: Normalize Item Data ---\n const getItemData = (index) => {\n const rawItem = items[index % items.length];\n if (typeof rawItem === \"string\") {\n return { content: rawItem, color: \"#00db46\" };\n }\n return {\n content: rawItem.content,\n color: rawItem.color || \"#00db46\",\n };\n };\n\n useEffect(() => {\n return () => cancelAnimationFrame(animationRef.current);\n }, []);\n\n useEffect(() => {\n updateFaceContent(0);\n }, [items]);\n\n // --- Random Float Logic (Drift) ---\n useEffect(() => {\n let timeoutId;\n const floatRandomly = () => {\n if (statusRef.current !== \"idle\") return;\n\n const rX = (Math.random() - 0.5) * 30;\n const rY = (Math.random() - 0.5) * 30;\n const rZ = (Math.random() - 0.5) * 10;\n const tY = (Math.random() - 0.5) * 30 - 5;\n\n setDriftStyle({\n transform: `translate3d(0px, ${tY}px, 0px) rotateX(${rX}deg) rotateY(${rY}deg) rotateZ(${rZ}deg)`,\n });\n\n const nextMoveTime = 4000 + Math.random() * 1000;\n timeoutId = setTimeout(floatRandomly, nextMoveTime);\n };\n\n if (status === \"idle\") {\n floatRandomly();\n } else {\n clearTimeout(timeoutId);\n setDriftStyle({\n transform: \"translate3d(0,0,0) rotateX(0) rotateY(0) rotateZ(0)\",\n });\n }\n return () => clearTimeout(timeoutId);\n }, [status]);\n\n const handleStart = () => {\n if (statusRef.current !== \"idle\") return;\n setWinner(null);\n setStatus(\"spinning\");\n statusRef.current = \"spinning\";\n speedRef.current = initialSpeed;\n listPointerRef.current = 0;\n rotationRef.current = 0;\n updateFaceContent(0);\n loop();\n };\n\n const handleStop = () => {\n if (statusRef.current === \"spinning\") {\n setStatus(\"stopping\");\n statusRef.current = \"stopping\";\n }\n };\n\n const loop = () => {\n rotationRef.current += speedRef.current;\n\n // Treadmill Logic: Keep rotation between 0-90 visually, but swap content\n if (rotationRef.current >= 90) {\n rotationRef.current %= 90;\n listPointerRef.current = (listPointerRef.current + 1) % items.length;\n updateFaceContent(listPointerRef.current);\n }\n\n if (cubeRef.current) {\n cubeRef.current.style.transform = `rotateX(${rotationRef.current}deg)`;\n }\n\n // Physics Engine\n if (statusRef.current === \"stopping\") {\n speedRef.current *= friction;\n if (speedRef.current < MIN_CRAWL_SPEED)\n speedRef.current = MIN_CRAWL_SPEED;\n\n // Snap to stop\n if (speedRef.current <= MIN_CRAWL_SPEED && rotationRef.current < 1.0) {\n finishGame();\n return;\n }\n }\n animationRef.current = requestAnimationFrame(loop);\n };\n\n const updateFaceContent = (startIndex) => {\n for (let i = 0; i < 4; i++) {\n const itemIndex = (startIndex + i) % items.length;\n const data = getItemData(itemIndex);\n const el = faceRefs.current[i];\n\n if (el) {\n el.innerText = data.content;\n // Apply dynamic color from the item object\n el.style.borderColor = data.color;\n el.style.boxShadow = `0 0 15px ${data.color}4d, inset 0 0 30px ${data.color}1a`;\n el.style.textShadow = `0 0 20px ${data.color}`;\n }\n }\n };\n\n const finishGame = () => {\n if (cubeRef.current) cubeRef.current.style.transform = `rotateX(0deg)`;\n const winningData = getItemData(listPointerRef.current);\n setStatus(\"idle\");\n statusRef.current = \"idle\";\n setWinner(winningData.content);\n if (onWinner) onWinner(winningData.content);\n };\n\n return (\n <div\n style={{\n position: \"relative\",\n zIndex: 10,\n width: \"100%\",\n height: \"100%\" /* Fills the parent container */,\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n ...rootStyle,\n }}\n >\n <div className=\"scene\" style={{ perspective }}>\n {/* Configurable Light Pillar */}\n {showPillar && (\n <div\n className=\"light-pillar\"\n style={{\n width: pillarSize.width,\n height: pillarSize.height,\n background: `linear-gradient(to bottom, transparent 0%, ${pillarColor} 50%, transparent 100%)`,\n }}\n ></div>\n )}\n\n {/* Floating Wrapper */}\n <div\n className={`cube-wrapper ${status !== \"idle\" ? \"locked\" : \"\"}`}\n style={status === \"idle\" ? driftStyle : {}}\n >\n {/* Spinning Cube */}\n <div\n ref={cubeRef}\n className={`cube ${status !== \"idle\" ? \"is-spinning\" : \"\"}`}\n style={{ transition: \"none\" }}\n >\n {/* The 4 active faces */}\n {[0, 1, 2, 3].map((i) => (\n <div\n key={i}\n className={`face ${[\"front\", \"bottom\", \"back\", \"top\"][i]}`}\n ref={(el) => (faceRefs.current[i] = el)}\n style={cubeStyle}\n ></div>\n ))}\n {/* The side caps */}\n <div className=\"face left\" style={cubeStyle}></div>\n <div className=\"face right\" style={cubeStyle}></div>\n </div>\n </div>\n\n <div className=\"cube-shadow\"></div>\n </div>\n\n {/* UI Controls (Result + Buttons) */}\n <div className=\"controls-container\">\n {showResult && (\n <div className=\"winner-text\" style={resultStyle}>\n {winner ? `Result: ${winner}` : \"...\"}\n </div>\n )}\n\n <div className=\"controls\">\n <button\n className=\"cyber-button\"\n onClick={handleStart}\n disabled={status !== \"idle\"}\n >\n Spin\n </button>\n <button\n className=\"cyber-button stop-btn\"\n onClick={handleStop}\n disabled={status !== \"spinning\"}\n >\n Stop\n </button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default InfiniteCube;\n"],"names":["DEMO_ITEMS","content","color","_ref","_ref$items","items","onWinner","_ref$perspective","perspective","_ref$initialSpeed","initialSpeed","_ref$friction","friction","_ref$showResult","showResult","_ref$resultStyle","resultStyle","_ref$cubeStyle","cubeStyle","_ref$showPillar","showPillar","_ref$pillarColor","pillarColor","_ref$pillarSize","pillarSize","width","height","_ref$rootStyle","rootStyle","_useState","useState","status","setStatus","_useState2","winner","setWinner","_useState3","transform","driftStyle","setDriftStyle","cubeRef","useRef","faceRefs","animationRef","rotationRef","speedRef","listPointerRef","statusRef","getItemData","index","rawItem","length","useEffect","cancelAnimationFrame","current","updateFaceContent","timeoutId","floatRandomly","rX","Math","random","rY","rZ","tY","nextMoveTime","setTimeout","clearTimeout","loop","style","finishGame","requestAnimationFrame","startIndex","i","data","el","innerText","borderColor","boxShadow","textShadow","winningData","React","createElement","_extends","position","zIndex","display","flexDirection","alignItems","justifyContent","className","background","ref","transition","map","key","onClick","disabled"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-holographic-cube",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "A 3D holographic spinning cube component for React",
5
5
  "source": "src/index.js",
6
6
  "main": "dist/index.js",