Catalog npm
PACKAGE EXPLORERView in registry

3d-whell-parallax-carousel

npm

Smooth 3D parallax carousel with trapezoid perspective effect. Works with Vanilla JS, React, and Vue.

3d3d-carouselcarouselparallaxparallax-sliderreactslidertypescriptvanillavue
Versions collected4
Direct dependencies11From release 1.0.3
Last observed20 Oct, 19:38 UTC

README

Current package documentation

Smooth 3D parallax carousel with trapezoid perspective effect. Shows 5 cards at once — center card flat, side cards angled like a fan. Works with Vanilla JS, React, Vue 3, and TypeScript.

Install

npm install 3d-whell-parallax-carousel

Usage

Vanilla JS

import { ParallaxCarousel } from "3d-whell-parallax-carousel";

const carousel = new ParallaxCarousel("#my-container", [
  '<div style="color:white">Card 1</div>',
  '<div style="color:white">Card 2</div>',
  '<div style="color:white">Card 3</div>',
]);

With renderItem callback (HTML string)

import { ParallaxCarousel } from "3d-whell-parallax-carousel";

const products = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

const carousel = new ParallaxCarousel("#my-container", products, {
  renderItem: ({ item, index }) => `
    <div style="text-align: center; padding: 20px;">
      <img src="${item.image}" alt="${item.name}" style="width: 100%; border-radius: 4px;" />
      <h3 style="margin-top: 10px; color: white;">${item.name}</h3>
    </div>
  `,
});

TypeScript

import { ParallaxCarousel, type ParallaxCarouselOptions } from "3d-whell-parallax-carousel";

interface Product {
  id: number;
  name: string;
  image: string;
}

const products: Product[] = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

const options: ParallaxCarouselOptions<Product> = {
  autoplay: true,
  renderItem: ({ item }) => `
    <div>
      <img src="${item.image}" alt="${item.name}" />
      <h3>${item.name}</h3>
    </div>
  `,
};

const carousel = new ParallaxCarousel<Product>("#my-container", products, options);

React

import { ParallaxCarouselReact } from "3d-whell-parallax-carousel/react";

const items = ["<div>Card 1</div>", "<div>Card 2</div>", "<div>Card 3</div>"];

function App() {
  const ref = useRef(null);

  return (
    <>
      <ParallaxCarouselReact
        ref={ref}
        items={items}
        options={{ autoplay: true, interval: 3000 }}
        onChange={({ index }) => console.log("Slide:", index)}
      />
      <button onClick={() => ref.current.next()}>Next</button>
    </>
  );
}

React with renderItem (JSX Component)

import { ParallaxCarouselReact } from "3d-whell-parallax-carousel/react";

const products = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

// Your custom React component
function ProductCard({ product, index }) {
  return (
    <div style={{ padding: '20px', textAlign: 'center' }}>
      <img src={product.image} alt={product.name} style={{ width: '100%', borderRadius: '4px' }} />
      <h3 style={{ marginTop: '10px', color: 'white' }}>{product.name}</h3>
      <p style={{ color: 'rgba(255,255,255,0.6)' }}>Index: {index}</p>
    </div>
  );
}

function App() {
  const ref = useRef(null);

  return (
    <ParallaxCarouselReact
      ref={ref}
      items={products}
      options={{
        autoplay: true,
        renderItem: ({ item, index }) => (
          <ProductCard product={item} index={index} />
        ),
      }}
      onChange={({ index }) => console.log("Slide:", index)}
    />
  );
}

React with TypeScript

import { useRef } from "react";
import {
  ParallaxCarouselReact,
  type ParallaxCarouselReactHandle,
  type ParallaxCarouselReactProps,
} from "3d-whell-parallax-carousel/react";

interface Product {
  id: number;
  name: string;
  image: string;
}

const items: Product[] = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

