npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ddevkim/carousel-circular-3d

v1.0.0

Published

A luxury 3D circular carousel component for React with smooth animations, drag interactions, and premium visual effects

Downloads

1,337

Readme

@ddevkim/carousel-circular-3d

A luxury 3D circular carousel component for React with smooth animations, drag interactions, and premium visual effects.

npm version npm downloads license

✨ Features

  • 🎨 Luxury 3D Effects - Smooth perspective transforms, depth perception, and premium visual effects
  • 🖱️ Interactive - Drag, touch, and momentum physics for natural interactions
  • High Performance - GPU-accelerated animations, 60fps on desktop, 55fps+ on mobile
  • 🖼️ Built-in Lightbox - Full-screen image viewer with smooth transitions
  • 🎯 LQIP Support - Progressive image loading with blur placeholders
  • ⌨️ Keyboard Navigation - Enhanced keyboard support for carousel and lightbox (Arrow keys, ESC) with configurable options
  • 📱 Fully Responsive - Touch-optimized for mobile devices
  • 🔧 Highly Customizable - Extensive API for fine-tuning every aspect
  • 💪 TypeScript - Full type safety and IntelliSense support
  • 🌟 Zero Dependencies - Only React as peer dependency

🎯 Why Choose This?

Unlike traditional flat carousels, this component provides:

  • ✨ Premium Feel: 3D transforms and smooth physics-based interactions
  • 🚀 Production Ready: Used in real projects, battle-tested
  • 📦 Zero Config: Works out of the box with sensible defaults
  • 🎨 Fully Customizable: 30+ props to fine-tune every aspect
  • 📱 Mobile First: Touch-optimized with momentum scrolling
  • ♿ Accessible: ARIA labels, keyboard navigation, screen reader friendly
  • ⚡ Performant: GPU-accelerated, 60fps on desktop

📚 Table of Contents

🚀 Demo

Live Demo - See it in action!

Interactive 3D carousel with smooth animations and lightbox

📦 Installation

# npm
npm install @ddevkim/carousel-circular-3d

# yarn
yarn add @ddevkim/carousel-circular-3d

# pnpm
pnpm add @ddevkim/carousel-circular-3d

🎯 Quick Start

1️⃣ Import Component + CSS

Important: You must import the CSS file for styles to work properly!

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css"; // Required for styles

2️⃣ Minimal Example (30 seconds)

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

const items = [
  { id: 1, image: "/image1.jpg", alt: "Image 1" },
  { id: 2, image: "/image2.jpg", alt: "Image 2" },
  { id: 3, image: "/image3.jpg", alt: "Image 3" },
];

function App() {
  return <CarouselCircular items={items} />;
}

That's it! 🎉 The carousel will render with sensible defaults.

3️⃣ Luxury Example (Recommended)

For a premium look with 3D depth and smooth interactions:

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

function App() {
  return (
    <CarouselCircular
      items={items}
      containerHeight={600}
      geometry={{
        radius: 900,
        cameraAngle: 12,
      }}
      visualEffect={{
        minScale: 0.5,
        enableReflection: true,
      }}
    />
  );
}

📖 API Reference

Props

Required Props

| Prop | Type | Description | | ------- | ---------------- | ---------------------------------------------- | | items | CarouselItem[] | Array of items to display (max 30 recommended) |

3D Geometry (geometry)

| Prop | Type | Default | Description | | ---------------- | -------- | --------------- | ------------------------------------------------------------- | | radius | number | 600 | Circle radius in pixels | | perspective | number | radius * 3.33 | Perspective depth (min: radius * 2) | | cameraAngle | number | 0 | Camera vertical angle (-30 to 30 degrees) | | depthIntensity | number | 0 | Individual item Z-depth variation (0-3, recommended: 1.0-2.0) |

Interaction (interaction)

| Prop | Type | Default | Description | | -------------------------- | --------- | ------- | ---------------------------------------------------------------------------- | | dragSensitivity | number | 1.0 | Drag responsiveness multiplier | | enableMomentum | boolean | true | Enable physics-based momentum | | momentumFriction | number | 0.95 | Friction coefficient (0-1) | | enableKeyboardNavigation | boolean | true | Enable keyboard navigation (Arrow keys). Auto-disabled when lightbox is open |

Auto-Rotation (autoRotateConfig)

| Prop | Type | Default | Description | | ------------- | --------- | ------- | -------------------------------------------- | | enabled | boolean | false | Enable auto-rotation | | speed | number | 0.1 | Rotation speed (degrees/frame) | | resumeDelay | number | 3000 | Delay before resuming after interaction (ms) |

Visual Effects (visualEffect)

