react-3d-carousel-fullcontrol 1.2.2 → 1.2.3

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.
Files changed (2) hide show
  1. package/dist/Carousel.js +73 -69
  2. package/package.json +1 -1
package/dist/Carousel.js CHANGED
@@ -235,14 +235,14 @@ var CarouselCard = /*#__PURE__*/(0, _react.memo)(function CarouselCard(_ref2) {
235
235
  objectFit: "cover",
236
236
  display: "block",
237
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)"),
238
+ filter: hovered ? "brightness(1.1) saturate(1.2) contrast(1.05)" : "brightness(0.95) saturate(1)",
239
239
  transition: "filter 0.4s ease"
240
240
  }
241
241
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
242
242
  style: {
243
243
  position: "absolute",
244
244
  inset: 0,
245
- background: "linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.55) 100%)",
245
+ background: "linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,0.2) 100%)",
246
246
  zIndex: 2
247
247
  }
248
248
  }), image.label && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
@@ -253,7 +253,7 @@ var CarouselCard = /*#__PURE__*/(0, _react.memo)(function CarouselCard(_ref2) {
253
253
  right: 0,
254
254
  padding: "20px 16px 16px",
255
255
  zIndex: 4,
256
- background: "linear-gradient(0deg, rgba(0,0,0,0.7) 0%, transparent 100%)"
256
+ background: "linear-gradient(0deg, rgba(0,0,0,0.5) 0%, transparent 100%)"
257
257
  },
258
258
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
259
259
  style: {
@@ -294,9 +294,9 @@ var CarouselCard = /*#__PURE__*/(0, _react.memo)(function CarouselCard(_ref2) {
294
294
  background: "url(".concat(image.src, ") center/cover no-repeat"),
295
295
  borderRadius: "12px",
296
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%)",
297
+ opacity: 0.08 + frontness * 0.04,
298
+ maskImage: "linear-gradient(to bottom, rgba(0,0,0,0.4) 0%, transparent 100%)",
299
+ WebkitMaskImage: "linear-gradient(to bottom, rgba(0,0,0,0.4) 0%, transparent 100%)",
300
300
  filter: "blur(3px)",
301
301
  pointerEvents: "none"
302
302
  }
@@ -307,7 +307,7 @@ var CarouselCard = /*#__PURE__*/(0, _react.memo)(function CarouselCard(_ref2) {
307
307
  // ─── Main reusable carousel component ────────────────────────────────────────
308
308
 
309
309
  function Carousel(_ref3) {
310
- var _defaultRotation$x, _defaultRotation$y, _defaultRotation$z;
310
+ var _defaultRotation$x, _defaultRotation$y, _defaultRotation$z, _defaultRotation$x2, _defaultRotation$y2, _defaultRotation$z2;
311
311
  var _ref3$images = _ref3.images,
312
312
  images = _ref3$images === void 0 ? [] : _ref3$images,
313
313
  _ref3$defaultRotation = _ref3.defaultRotation,
@@ -345,11 +345,10 @@ function Carousel(_ref3) {
345
345
  className = _ref3$className === void 0 ? "" : _ref3$className,
346
346
  _ref3$style = _ref3.style,
347
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
- });
348
+ // Use refs for rotation values to avoid re-renders
349
+ var rotationXRef = (0, _react.useRef)((_defaultRotation$x = defaultRotation.x) !== null && _defaultRotation$x !== void 0 ? _defaultRotation$x : -20);
350
+ var rotationYRef = (0, _react.useRef)((_defaultRotation$y = defaultRotation.y) !== null && _defaultRotation$y !== void 0 ? _defaultRotation$y : 10);
351
+ var rotationZRef = (0, _react.useRef)((_defaultRotation$z = defaultRotation.z) !== null && _defaultRotation$z !== void 0 ? _defaultRotation$z : 20);
353
352
  var rafRef = (0, _react.useRef)(null);
354
353
  var isDragging = (0, _react.useRef)(false);
355
354
  var lastMousePos = (0, _react.useRef)({
@@ -361,75 +360,93 @@ function Carousel(_ref3) {
361
360
  y: 0,
362
361
  z: 0
363
362
  });
364
- var _useState3 = (0, _react.useState)(_objectSpread({}, rotationRef.current)),
363
+ var _useState3 = (0, _react.useState)({
364
+ x: (_defaultRotation$x2 = defaultRotation.x) !== null && _defaultRotation$x2 !== void 0 ? _defaultRotation$x2 : -20,
365
+ y: (_defaultRotation$y2 = defaultRotation.y) !== null && _defaultRotation$y2 !== void 0 ? _defaultRotation$y2 : 10,
366
+ z: (_defaultRotation$z2 = defaultRotation.z) !== null && _defaultRotation$z2 !== void 0 ? _defaultRotation$z2 : 20
367
+ }),
365
368
  _useState4 = _slicedToArray(_useState3, 2),
366
369
  renderRotation = _useState4[0],
367
370
  setRenderRotation = _useState4[1];
368
- var returnAnimRef = (0, _react.useRef)(null);
371
+ var lastRenderTime = (0, _react.useRef)(0);
372
+ var FRAME_INTERVAL = 1000 / 60; // Target 60fps
373
+
369
374
  var cardCount = images.length;
370
375
  var angleStep = cardCount > 0 ? 360 / cardCount : 0;
371
376
  var radius = cardCount > 0 ? (cardWidth + gap) * cardCount / (2 * Math.PI) : 0;
372
377
  (0, _react.useEffect)(function () {
373
378
  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));
379
+ var _defaultRotation$x3, _defaultRotation$y3, _defaultRotation$z3;
380
+ rotationXRef.current = (_defaultRotation$x3 = defaultRotation.x) !== null && _defaultRotation$x3 !== void 0 ? _defaultRotation$x3 : -20;
381
+ rotationYRef.current = (_defaultRotation$y3 = defaultRotation.y) !== null && _defaultRotation$y3 !== void 0 ? _defaultRotation$y3 : 10;
382
+ rotationZRef.current = (_defaultRotation$z3 = defaultRotation.z) !== null && _defaultRotation$z3 !== void 0 ? _defaultRotation$z3 : 20;
383
+ setRenderRotation({
384
+ x: rotationXRef.current,
385
+ y: rotationYRef.current,
386
+ z: rotationZRef.current
387
+ });
381
388
  }
382
389
  }, [defaultRotation.x, defaultRotation.y, defaultRotation.z]);
383
390
  (0, _react.useEffect)(function () {
384
391
  if (cardCount === 0) return;
385
- var lastTime = performance.now();
386
392
  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;
393
+ // Limit updates to target frame rate for smooth animation
394
+ if (now - lastRenderTime.current < FRAME_INTERVAL) {
395
+ rafRef.current = requestAnimationFrame(_tick);
396
+ return;
397
+ }
398
+ var delta = Math.min(now - lastRenderTime.current, 32);
399
+ lastRenderTime.current = now;
400
+ if (!isDragging.current) {
401
+ // Apply friction
402
+ velocityRef.current.x *= 0.95;
403
+ velocityRef.current.y *= 0.95;
404
+ velocityRef.current.z *= 0.95;
394
405
  if (Math.abs(velocityRef.current.x) < 0.001) velocityRef.current.x = 0;
395
406
  if (Math.abs(velocityRef.current.y) < 0.001) velocityRef.current.y = 0;
396
407
  if (Math.abs(velocityRef.current.z) < 0.001) velocityRef.current.z = 0;
397
408
  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;
409
+ // Smooth auto-rotation
410
+ if (autoRotateAxes.x) rotationXRef.current += autoRotateSpeed * (delta / 16.67);
411
+ if (autoRotateAxes.y) rotationYRef.current += autoRotateSpeed * (delta / 16.67);
412
+ if (autoRotateAxes.z) rotationZRef.current += autoRotateSpeed * (delta / 16.67);
413
+ rotationXRef.current += velocityRef.current.x;
414
+ rotationYRef.current += velocityRef.current.y;
415
+ rotationZRef.current += velocityRef.current.z;
405
416
  } else {
406
- rotationRef.current.x += velocityRef.current.x;
407
- rotationRef.current.y += velocityRef.current.y;
408
- rotationRef.current.z += velocityRef.current.z;
417
+ rotationXRef.current += velocityRef.current.x;
418
+ rotationYRef.current += velocityRef.current.y;
419
+ rotationZRef.current += velocityRef.current.z;
409
420
  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;
421
+ var _defaultRotation$x4, _defaultRotation$y4, _defaultRotation$z4;
411
422
  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;
423
+ rotationXRef.current += (((_defaultRotation$x4 = defaultRotation.x) !== null && _defaultRotation$x4 !== void 0 ? _defaultRotation$x4 : -20) - rotationXRef.current) * returnSpeed;
424
+ rotationYRef.current += (((_defaultRotation$y4 = defaultRotation.y) !== null && _defaultRotation$y4 !== void 0 ? _defaultRotation$y4 : 10) - rotationYRef.current) * returnSpeed;
425
+ rotationZRef.current += (((_defaultRotation$z4 = defaultRotation.z) !== null && _defaultRotation$z4 !== void 0 ? _defaultRotation$z4 : 20) - rotationZRef.current) * returnSpeed;
418
426
  }
419
427
  }
420
428
  }
421
- setRenderRotation(_objectSpread({}, rotationRef.current));
429
+
430
+ // Only update state if values changed significantly
431
+ setRenderRotation({
432
+ x: rotationXRef.current,
433
+ y: rotationYRef.current,
434
+ z: rotationZRef.current
435
+ });
422
436
  if (onRotationChange) {
423
- onRotationChange(_objectSpread({}, rotationRef.current));
437
+ onRotationChange({
438
+ x: rotationXRef.current,
439
+ y: rotationYRef.current,
440
+ z: rotationZRef.current
441
+ });
424
442
  }
425
443
  rafRef.current = requestAnimationFrame(_tick);
426
444
  };
427
445
  rafRef.current = requestAnimationFrame(_tick);
428
446
  return function () {
429
447
  if (rafRef.current) cancelAnimationFrame(rafRef.current);
430
- if (returnAnimRef.current) cancelAnimationFrame(returnAnimRef.current);
431
448
  };
432
- }, [controlled, defaultRotation, autoRotateSpeed, autoRotateAxes, pauseOnDrag, onRotationChange, cardCount]);
449
+ }, [controlled, defaultRotation, autoRotateSpeed, autoRotateAxes, onRotationChange, cardCount]);
433
450
  var handlePointerDown = (0, _react.useCallback)(function (clientX, clientY) {
434
451
  isDragging.current = true;
435
452
  lastMousePos.current = {
@@ -441,34 +458,22 @@ function Carousel(_ref3) {
441
458
  y: 0,
442
459
  z: 0
443
460
  };
444
- if (returnAnimRef.current) {
445
- cancelAnimationFrame(returnAnimRef.current);
446
- returnAnimRef.current = null;
447
- }
448
461
  }, []);
449
462
  var handlePointerMove = (0, _react.useCallback)(function (clientX, clientY) {
450
463
  if (!isDragging.current) return;
451
464
  var dx = clientX - lastMousePos.current.x;
452
465
  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)
466
+ rotationYRef.current += dx * sensitivity;
467
+ rotationXRef.current -= dy * sensitivity * 0.6;
461
468
  if (Math.abs(dx) > 2 && Math.abs(dy) > 2) {
462
469
  var diagonalComponent = dx * dy / Math.sqrt(dx * dx + dy * dy);
463
- rotationRef.current.z += diagonalComponent * sensitivity * 0.3;
470
+ rotationZRef.current += diagonalComponent * sensitivity * 0.3;
464
471
  }
465
472
  velocityRef.current.y = dx * sensitivity * 0.5;
466
473
  velocityRef.current.x = -dy * sensitivity * 0.3;
467
474
  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));
475
+ rotationXRef.current = Math.max(-75, Math.min(75, rotationXRef.current));
476
+ rotationZRef.current = Math.max(-45, Math.min(45, rotationZRef.current));
472
477
  lastMousePos.current = {
473
478
  x: clientX,
474
479
  y: clientY
@@ -517,8 +522,6 @@ function Carousel(_ref3) {
517
522
  })
518
523
  });
519
524
  }
520
-
521
- // Sort cards by depth for proper rendering order (back to front)
522
525
  var sortedImages = _toConsumableArray(images).map(function (image, i) {
523
526
  var angle = i * angleStep;
524
527
  var totalAngle = (renderRotation.y + angle) % 360;
@@ -576,6 +579,7 @@ function Carousel(_ref3) {
576
579
  image: image,
577
580
  index: index,
578
581
  totalAngle: renderRotation.y,
582
+ opacity: 1,
579
583
  angleStep: angleStep,
580
584
  radius: radius,
581
585
  cardWidth: cardWidth,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-3d-carousel-fullcontrol",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A highly customizable 3D carousel component for React with full axis rotation control",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",