function App() {
  const carouselRef = useRef<ParallaxCarouselReactHandle>(null);

  const handleChange: ParallaxCarouselReactProps["onChange"] = ({ index, total }) => {
    console.log(`Slide ${index} of ${total}`);
  };

  return (
    <>
      <ParallaxCarouselReact<Product>
        ref={carouselRef}
        items={items}
        options={{
          autoplay: true,
          renderItem: ({ item, index }) => (
            <div>
              <img src={item.image} alt={item.name} />
              <h3>{item.name}</h3>
            </div>
          ),
        }}
        onChange={handleChange}
      />
      <button onClick={() => carouselRef.current?.next()}>Next</button>
    </>
  );
}

Vue 3

<template>
  <ParallaxCarousel
    ref="carousel"
    :items="items"
    :options="{ autoplay: true, interval: 3000 }"
    @change="onSlideChange"
  />
  <button @click="$refs.carousel.next()">Next</button>
</template>

<script setup>
import { ParallaxCarouselVue as ParallaxCarousel } from "3d-whell-parallax-carousel/vue";

const items = ["<div>Card 1</div>", "<div>Card 2</div>"];
const onSlideChange = ({ index, total }) => console.log(index, total);
</script>

Vue 3 with renderItem (VNode)

<template>
  <ParallaxCarousel
    ref="carousel"
    :items="products"
    :options="{
      autoplay: true,
      renderItem: ({ item, index }) => h('div', { 
        style: { padding: '20px', textAlign: 'center' }
      }, [
        h('img', { src: item.image, style: { width: '100%', borderRadius: '4px' } }),
        h('h3', { style: { marginTop: '10px', color: 'white' } }, item.name),
        h('p', { style: { color: 'rgba(255,255,255,0.6)' } }, `Index: ${index}`),
      ]),
    }"
    @change="onSlideChange"
  />
</template>

<script setup>
import { h } from 'vue';
import { ParallaxCarouselVue as ParallaxCarousel } from "3d-whell-parallax-carousel/vue";

const products = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

const onSlideChange = ({ index, total }) => console.log(index, total);
</script>

Vue 3 with TypeScript

<template>
  <ParallaxCarousel
    ref="carouselRef"
    :items="products"
    :options="options"
    @change="onSlideChange"
  />
  <button @click="carouselRef?.next()">Next</button>
</template>

<script setup lang="ts">
import { ref, h, type VNode } from "vue";
import {
  ParallaxCarouselVue as ParallaxCarousel,
  type ParallaxCarouselInstance,
  type ParallaxCarouselOptions,
  type RenderItemContext,
} from "3d-whell-parallax-carousel/vue";

interface Product {
  id: number;
  name: string;
  image: string;
}

const carouselRef = ref<ParallaxCarouselInstance | null>(null);

const products: Product[] = [
  { id: 1, name: "Product 1", image: "/img1.jpg" },
  { id: 2, name: "Product 2", image: "/img2.jpg" },
];

const options: ParallaxCarouselOptions<Product> = {
  autoplay: true,
  renderItem: ({ item, index }: RenderItemContext<Product>): VNode => {
    return h('div', { style: { padding: '20px' } }, [
      h('img', { src: item.image, style: { width: '100%' } }),
      h('h3', item.name),
    ]);
  },
};

const onSlideChange = ({ index, total }: { index: number; total: number }) => {
  console.log(`Slide ${index} of ${total}`);
};
</script>

Options

OptionTypeDefaultDescription
autoplaybooleantrueEnable auto-advance
intervalnumber2800Autoplay interval in ms
pauseOnHoverbooleantruePause autoplay on hover
durationnumber650Transition duration in ms
easingstring'cubic-bezier(0.4,0,0.2,1)'CSS easing
backgroundstring'#111111'Card background color
borderColorstring'rgba(255,255,255,0.1)'Card border color
borderWidthstring'1.5px'Card border width
borderRadiusstring'4px'Card border radius
stageHeightstring'420px'Height of the carousel stage
perspectivenumber900CSS perspective value in px
showGridbooleantrueShow background grid
gridColorstring'rgba(255,255,255,0.032)'Grid line color
gridSizestring'38px'Grid cell size
slotsobjectsee belowPer-slot position config
renderItemfunctionundefinedCustom render function