| Prop | Type | Default | Description | | ------------------ | ------------------ | ------------ | ------------------------------- | | opacityRange | [number, number] | [0.3, 1.0] | Opacity range [min, max] | | minScale | number | 0.7 | Minimum scale for back items (0.0~1.0, front items are always 1.0) | | enableReflection | boolean | false | Enable bottom reflection effect |

Styling (style)

| Prop | Type | Description | | --------------- | -------- | ----------------------- | | className | string | CSS class for container | | itemClassName | string | CSS class for each item |

Container

| Prop | Type | Default | Description | | ----------------- | -------- | ------- | -------------------------- | | containerHeight | number | 600 | Container height in pixels |

Lightbox

| Prop | Type | Default | Description | | ------------------------- | ----------------- | ------- | ------------------------ | | enableLightboxWhenClick | boolean | false | Enable lightbox on click | | lightboxOptions | LightboxOptions | - | Lightbox configuration |

LightboxOptions:

| Prop | Type | Default | Description | | -------------------------- | ---------- | ------- | ------------------------------------------------------------- | | enableKeyboardNavigation | boolean | true | Enable keyboard navigation (ArrowLeft/ArrowRight) in lightbox | | closeOnEsc | boolean | true | Enable ESC key to close lightbox | | backgroundBlur | number | 8 | Background blur intensity in pixels | | animationDuration | number | 500 | Animation duration in milliseconds | | onOpen | function | - | Callback when lightbox opens (receives index) | | onClose | function | - | Callback when lightbox closes |

Callbacks & Accessibility

| Prop | Type | Description | | ------------- | ----------------------- | ----------------------------- | | onItemClick | (item, index) => void | Callback when item is clicked | | ariaLabel | string | ARIA label for screen readers |

CarouselItem Type

// Image-based item
type CarouselItemWithImage = {
  id: string | number;
  image: string;
  lqip?: {
    base64: string;
    width: number;
    height: number;
  };
  alt?: string;
  title?: string;
};

// Custom content item
type CarouselItemWithContent = {
  id: string | number;
  content: ReactNode;
  alt?: string;
  title?: string;
};

type CarouselItem = CarouselItemWithImage | CarouselItemWithContent;

🎨 Use Cases & Examples

📸 Product Gallery with Lightbox

Perfect for e-commerce sites, portfolios, or any image-heavy application:

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

const products = [
  { id: 1, image: "/products/watch.jpg", alt: "Luxury Watch" },
  { id: 2, image: "/products/phone.jpg", alt: "Smartphone" },
  { id: 3, image: "/products/laptop.jpg", alt: "Laptop" },
];

export function ProductGallery() {
  return (
    <CarouselCircular
      items={products}
      enableLightboxWhenClick={true}
      lightboxOptions={{
        enableKeyboardNavigation: true,
        closeOnEsc: true,
        backgroundBlur: 10,
      }}
      geometry={{
        radius: 900,
        cameraAngle: 12,
      }}
    />
  );
}

Features:

  • Click any product to view full-screen
  • Navigate with arrow keys or swipe
  • Press ESC to close
  • Smooth fade transitions

🚀 Progressive Loading with LQIP

Show blurred placeholders instantly while high-res images load:

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

const items = [
  {
    id: 1,
    image: "/gallery/hero.jpg",
    lqip: {
      base64: "data:image/webp;base64,UklGRiQAAABXRUJQ...", // tiny base64 image
      width: 800,
      height: 600,
    },
    alt: "Mountain landscape",
  },
];

<CarouselCircular items={items} />;

Benefits:

  • Instant visual feedback (no blank space)
  • Smooth transition from blur to sharp
  • Better perceived performance
  • Works offline (base64 inline)

🎡 Auto-Rotating Hero Carousel

Great for landing pages or showcases:

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

export function HeroCarousel() {
  return (
    <CarouselCircular
      items={items}
      autoRotateConfig={{
        enabled: true,
        speed: 0.1, // Slow, elegant rotation
        resumeDelay: 3000, // Resume 3s after user interaction
      }}
      geometry={{
        radius: 1200,
        cameraAngle: 15,
      }}
    />
  );
}

Pro Tips:

  • Use slower speed (0.05-0.15) for luxury feel
  • Longer resumeDelay gives users control
  • Rotation pauses on hover/drag automatically

🎨 Custom Content Cards

Not just images! Render any React component:

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

const teamMembers = [
  {
    id: 1,
    content: (
      <div className="team-card">
        <img src="/avatar1.jpg" alt="John Doe" />
        <h3>John Doe</h3>
        <p>CEO & Founder</p>
        <div className="social-links">{/* Your custom content */}</div>
      </div>
    ),
  },
];

export function TeamCarousel() {
  return (
    <CarouselCircular
      items={teamMembers}
      containerHeight={500}
      itemClassName="custom-team-card"
    />
  );
}

