react-3d-carousel-fullcontrol 1.2.0 → 1.2.2

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.
@@ -0,0 +1,696 @@
1
+ "use strict";
2
+
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.Carousel = Carousel;
8
+ exports.CarouselWithBackground = CarouselWithBackground;
9
+ exports["default"] = void 0;
10
+ var _react = require("react");
11
+ var _framerMotion = require("framer-motion");
12
+ var _jsxRuntime = require("react/jsx-runtime");
13
+ var _excluded = ["images", "defaultRotation", "controlled", "onRotationChange"];
14
+ function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
15
+ function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
16
+ function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
17
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
18
+ function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
19
+ function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
20
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
21
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
22
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
23
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
24
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
25
+ function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
26
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
27
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
28
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
29
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
30
+ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } // ─── Particle system ────────────────────────────────────────────────────────
31
+ function Particles() {
32
+ var count = 80;
33
+ var particles = (0, _react.useRef)(Array.from({
34
+ length: count
35
+ }, function (_, i) {
36
+ return {
37
+ id: i,
38
+ x: Math.random() * 100,
39
+ y: Math.random() * 100,
40
+ size: Math.random() * 2.5 + 0.5,
41
+ opacity: Math.random() * 0.5 + 0.1,
42
+ dur: Math.random() * 12 + 8,
43
+ delay: Math.random() * -20
44
+ };
45
+ })).current;
46
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
47
+ style: {
48
+ position: "absolute",
49
+ inset: 0,
50
+ overflow: "hidden",
51
+ pointerEvents: "none",
52
+ zIndex: 1
53
+ },
54
+ children: particles.map(function (p) {
55
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
56
+ style: {
57
+ position: "absolute",
58
+ left: "".concat(p.x, "%"),
59
+ top: "".concat(p.y, "%"),
60
+ width: p.size,
61
+ height: p.size,
62
+ borderRadius: "50%",
63
+ background: "rgba(180,160,255,".concat(p.opacity, ")")
64
+ },
65
+ animate: {
66
+ y: [0, -30, 0],
67
+ opacity: [p.opacity, p.opacity * 2, p.opacity]
68
+ },
69
+ transition: {
70
+ duration: p.dur,
71
+ repeat: Infinity,
72
+ ease: "easeInOut",
73
+ delay: p.delay
74
+ }
75
+ }, p.id);
76
+ })
77
+ });
78
+ }
79
+
80
+ // ─── Light blobs ────────────────────────────────────────────────────────────
81
+
82
+ function LightBlobs(_ref) {
83
+ var mouseX = _ref.mouseX,
84
+ mouseY = _ref.mouseY;
85
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
86
+ style: {
87
+ position: "absolute",
88
+ inset: 0,
89
+ pointerEvents: "none",
90
+ zIndex: 0,
91
+ overflow: "hidden"
92
+ },
93
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
94
+ style: {
95
+ position: "absolute",
96
+ width: 700,
97
+ height: 700,
98
+ borderRadius: "50%",
99
+ left: mouseX - 350,
100
+ top: mouseY - 350,
101
+ background: "radial-gradient(circle, rgba(100,80,200,0.12) 0%, transparent 70%)",
102
+ transition: "left 0.6s ease, top 0.6s ease",
103
+ pointerEvents: "none"
104
+ }
105
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
106
+ style: {
107
+ position: "absolute",
108
+ width: 600,
109
+ height: 600,
110
+ borderRadius: "50%",
111
+ top: "-10%",
112
+ left: "10%",
113
+ background: "radial-gradient(circle, rgba(80,40,180,0.18) 0%, transparent 70%)",
114
+ filter: "blur(60px)"
115
+ },
116
+ animate: {
117
+ scale: [1, 1.15, 1],
118
+ x: [0, 40, 0]
119
+ },
120
+ transition: {
121
+ duration: 18,
122
+ repeat: Infinity,
123
+ ease: "easeInOut"
124
+ }
125
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
126
+ style: {
127
+ position: "absolute",
128
+ width: 500,
129
+ height: 500,
130
+ borderRadius: "50%",
131
+ bottom: "-5%",
132
+ right: "5%",
133
+ background: "radial-gradient(circle, rgba(40,100,200,0.14) 0%, transparent 70%)",
134
+ filter: "blur(80px)"
135
+ },
136
+ animate: {
137
+ scale: [1, 1.2, 1],
138
+ y: [0, -50, 0]
139
+ },
140
+ transition: {
141
+ duration: 14,
142
+ repeat: Infinity,
143
+ ease: "easeInOut",
144
+ delay: 3
145
+ }
146
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
147
+ style: {
148
+ position: "absolute",
149
+ width: 400,
150
+ height: 400,
151
+ borderRadius: "50%",
152
+ top: "40%",
153
+ left: "40%",
154
+ background: "radial-gradient(circle, rgba(160,60,220,0.08) 0%, transparent 70%)",
155
+ filter: "blur(100px)"
156
+ },
157
+ animate: {
158
+ scale: [1, 1.3, 1]
159
+ },
160
+ transition: {
161
+ duration: 22,
162
+ repeat: Infinity,
163
+ ease: "easeInOut",
164
+ delay: 7
165
+ }
166
+ })]
167
+ });
168
+ }
169
+
170
+ // ─── Single carousel card ────────────────────────────────────────────────────
171
+
172
+ var CarouselCard = /*#__PURE__*/(0, _react.memo)(function CarouselCard(_ref2) {
173
+ var image = _ref2.image,
174
+ index = _ref2.index,
175
+ totalAngle = _ref2.totalAngle,
176
+ opacity = _ref2.opacity,
177
+ angleStep = _ref2.angleStep,
178
+ radius = _ref2.radius,
179
+ cardWidth = _ref2.cardWidth,
180
+ cardHeight = _ref2.cardHeight;
181
+ var angle = index * angleStep;
182
+ var _useState = (0, _react.useState)(false),
183
+ _useState2 = _slicedToArray(_useState, 2),
184
+ hovered = _useState2[0],
185
+ setHovered = _useState2[1];
186
+ var normalizedAngle = ((totalAngle + angle) % 360 + 360) % 360;
187
+ var frontness = Math.max(0, Math.cos(normalizedAngle * Math.PI / 180));
188
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
189
+ style: {
190
+ position: "absolute",
191
+ width: "".concat(cardWidth, "px"),
192
+ height: "".concat(cardHeight, "px"),
193
+ left: "-".concat(cardWidth / 2, "px"),
194
+ top: "-".concat(cardHeight / 2, "px"),
195
+ transform: "rotateY(".concat(angle, "deg) translateZ(").concat(radius, "px)"),
196
+ transformStyle: "preserve-3d",
197
+ backfaceVisibility: "visible",
198
+ WebkitBackfaceVisibility: "visible",
199
+ opacity: opacity || 1,
200
+ willChange: "transform, opacity"
201
+ },
202
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_framerMotion.motion.div, {
203
+ onHoverStart: function onHoverStart() {
204
+ return setHovered(true);
205
+ },
206
+ onHoverEnd: function onHoverEnd() {
207
+ return setHovered(false);
208
+ },
209
+ animate: {
210
+ y: hovered ? -12 : 0
211
+ },
212
+ transition: {
213
+ type: "spring",
214
+ stiffness: 300,
215
+ damping: 22
216
+ },
217
+ style: {
218
+ width: "100%",
219
+ height: "100%",
220
+ borderRadius: "12px",
221
+ overflow: "hidden",
222
+ position: "relative",
223
+ cursor: "pointer",
224
+ willChange: "transform",
225
+ boxShadow: hovered ? "0 0 30px rgba(160,120,255,0.8), 0 0 60px rgba(100,80,220,0.6), 0 0 100px rgba(60,40,180,0.4), 0 20px 40px rgba(0,0,0,0.8)" : "0 10px 20px rgba(0,0,0,0.5)",
226
+ transition: "box-shadow 0.4s ease"
227
+ },
228
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("img", {
229
+ src: image.src,
230
+ alt: image.label || "Card ".concat(index + 1),
231
+ loading: "lazy",
232
+ style: {
233
+ width: "100%",
234
+ height: "100%",
235
+ objectFit: "cover",
236
+ display: "block",
237
+ borderRadius: "12px",
238
+ filter: hovered ? "brightness(1.2) saturate(1.3) contrast(1.1)" : "brightness(".concat(0.65 + frontness * 0.3, ") saturate(1.05)"),
239
+ transition: "filter 0.4s ease"
240
+ }
241
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
242
+ style: {
243
+ position: "absolute",
244
+ inset: 0,
245
+ background: "linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.55) 100%)",
246
+ zIndex: 2
247
+ }
248
+ }), image.label && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
249
+ style: {
250
+ position: "absolute",
251
+ bottom: 0,
252
+ left: 0,
253
+ right: 0,
254
+ padding: "20px 16px 16px",
255
+ zIndex: 4,
256
+ background: "linear-gradient(0deg, rgba(0,0,0,0.7) 0%, transparent 100%)"
257
+ },
258
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
259
+ style: {
260
+ fontFamily: "'SF Pro Display', 'Helvetica Neue', sans-serif",
261
+ fontSize: "13px",
262
+ fontWeight: 600,
263
+ color: "rgba(255,255,255,0.9)",
264
+ letterSpacing: "0.08em",
265
+ textTransform: "uppercase"
266
+ },
267
+ children: image.label
268
+ })
269
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
270
+ animate: hovered ? {
271
+ opacity: [0, 0.15, 0],
272
+ x: ["-100%", "200%"]
273
+ } : {
274
+ opacity: 0
275
+ },
276
+ transition: {
277
+ duration: 0.7,
278
+ ease: "easeInOut"
279
+ },
280
+ style: {
281
+ position: "absolute",
282
+ inset: 0,
283
+ background: "linear-gradient(105deg, transparent 40%, rgba(255,255,255,0.4) 50%, transparent 60%)",
284
+ zIndex: 5
285
+ }
286
+ })]
287
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
288
+ style: {
289
+ position: "absolute",
290
+ top: "105%",
291
+ left: "5%",
292
+ right: "5%",
293
+ height: "80px",
294
+ background: "url(".concat(image.src, ") center/cover no-repeat"),
295
+ borderRadius: "12px",
296
+ transform: "scaleY(-1)",
297
+ opacity: 0.12 + frontness * 0.08,
298
+ maskImage: "linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, transparent 100%)",
299
+ WebkitMaskImage: "linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, transparent 100%)",
300
+ filter: "blur(3px)",
301
+ pointerEvents: "none"
302
+ }
303
+ })]
304
+ });
305
+ });
306
+
307
+ // ─── Main reusable carousel component ────────────────────────────────────────
308
+
309
+ function Carousel(_ref3) {
310
+ var _defaultRotation$x, _defaultRotation$y, _defaultRotation$z;
311
+ var _ref3$images = _ref3.images,
312
+ images = _ref3$images === void 0 ? [] : _ref3$images,
313
+ _ref3$defaultRotation = _ref3.defaultRotation,
314
+ defaultRotation = _ref3$defaultRotation === void 0 ? {
315
+ x: -20,
316
+ y: 10,
317
+ z: 20
318
+ } : _ref3$defaultRotation,
319
+ _ref3$controlled = _ref3.controlled,
320
+ controlled = _ref3$controlled === void 0 ? false : _ref3$controlled,
321
+ onRotationChange = _ref3.onRotationChange,
322
+ _ref3$autoRotateSpeed = _ref3.autoRotateSpeed,
323
+ autoRotateSpeed = _ref3$autoRotateSpeed === void 0 ? 0.3 : _ref3$autoRotateSpeed,
324
+ _ref3$autoRotateAxes = _ref3.autoRotateAxes,
325
+ autoRotateAxes = _ref3$autoRotateAxes === void 0 ? {
326
+ x: false,
327
+ y: true,
328
+ z: false
329
+ } : _ref3$autoRotateAxes,
330
+ _ref3$pauseOnDrag = _ref3.pauseOnDrag,
331
+ pauseOnDrag = _ref3$pauseOnDrag === void 0 ? true : _ref3$pauseOnDrag,
332
+ _ref3$cardWidth = _ref3.cardWidth,
333
+ cardWidth = _ref3$cardWidth === void 0 ? 220 : _ref3$cardWidth,
334
+ _ref3$cardHeight = _ref3.cardHeight,
335
+ cardHeight = _ref3$cardHeight === void 0 ? 300 : _ref3$cardHeight,
336
+ _ref3$gap = _ref3.gap,
337
+ gap = _ref3$gap === void 0 ? 2 : _ref3$gap,
338
+ _ref3$perspective = _ref3.perspective,
339
+ perspective = _ref3$perspective === void 0 ? 2000 : _ref3$perspective,
340
+ _ref3$sensitivity = _ref3.sensitivity,
341
+ sensitivity = _ref3$sensitivity === void 0 ? 0.4 : _ref3$sensitivity,
342
+ _ref3$showDragHint = _ref3.showDragHint,
343
+ showDragHint = _ref3$showDragHint === void 0 ? true : _ref3$showDragHint,
344
+ _ref3$className = _ref3.className,
345
+ className = _ref3$className === void 0 ? "" : _ref3$className,
346
+ _ref3$style = _ref3.style,
347
+ style = _ref3$style === void 0 ? {} : _ref3$style;
348
+ var rotationRef = (0, _react.useRef)({
349
+ x: (_defaultRotation$x = defaultRotation.x) !== null && _defaultRotation$x !== void 0 ? _defaultRotation$x : -20,
350
+ y: (_defaultRotation$y = defaultRotation.y) !== null && _defaultRotation$y !== void 0 ? _defaultRotation$y : 10,
351
+ z: (_defaultRotation$z = defaultRotation.z) !== null && _defaultRotation$z !== void 0 ? _defaultRotation$z : 20
352
+ });
353
+ var rafRef = (0, _react.useRef)(null);
354
+ var isDragging = (0, _react.useRef)(false);
355
+ var lastMousePos = (0, _react.useRef)({
356
+ x: 0,
357
+ y: 0
358
+ });
359
+ var velocityRef = (0, _react.useRef)({
360
+ x: 0,
361
+ y: 0,
362
+ z: 0
363
+ });
364
+ var _useState3 = (0, _react.useState)(_objectSpread({}, rotationRef.current)),
365
+ _useState4 = _slicedToArray(_useState3, 2),
366
+ renderRotation = _useState4[0],
367
+ setRenderRotation = _useState4[1];
368
+ var returnAnimRef = (0, _react.useRef)(null);
369
+ var cardCount = images.length;
370
+ var angleStep = cardCount > 0 ? 360 / cardCount : 0;
371
+ var radius = cardCount > 0 ? (cardWidth + gap) * cardCount / (2 * Math.PI) : 0;
372
+ (0, _react.useEffect)(function () {
373
+ if (!isDragging.current) {
374
+ var _defaultRotation$x2, _defaultRotation$y2, _defaultRotation$z2;
375
+ rotationRef.current = {
376
+ x: (_defaultRotation$x2 = defaultRotation.x) !== null && _defaultRotation$x2 !== void 0 ? _defaultRotation$x2 : -20,
377
+ y: (_defaultRotation$y2 = defaultRotation.y) !== null && _defaultRotation$y2 !== void 0 ? _defaultRotation$y2 : 10,
378
+ z: (_defaultRotation$z2 = defaultRotation.z) !== null && _defaultRotation$z2 !== void 0 ? _defaultRotation$z2 : 20
379
+ };
380
+ setRenderRotation(_objectSpread({}, rotationRef.current));
381
+ }
382
+ }, [defaultRotation.x, defaultRotation.y, defaultRotation.z]);
383
+ (0, _react.useEffect)(function () {
384
+ if (cardCount === 0) return;
385
+ var lastTime = performance.now();
386
+ var _tick = function tick(now) {
387
+ var delta = Math.min(now - lastTime, 32);
388
+ lastTime = now;
389
+ var isCurrentlyDragging = isDragging.current;
390
+ if (!isCurrentlyDragging) {
391
+ velocityRef.current.x *= 0.94;
392
+ velocityRef.current.y *= 0.94;
393
+ velocityRef.current.z *= 0.94;
394
+ if (Math.abs(velocityRef.current.x) < 0.001) velocityRef.current.x = 0;
395
+ if (Math.abs(velocityRef.current.y) < 0.001) velocityRef.current.y = 0;
396
+ if (Math.abs(velocityRef.current.z) < 0.001) velocityRef.current.z = 0;
397
+ if (!controlled) {
398
+ // Auto-rotate on specified axes
399
+ if (autoRotateAxes.x) rotationRef.current.x += autoRotateSpeed * (delta / 16.67);
400
+ if (autoRotateAxes.y) rotationRef.current.y += autoRotateSpeed * (delta / 16.67);
401
+ if (autoRotateAxes.z) rotationRef.current.z += autoRotateSpeed * (delta / 16.67);
402
+ rotationRef.current.x += velocityRef.current.x;
403
+ rotationRef.current.y += velocityRef.current.y;
404
+ rotationRef.current.z += velocityRef.current.z;
405
+ } else {
406
+ rotationRef.current.x += velocityRef.current.x;
407
+ rotationRef.current.y += velocityRef.current.y;
408
+ rotationRef.current.z += velocityRef.current.z;
409
+ if (Math.abs(velocityRef.current.x) < 0.01 && Math.abs(velocityRef.current.y) < 0.01 && Math.abs(velocityRef.current.z) < 0.01) {
410
+ var _defaultRotation$x3, _defaultRotation$y3, _defaultRotation$z3;
411
+ var returnSpeed = 0.08;
412
+ var targetX = (_defaultRotation$x3 = defaultRotation.x) !== null && _defaultRotation$x3 !== void 0 ? _defaultRotation$x3 : -20;
413
+ var targetY = (_defaultRotation$y3 = defaultRotation.y) !== null && _defaultRotation$y3 !== void 0 ? _defaultRotation$y3 : 10;
414
+ var targetZ = (_defaultRotation$z3 = defaultRotation.z) !== null && _defaultRotation$z3 !== void 0 ? _defaultRotation$z3 : 20;
415
+ rotationRef.current.x += (targetX - rotationRef.current.x) * returnSpeed;
416
+ rotationRef.current.y += (targetY - rotationRef.current.y) * returnSpeed;
417
+ rotationRef.current.z += (targetZ - rotationRef.current.z) * returnSpeed;
418
+ }
419
+ }
420
+ }
421
+ setRenderRotation(_objectSpread({}, rotationRef.current));
422
+ if (onRotationChange) {
423
+ onRotationChange(_objectSpread({}, rotationRef.current));
424
+ }
425
+ rafRef.current = requestAnimationFrame(_tick);
426
+ };
427
+ rafRef.current = requestAnimationFrame(_tick);
428
+ return function () {
429
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
430
+ if (returnAnimRef.current) cancelAnimationFrame(returnAnimRef.current);
431
+ };
432
+ }, [controlled, defaultRotation, autoRotateSpeed, autoRotateAxes, pauseOnDrag, onRotationChange, cardCount]);
433
+ var handlePointerDown = (0, _react.useCallback)(function (clientX, clientY) {
434
+ isDragging.current = true;
435
+ lastMousePos.current = {
436
+ x: clientX,
437
+ y: clientY
438
+ };
439
+ velocityRef.current = {
440
+ x: 0,
441
+ y: 0,
442
+ z: 0
443
+ };
444
+ if (returnAnimRef.current) {
445
+ cancelAnimationFrame(returnAnimRef.current);
446
+ returnAnimRef.current = null;
447
+ }
448
+ }, []);
449
+ var handlePointerMove = (0, _react.useCallback)(function (clientX, clientY) {
450
+ if (!isDragging.current) return;
451
+ var dx = clientX - lastMousePos.current.x;
452
+ var dy = clientY - lastMousePos.current.y;
453
+
454
+ // Horizontal drag = Y axis rotation (spin the cylinder)
455
+ rotationRef.current.y += dx * sensitivity;
456
+
457
+ // Vertical drag = X axis rotation (tilt the cylinder)
458
+ rotationRef.current.x -= dy * sensitivity * 0.6;
459
+
460
+ // Diagonal drag = Z axis rotation (roll)
461
+ if (Math.abs(dx) > 2 && Math.abs(dy) > 2) {
462
+ var diagonalComponent = dx * dy / Math.sqrt(dx * dx + dy * dy);
463
+ rotationRef.current.z += diagonalComponent * sensitivity * 0.3;
464
+ }
465
+ velocityRef.current.y = dx * sensitivity * 0.5;
466
+ velocityRef.current.x = -dy * sensitivity * 0.3;
467
+ velocityRef.current.z = dx * dy / Math.sqrt(dx * dx + dy * dy || 1) * sensitivity * 0.2;
468
+
469
+ // Clamp values
470
+ rotationRef.current.x = Math.max(-75, Math.min(75, rotationRef.current.x));
471
+ rotationRef.current.z = Math.max(-45, Math.min(45, rotationRef.current.z));
472
+ lastMousePos.current = {
473
+ x: clientX,
474
+ y: clientY
475
+ };
476
+ }, [sensitivity]);
477
+ var handlePointerUp = (0, _react.useCallback)(function () {
478
+ isDragging.current = false;
479
+ }, []);
480
+ var onMouseDown = (0, _react.useCallback)(function (e) {
481
+ e.preventDefault();
482
+ handlePointerDown(e.clientX, e.clientY);
483
+ }, [handlePointerDown]);
484
+ var onMouseMove = (0, _react.useCallback)(function (e) {
485
+ handlePointerMove(e.clientX, e.clientY);
486
+ }, [handlePointerMove]);
487
+ var onMouseUp = (0, _react.useCallback)(function () {
488
+ handlePointerUp();
489
+ }, [handlePointerUp]);
490
+ var onTouchStart = (0, _react.useCallback)(function (e) {
491
+ handlePointerDown(e.touches[0].clientX, e.touches[0].clientY);
492
+ }, [handlePointerDown]);
493
+ var onTouchMove = (0, _react.useCallback)(function (e) {
494
+ handlePointerMove(e.touches[0].clientX, e.touches[0].clientY);
495
+ }, [handlePointerMove]);
496
+ var onTouchEnd = (0, _react.useCallback)(function () {
497
+ handlePointerUp();
498
+ }, [handlePointerUp]);
499
+ if (cardCount === 0) {
500
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
501
+ className: className,
502
+ style: _objectSpread({
503
+ position: "relative",
504
+ width: "100%",
505
+ height: "100%"
506
+ }, style),
507
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
508
+ style: {
509
+ position: "absolute",
510
+ top: "50%",
511
+ left: "50%",
512
+ transform: "translate(-50%, -50%)",
513
+ color: "rgba(255,255,255,0.5)",
514
+ fontSize: "16px"
515
+ },
516
+ children: "No images to display"
517
+ })
518
+ });
519
+ }
520
+
521
+ // Sort cards by depth for proper rendering order (back to front)
522
+ var sortedImages = _toConsumableArray(images).map(function (image, i) {
523
+ var angle = i * angleStep;
524
+ var totalAngle = (renderRotation.y + angle) % 360;
525
+ var zDepth = Math.cos(totalAngle * Math.PI / 180);
526
+ return {
527
+ image: image,
528
+ index: i,
529
+ zDepth: zDepth
530
+ };
531
+ }).sort(function (a, b) {
532
+ return a.zDepth - b.zDepth;
533
+ });
534
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
535
+ className: className,
536
+ style: _objectSpread({
537
+ position: "relative",
538
+ width: "100%",
539
+ height: "100%",
540
+ perspective: "".concat(perspective, "px"),
541
+ perspectiveOrigin: "50% 50%",
542
+ cursor: isDragging.current ? "grabbing" : "grab",
543
+ userSelect: "none",
544
+ touchAction: "none"
545
+ }, style),
546
+ onMouseDown: onMouseDown,
547
+ onMouseMove: onMouseMove,
548
+ onMouseUp: onMouseUp,
549
+ onMouseLeave: onMouseUp,
550
+ onTouchStart: onTouchStart,
551
+ onTouchMove: onTouchMove,
552
+ onTouchEnd: onTouchEnd,
553
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
554
+ style: {
555
+ position: "absolute",
556
+ top: "50%",
557
+ left: "50%",
558
+ transformStyle: "preserve-3d",
559
+ transform: "translate(-50%, -50%) rotateX(".concat(renderRotation.x, "deg) rotateZ(").concat(renderRotation.z, "deg)"),
560
+ willChange: "transform"
561
+ },
562
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
563
+ style: {
564
+ position: "absolute",
565
+ top: "50%",
566
+ left: "50%",
567
+ transformStyle: "preserve-3d",
568
+ transform: "translate(-50%, -50%) rotateY(".concat(renderRotation.y, "deg)"),
569
+ willChange: "transform"
570
+ },
571
+ children: sortedImages.map(function (_ref4) {
572
+ var image = _ref4.image,
573
+ index = _ref4.index,
574
+ zDepth = _ref4.zDepth;
575
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(CarouselCard, {
576
+ image: image,
577
+ index: index,
578
+ totalAngle: renderRotation.y,
579
+ angleStep: angleStep,
580
+ radius: radius,
581
+ cardWidth: cardWidth,
582
+ cardHeight: cardHeight
583
+ }, index);
584
+ })
585
+ })
586
+ }), showDragHint && /*#__PURE__*/(0, _jsxRuntime.jsx)(_framerMotion.motion.div, {
587
+ initial: {
588
+ opacity: 0
589
+ },
590
+ animate: {
591
+ opacity: 1
592
+ },
593
+ transition: {
594
+ delay: 2.5,
595
+ duration: 1
596
+ },
597
+ style: {
598
+ position: "absolute",
599
+ bottom: "28px",
600
+ left: "50%",
601
+ transform: "translateX(-50%)",
602
+ zIndex: 10,
603
+ color: "rgba(255,255,255,0.25)",
604
+ fontSize: "11px",
605
+ letterSpacing: "0.2em",
606
+ textTransform: "uppercase",
607
+ textAlign: "center",
608
+ pointerEvents: "none"
609
+ },
610
+ children: "drag to rotate \u2022 auto-rotating"
611
+ })]
612
+ });
613
+ }
614
+
615
+ // ─── Full page component with backgrounds ────────────────────────────────────
616
+
617
+ function CarouselWithBackground(_ref5) {
618
+ var images = _ref5.images,
619
+ defaultRotation = _ref5.defaultRotation,
620
+ controlled = _ref5.controlled,
621
+ onRotationChange = _ref5.onRotationChange,
622
+ carouselProps = _objectWithoutProperties(_ref5, _excluded);
623
+ var containerRef = (0, _react.useRef)(null);
624
+ var _useState5 = (0, _react.useState)({
625
+ x: 0,
626
+ y: 0
627
+ }),
628
+ _useState6 = _slicedToArray(_useState5, 2),
629
+ mouse = _useState6[0],
630
+ setMouse = _useState6[1];
631
+ (0, _react.useEffect)(function () {
632
+ var onResize = function onResize() {
633
+ setMouse(function (prev) {
634
+ return _objectSpread({}, prev);
635
+ });
636
+ };
637
+ window.addEventListener("resize", onResize);
638
+ return function () {
639
+ return window.removeEventListener("resize", onResize);
640
+ };
641
+ }, []);
642
+ var onMouseMove = (0, _react.useCallback)(function (e) {
643
+ setMouse({
644
+ x: e.clientX,
645
+ y: e.clientY
646
+ });
647
+ }, []);
648
+ return /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
649
+ ref: containerRef,
650
+ onMouseMove: onMouseMove,
651
+ style: {
652
+ position: "relative",
653
+ width: "100vw",
654
+ height: "100vh",
655
+ background: "#000",
656
+ overflow: "hidden",
657
+ fontFamily: "'SF Pro Display', 'Helvetica Neue', sans-serif"
658
+ },
659
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(LightBlobs, {
660
+ mouseX: mouse.x,
661
+ mouseY: mouse.y
662
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(Particles, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
663
+ style: {
664
+ position: "absolute",
665
+ inset: 0,
666
+ background: "radial-gradient(ellipse 60% 40% at 50% 65%, rgba(80,50,160,0.18) 0%, transparent 70%)",
667
+ pointerEvents: "none",
668
+ zIndex: 1
669
+ }
670
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
671
+ style: {
672
+ position: "absolute",
673
+ bottom: 0,
674
+ left: 0,
675
+ right: 0,
676
+ height: "35%",
677
+ background: "linear-gradient(to top, rgba(20,10,40,0.5) 0%, transparent 100%)",
678
+ pointerEvents: "none",
679
+ zIndex: 2
680
+ }
681
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
682
+ style: {
683
+ position: "absolute",
684
+ inset: 0,
685
+ zIndex: 5
686
+ },
687
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Carousel, _objectSpread({
688
+ images: images,
689
+ defaultRotation: defaultRotation,
690
+ controlled: controlled,
691
+ onRotationChange: onRotationChange
692
+ }, carouselProps))
693
+ })]
694
+ });
695
+ }
696
+ var _default = exports["default"] = Carousel;