react-3d-tablet-carousel
v1.0.3
Published
A lightweight 3D floating tablet carousel for React.
Maintainers
Readme
react-3d-tablet-carousel
A lightweight 3D floating tablet/image carousel for React.
Designed for screenshots, product previews, portfolios, landing pages, and split-screen layouts where the active image stays large and readable while nearby images sit behind it in 3D.
Installation
npm install react-3d-tablet-carouselImport the component and its styles:
import { TabletCarousel } from "react-3d-tablet-carousel";
import "react-3d-tablet-carousel/styles.css";Two common layouts
1. Full-screen / full-width carousel
Use this when the carousel should occupy the available page or viewport area.
<TabletCarousel
imagePath="/images"
imageNames={["01.png", "02.png", "03.png", "04.png", "05.png"]}
sizing="viewport"
align="center"
/>With Vite/React, the files can live in:
public/
└── images/
├── 01.png
├── 02.png
├── 03.png
├── 04.png
└── 05.pngThe browser URL for 01.png is:
/images/01.png2. 50% split-screen carousel
Use sizing="container" when the carousel is inside a parent such as a 50/50 layout.
<div style={{ display: "flex", width: "100%" }}>
<div style={{ width: "50%" }}>Your content</div>
<div style={{ width: "50%" }}>
<TabletCarousel
imagePath="/images"
imageNames={["01.png", "02.png", "03.png", "04.png", "05.png"]}
sizing="container"
width="100%"
align="center"
/>
</div>
</div>container sizing makes the carousel respond to the width of its parent instead of the browser viewport.
Using image URLs
You can also pass complete image URLs directly:
<TabletCarousel
images={[
"https://example.com/images/01.png",
"https://example.com/images/02.png",
"https://example.com/images/03.png",
]}
/>You can also use local paths:
<TabletCarousel
images={["/images/01.png", "/images/02.png", "/images/03.png"]}
/>Image loading
The carousel supports smart loading so the active image and nearby images are loaded first.
<TabletCarousel
images={[
"/images/01.png",
"/images/02.png",
"/images/03.png",
"/images/04.png",
]}
imageLoading="smart"
preloadDistance={1}
/>Options:
smart— preload the active image and nearby imageslazy— use browser lazy loadingeager— load images eagerlyauto— let the browser decide
Controls and interaction
The carousel supports:
- Mouse / touch swipe
- Dragging
- Previous / next buttons
- Pagination dots
- Clicking side images
- Keyboard arrow keys
- Mouse wheel / trackpad navigation
- Optional autoplay
Example:
<TabletCarousel
images={["/01.png", "/02.png", "/03.png", "/04.png"]}
showArrows
showDots
swipeEnabled
keyboardEnabled
wheelEnabled
clickSideImages
/>Autoplay
<TabletCarousel
images={["/01.png", "/02.png", "/03.png"]}
autoPlay
autoPlayInterval={4000}
/>autoPlayInterval is in milliseconds.
3D customization
Adjust the depth and perspective of the carousel:
<TabletCarousel
images={["/01.png", "/02.png", "/03.png", "/04.png"]}
perspective={1400}
depth={260}
rotation={32}
sideScale={0.72}
sideOpacity={0.82}
maxVisible={2}
/>Common options:
| Prop | Default | Description |
| ------------- | ------: | ----------------------------------- |
| perspective | 1400 | 3D perspective |
| depth | 260 | Distance of side images |
| rotation | 32 | Side-image rotation |
| sideScale | 0.72 | Scale of side images |
| sideOpacity | 0.82 | Side-image opacity |
| maxVisible | 2 | Number of images shown on each side |
Floating animation
The active tablet can gently float vertically:
<TabletCarousel
images={["/01.png", "/02.png", "/03.png"]}
float
floatAmplitude={10}
floatDuration={4.8}
/>Disable it with:
<TabletCarousel images={["/01.png", "/02.png", "/03.png"]} float={false} />Animation
<TabletCarousel
images={["/01.png", "/02.png", "/03.png"]}
transitionDuration={650}
easing="cubic-bezier(.22,1,.36,1)"
/>Callbacks
Listen for the active image changing:
<TabletCarousel
images={["/01.png", "/02.png", "/03.png"]}
onChange={(index) => {
console.log("Active image:", index);
}}
/>Handle image clicks:
<TabletCarousel
images={["/01.png", "/02.png", "/03.png"]}
onImageClick={(index, image) => {
console.log("Clicked:", index, image);
}}
/>Common props
| Prop | Default | Description |
| ------------------ | ------------ | ---------------------------------- |
| images | [] | Array of image URLs |
| imagePath | "" | Base path for local images |
| imageNames | — | Image filenames |
| startIndex | 0 | Initial active image |
| loop | true | Loop from last image to first |
| autoPlay | false | Enable autoplay |
| autoPlayInterval | 4000 | Autoplay interval in ms |
| swipeEnabled | true | Enable swipe / drag |
| keyboardEnabled | true | Enable keyboard navigation |
| wheelEnabled | true | Enable wheel navigation |
| clickSideImages | true | Allow clicking side images |
| showArrows | true | Show navigation arrows |
| showDots | true | Show pagination dots |
| showCounter | false | Show image counter |
| showHint | false | Show interaction hint |
| sizing | "viewport" | "viewport" or "container" |
| align | "center" | "center", "left", or "right" |
| width | — | Carousel/tablet width |
| aspectRatio | "16 / 9" | Image aspect ratio |
| float | true | Enable floating animation |
| imageLoading | "smart" | Image loading strategy |
| preloadDistance | 1 | Number of nearby images to preload |
License
MIT