slots config

Customize each of the 5 visible positions (-2 to +2):

import type { ParallaxCarouselOptions } from "3d-whell-parallax-carousel";

const options: ParallaxCarouselOptions = {
  slots: {
    '-2': { x: -490, w: 220, h: 330, ry:  50, origin: 'right center',  z: 1, op: 1 },
    '-1': { x: -255, w: 192, h: 295, ry:  26, origin: 'right center',  z: 2, op: 1 },
     '0': { x:    0, w: 188, h: 275, ry:   0, origin: 'center center', z: 3, op: 1 },
     '1': { x:  255, w: 192, h: 295, ry: -26, origin: 'left center',   z: 2, op: 1 },
     '2': { x:  490, w: 220, h: 330, ry: -50, origin: 'left center',   z: 1, op: 1 },
  },
};
FieldDescription
xHorizontal offset from center in px
wCard width in px
hCard height in px
ryrotateY angle in degrees
originCSS transform-origin
zz-index
opopacity (0–1)

renderItem callback

Custom render function for each item. Returns depend on framework:

FrameworkReturn TypeExample
Vanilla JSstring | HTMLElement'<div>Content</div>'
ReactReactNode<MyComponent />
Vue 3VNode | stringh('div', 'Content')

Context object:

type RenderItem = (context: {
  item: T;        // The item data
  index: number;  // Item index
  container: HTMLElement; // Card container element
}) => ReactNode | VNode | HTMLElement | string;

API

Vanilla JS / Core

carousel.next(); // Go to next slide
carousel.prev(); // Go to previous slide
carousel.goTo(index); // Jump to specific index
carousel.updateOptions({
  // Update options at runtime
  interval: 5000,
  background: "#222",
});
carousel.destroy(); // Clean up and remove from DOM

React Ref Methods

const ref = useRef<ParallaxCarouselReactHandle>(null);

ref.current?.next();
ref.current?.prev();
ref.current?.goTo(2);
ref.current?.updateOptions({ interval: 5000 });
ref.current?.destroy();

Vue Ref Methods

<script setup lang="ts">
const carouselRef = ref<ParallaxCarouselInstance | null>(null);

carouselRef.value?.next();
carouselRef.value?.prev();
carouselRef.value?.goTo(2);
carouselRef.value?.updateOptions({ interval: 5000 });
carouselRef.value?.destroy();
</script>

Events

Vanilla JS

container.addEventListener("change", (e) => {
  console.log(e.detail.index); // current index
  console.log(e.detail.total); // total items
});

React

<ParallaxCarouselReact
  items={items}
  onChange={({ index, total }) => {
    console.log(`Slide ${index} of ${total}`);
  }}
/>

Vue

<ParallaxCarousel
  :items="items"
  @change="({ index, total }) => console.log(`Slide ${index} of ${total}`)"
/>

Build from source

npm install
npm run build

Output goes to dist/.

Development

# Watch mode
npm run dev

# Type check
npm run typecheck

TypeScript Support

This library includes full TypeScript support with:

  • ✅ Complete type definitions for all exports
  • ✅ Generic type support for items (<T>)
  • ✅ Type-safe renderItem callback with framework-specific return types
  • ✅ ReactNode support for React
  • ✅ VNode support for Vue
  • ✅ Type-safe options and props
  • ✅ Typed event handlers
  • ✅ Proper ref types for React and Vue
  • ✅ tsconfig.json included

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 4

Collected releases
VersionPublishedDirect dependenciesOpen version
1.0.3Registry latest18 Feb 202611
1.0.218 Feb 202611
1.0.118 Feb 20268
1.0.018 Feb 20268

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
nodirbek/3d-whell-parallax-carousel

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 19:38 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:f2d4b9a5afb39605d66ad644b4e4b060c22879d5768adb2bf2347c6a9e1c6209