Use Cases:

  • Team members
  • Testimonials
  • Feature cards
  • Pricing tiers
  • Anything you can imagine!

🎯 Full Example: Complete Product Showcase

import { useState } from "react";
import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

export function ProductShowcase() {
  const [selectedProduct, setSelectedProduct] = useState(null);

  const products = [
    {
      id: 1,
      image: "/products/watch.jpg",
      lqip: { base64: "...", width: 800, height: 600 },
      alt: "Premium Watch",
      title: "Swiss Automatic Watch",
    },
    // ... more products
  ];

  return (
    <div className="showcase">
      <CarouselCircular
        items={products}
        containerHeight={700}
        geometry={{
          radius: 1000,
          cameraAngle: 12,
          depthIntensity: 1.5,
        }}
        visualEffect={{
          minScale: 0.6,
          opacityRange: [0.4, 1],
          enableReflection: true,
        }}
        enableLightboxWhenClick={true}
        lightboxOptions={{
          onOpen: (index) => setSelectedProduct(products[index]),
          onClose: () => setSelectedProduct(null),
        }}
        autoRotateConfig={{
          enabled: true,
          speed: 0.08,
          resumeDelay: 4000,
        }}
        onItemClick={(item, index) => {
          console.log("Clicked:", item.title);
        }}
        ariaLabel="Product showcase carousel"
      />

      {selectedProduct && (
        <div className="product-info">
          <h2>{selectedProduct.title}</h2>
          {/* Additional product details */}
        </div>
      )}
    </div>
  );
}

🎯 Best Practices

Performance Tips

  1. Image Optimization: Use optimized images (WebP, compressed JPEG)
  2. LQIP: Include LQIP data for smooth loading experience
  3. Item Count: Keep items under 30 for optimal performance
  4. Container Height: Match your content size to avoid unnecessary scaling

Visual Design Tips

  1. Radius: Larger radius (900-1200px) creates more luxurious spacing
  2. Camera Angle: 8-15 degrees provides subtle depth without distortion
  3. Depth Intensity: 1.0-2.0 adds subtle Z-axis variation
  4. Scale Range: [0.5, 1] creates dramatic focus effect

Accessibility

  1. Always provide alt text for images
  2. Set meaningful ariaLabel for container
  3. Test keyboard navigation:
    • Carousel: Arrow keys (Left/Right) for navigation
    • Lightbox: Arrow keys (Left/Right) for navigation, ESC to close
    • Keyboard navigation is automatically disabled for carousel when lightbox is open to prevent conflicts
  4. Ensure sufficient color contrast for text overlays
  5. Configure keyboard options via interaction.enableKeyboardNavigation and lightboxOptions.enableKeyboardNavigation if needed

🔧 Framework Integration

Next.js (App Router)

// app/components/ProductCarousel.tsx
"use client"; // Required for client-side interactivity

import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

export function ProductCarousel({ items }) {
  return <CarouselCircular items={items} />;
}

Next.js (Pages Router)

// pages/index.tsx
import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

export default function Home() {
  return <CarouselCircular items={items} />;
}

Vite + React

// src/App.tsx
import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

export default function App() {
  return <CarouselCircular items={items} />;
}

Create React App

// src/App.js
import { CarouselCircular } from "@ddevkim/carousel-circular-3d";
import "@ddevkim/carousel-circular-3d/dist/index.css";

function App() {
  return <CarouselCircular items={items} />;
}

❓ Troubleshooting

Styles Not Showing

Problem: Carousel renders but has no styles (buttons missing, layout broken)

Solution: Make sure you import the CSS file:

import "@ddevkim/carousel-circular-3d/dist/index.css"; // ← Don't forget this!

Alternative imports that work:

// Option 1: Direct path (recommended)
import "@ddevkim/carousel-circular-3d/dist/index.css";

// Option 2: Using styles export
import "@ddevkim/carousel-circular-3d/styles";

TypeScript Errors

Problem: Type errors when using the component

Solution: The package includes TypeScript definitions. Make sure your tsconfig.json includes:

{
  "compilerOptions": {
    "moduleResolution": "bundler", // or "node"
    "esModuleInterop": true
  }
}

Images Not Loading

Problem: Images show broken icon or don't load

Solution:

  1. Check image paths: Ensure paths are correct relative to your public folder
  2. Use absolute URLs: Try using full URLs: https://example.com/image.jpg
  3. Verify CORS: If using external images, ensure CORS headers are set
// ✅ Good - relative to public folder
{ id: 1, image: "/images/product.jpg" }

// ✅ Good - absolute URL
{ id: 1, image: "https://cdn.example.com/product.jpg" }

