react-3d-carousel-fullcontrol 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/Carousel.jsx +41 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-3d-carousel-fullcontrol",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "A highly customizable 3D carousel component for React with full axis rotation control",
5
5
  "main": "src/Carousel.jsx",
6
6
  "keywords": [
package/src/Carousel.jsx CHANGED
@@ -174,13 +174,13 @@ const CarouselCard = memo(function CarouselCard({
174
174
  style={{
175
175
  width: "100%",
176
176
  height: "100%",
177
- borderRadius: "12px",
177
+ borderRadius: "0px",
178
178
  overflow: "hidden",
179
179
  position: "relative",
180
180
  cursor: "pointer",
181
181
  willChange: "transform",
182
182
  boxShadow: hovered
183
- ? `0 20px 40px rgba(0,0,0,0.8)`
183
+ ? `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)`
184
184
  : `0 10px 20px rgba(0,0,0,0.5)`,
185
185
  transition: "box-shadow 0.4s ease",
186
186
  }}
@@ -194,7 +194,7 @@ const CarouselCard = memo(function CarouselCard({
194
194
  height: "100%",
195
195
  objectFit: "cover",
196
196
  display: "block",
197
- borderRadius: "12px",
197
+ borderRadius: "0px",
198
198
  filter: hovered
199
199
  ? "brightness(1.2) saturate(1.3) contrast(1.1)"
200
200
  : `brightness(${0.65 + frontness * 0.3}) saturate(1.05)`,
@@ -261,7 +261,7 @@ const CarouselCard = memo(function CarouselCard({
261
261
  right: "5%",
262
262
  height: "80px",
263
263
  background: `url(${image.src}) center/cover no-repeat`,
264
- borderRadius: "12px",
264
+ borderRadius: "0px",
265
265
  transform: "scaleY(-1)",
266
266
  opacity: 0.12 + frontness * 0.08,
267
267
  maskImage: "linear-gradient(to bottom, rgba(0,0,0,0.6) 0%, transparent 100%)",
@@ -277,14 +277,15 @@ const CarouselCard = memo(function CarouselCard({
277
277
  // ─── Main reusable carousel component ────────────────────────────────────────
278
278
 
279
279
  /**
280
- * 3D Carousel with full axis rotation control and auto-rotation
280
+ * 3D Carousel with cylinder-style rotation and full axis control
281
+ * Cards arranged in a circle and the entire cylinder rotates
281
282
  *
282
283
  * @param {Object} props
283
284
  * @param {Array<{src: string, label?: string}>} props.images
284
285
  * @param {Object} [props.defaultRotation] - Default rotation { x: -20, y: 10, z: 20 }
285
286
  * @param {boolean} [props.controlled=false] - Return to default position on release
286
287
  * @param {function} [props.onRotationChange] - Callback with current rotation
287
- * @param {number} [props.autoRotateSpeed=0.3] - Auto rotation speed for Y axis (degrees per frame)
288
+ * @param {number} [props.autoRotateSpeed=0.3] - Auto rotation speed (degrees per frame)
288
289
  * @param {Object} [props.autoRotateAxes] - Which axes to auto-rotate { x: false, y: true, z: false }
289
290
  * @param {boolean} [props.pauseOnDrag=true] - Pause auto-rotation while dragging
290
291
  * @param {number} [props.cardWidth=220]
@@ -293,6 +294,7 @@ const CarouselCard = memo(function CarouselCard({
293
294
  * @param {number} [props.perspective=2000]
294
295
  * @param {number} [props.sensitivity=0.4] - Mouse drag sensitivity
295
296
  * @param {boolean} [props.showDragHint=true]
297
+ * @param {boolean} [props.glowEffect=true] - Enable glow effect on hover
296
298
  * @param {string} [props.className=""]
297
299
  * @param {Object} [props.style={}]
298
300
  */
@@ -310,6 +312,7 @@ function Carousel({
310
312
  perspective = 2000,
311
313
  sensitivity = 0.4,
312
314
  showDragHint = true,
315
+ glowEffect = true,
313
316
  className = "",
314
317
  style = {},
315
318
  }) {
@@ -395,9 +398,6 @@ function Carousel({
395
398
  rotationRef.current.z += (targetZ - rotationRef.current.z) * returnSpeed;
396
399
  }
397
400
  }
398
- } else if (pauseOnDrag) {
399
- // During drag: only apply auto-rotation if pauseOnDrag is false
400
- // (Currently paused, but momentum is handled in pointer move)
401
401
  }
402
402
 
403
403
  setRenderRotation({ ...rotationRef.current });
@@ -434,13 +434,13 @@ function Carousel({
434
434
  const dx = clientX - lastMousePos.current.x;
435
435
  const dy = clientY - lastMousePos.current.y;
436
436
 
437
- // Horizontal drag = Y axis rotation (spin around)
437
+ // Horizontal drag = Y axis rotation (spin the cylinder)
438
438
  rotationRef.current.y += dx * sensitivity;
439
439
 
440
- // Vertical drag = X axis rotation (tilt forward/backward)
440
+ // Vertical drag = X axis rotation (tilt the cylinder forward/backward)
441
441
  rotationRef.current.x -= dy * sensitivity * 0.6;
442
442
 
443
- // Diagonal drag = Z axis rotation (roll/twist)
443
+ // Diagonal drag = Z axis rotation (roll/twist the cylinder)
444
444
  if (Math.abs(dx) > 2 && Math.abs(dy) > 2) {
445
445
  const diagonalComponent = (dx * dy) / Math.sqrt(dx * dx + dy * dy);
446
446
  rotationRef.current.z += diagonalComponent * sensitivity * 0.3;
@@ -507,7 +507,7 @@ function Carousel({
507
507
  );
508
508
  }
509
509
 
510
- // Sort cards by depth for proper rendering
510
+ // Sort cards by depth for proper rendering order (back to front)
511
511
  const sortedImages = [...images].map((image, i) => {
512
512
  const angle = i * angleStep;
513
513
  const totalAngle = (renderRotation.y + angle) % 360;
@@ -537,30 +537,43 @@ function Carousel({
537
537
  onTouchMove={onTouchMove}
538
538
  onTouchEnd={onTouchEnd}
539
539
  >
540
- {/* Apply all 3 axis rotations */}
540
+ {/* Outer container - tilts the entire cylinder on X and Z axes */}
541
541
  <div
542
542
  style={{
543
543
  position: "absolute",
544
544
  top: "50%",
545
545
  left: "50%",
546
546
  transformStyle: "preserve-3d",
547
- transform: `translate(-50%, -50%) rotateX(${renderRotation.x}deg) rotateY(${renderRotation.y}deg) rotateZ(${renderRotation.z}deg)`,
547
+ transform: `translate(-50%, -50%) rotateX(${renderRotation.x}deg) rotateZ(${renderRotation.z}deg)`,
548
548
  willChange: "transform",
549
549
  }}
550
550
  >
551
- {sortedImages.map(({ image, index, zDepth }) => (
552
- <CarouselCard
553
- key={index}
554
- image={image}
555
- index={index}
556
- totalAngle={renderRotation.y}
557
- opacity={0.3 + (zDepth + 1) * 0.35}
558
- angleStep={angleStep}
559
- radius={radius}
560
- cardWidth={cardWidth}
561
- cardHeight={cardHeight}
562
- />
563
- ))}
551
+ {/* Inner container - rotates the cards around Y axis (cylinder spin) */}
552
+ <div
553
+ style={{
554
+ position: "absolute",
555
+ top: "50%",
556
+ left: "50%",
557
+ transformStyle: "preserve-3d",
558
+ transform: `translate(-50%, -50%) rotateY(${renderRotation.y}deg)`,
559
+ willChange: "transform",
560
+ }}
561
+ >
562
+ {/* Render cards in sorted order (back to front) */}
563
+ {sortedImages.map(({ image, index, zDepth }) => (
564
+ <CarouselCard
565
+ key={index}
566
+ image={image}
567
+ index={index}
568
+ totalAngle={renderRotation.y}
569
+ opacity={0.3 + (zDepth + 1) * 0.35}
570
+ angleStep={angleStep}
571
+ radius={radius}
572
+ cardWidth={cardWidth}
573
+ cardHeight={cardHeight}
574
+ />
575
+ ))}
576
+ </div>
564
577
  </div>
565
578
 
566
579
  {showDragHint && (