// ❌ Bad - relative to component file
{ id: 1, image: "../assets/product.jpg" }

Performance Issues

Problem: Carousel feels laggy or slow

Solutions:

  1. Reduce item count: Keep items under 30
  2. Optimize images: Use WebP format and compress
  3. Add LQIP: Use progressive loading
  4. Check radius: Very large radius (>2000px) may impact performance
// ✅ Optimized
<CarouselCircular
  items={items.slice(0, 20)} // Limit items
  geometry={{ radius: 900 }} // Reasonable radius
/>

Lightbox Not Opening

Problem: Click on image but lightbox doesn't open

Solution: Make sure enableLightboxWhenClick is set to true:

<CarouselCircular
  items={items}
  enableLightboxWhenClick={true} // ← Required for lightbox
/>

Auto-Rotation Not Working

Problem: Carousel doesn't auto-rotate

Solution: Check your config:

<CarouselCircular
  items={items}
  autoRotateConfig={{
    enabled: true, // ← Must be true
    speed: 0.1,
  }}
/>

Keyboard Navigation Issues

Problem: Arrow keys don't work

Solutions:

  1. Carousel navigation: Ensure interaction.enableKeyboardNavigation is true (default)
  2. Lightbox navigation: Check lightboxOptions.enableKeyboardNavigation is true (default)
  3. Focus state: Carousel container must be focused (click on it first)
<CarouselCircular
  items={items}
  interaction={{
    enableKeyboardNavigation: true, // Carousel arrow keys
  }}
  lightboxOptions={{
    enableKeyboardNavigation: true, // Lightbox arrow keys
    closeOnEsc: true, // ESC to close
  }}
/>

🏗️ Architecture

Key Features

  • GPU-Accelerated: Uses CSS transform and will-change for 60fps animations
  • Physics-Based: Realistic momentum with configurable friction
  • Orientation Detection: Automatically calculates item sizes based on image dimensions
  • Smart Angle Distribution: Even spacing regardless of portrait/landscape mix
  • RAF-Based: All animations use requestAnimationFrame for smooth performance

💡 FAQ

Can I use this with TypeScript?

Yes! The package includes full TypeScript definitions with IntelliSense support.

Does it work with Server-Side Rendering (SSR)?

Yes! It works with Next.js (both App Router and Pages Router), including SSR and SSG.

For Next.js App Router, use the "use client" directive in your component file.

How do I generate LQIP data?

You can use any LQIP generation tool. Here are popular options:

  • sqip - SVG-based LQIP generator
  • lqip-modern - Modern LQIP with multiple algorithms
  • plaiceholder - Next.js-friendly LQIP generator
  • ImageMagick - Create base64 thumbnails with blur

Example with ImageMagick:

convert input.jpg -resize 20x -quality 30 -blur 0x1 output.webp
base64 output.webp

Can I customize the lightbox appearance?

The lightbox uses minimal inline styles. You can customize it by overriding CSS classes or using className props.

What's the browser support?

Modern browsers (Chrome, Firefox, Safari, Edge) with CSS3 transforms support. IE11 is not supported.

How many items can I display?

We recommend keeping items under 30 for optimal performance. The component can handle more, but performance may degrade on lower-end devices.

Can I use videos instead of images?

Currently, the component is optimized for images. For videos, use the content prop with a custom video player component.

🤝 Contributing

Contributions are welcome! This project is open source and we appreciate your help.

How to Contribute

  1. Fork the repository: Click the "Fork" button on GitHub
  2. Clone your fork:
    git clone https://github.com/YOUR_USERNAME/carousel-circular-3d.git
    cd carousel-circular-3d
  3. Install dependencies:
    pnpm install
  4. Create a feature branch:
    git checkout -b feature/amazing-feature
  5. Make your changes and test in the playground:
    pnpm dev
  6. Run linting:
    pnpm lint:fix
  7. Run type checking:
    pnpm type-check
  8. Commit your changes:
    git commit -m 'feat: add amazing feature'
  9. Push to your fork:
    git push origin feature/amazing-feature
  10. Open a Pull Request on GitHub

Reporting Bugs

Found a bug? Please open an issue with:

  • Clear description of the problem
  • Steps to reproduce
  • Expected vs actual behavior
  • Browser/device information
  • Minimal code example

Feature Requests

Have an idea? Open an issue describing:

  • The feature you'd like
  • Why it would be useful
  • Proposed API (if applicable)

📄 License

MIT © ddevkim

🙏 Acknowledgments

Built with:

  • React 18+ for modern UI
  • TypeScript for type safety
  • tsup for blazing-fast builds
  • Turbo for monorepo management

📬 Contact

Have questions or need support?


Made with ❤️ by ddevkim