## Media Components

JavaScript components for carousels, galleries, image comparison, lazy loading, and lightbox.

### Carousel Manager

Carousel/slider for cycling through items with autoplay and looping.

### Slide 1

First slide content

### Slide 2

Second slide content

### Slide 3

Third slide content

HTML

    <!-- Basic carousel -->
            <div
                data-ss="carousel"
                data-ss-carousel-loop="true"
                data-ss-carousel-autoplay="5000"
                style="
                    position: relative;
                    max-width: 600px;
                    border-radius: 12px;
                    overflow: hidden;
                "
            >
                <div
                    class="carousel-track"
                    style="display: flex; transition: transform 0.5s ease"
                >
                    <div
                        class="carousel-item active"
                        style="
                            min-width: 100%;
                            height: 300px;
                            background: linear-gradient(
                                135deg,
                                #667eea 0%,
                                #764ba2 100%
                            );
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            color: white;
                        "
                    >
                        <div style="text-align: center">
                            <h3 style="margin: 0 0 8px">Slide 1</h3>
                            <p style="margin: 0; opacity: 0.8">
                                First slide content
                            </p>
                        </div>
                    </div>
                    <div
                        class="carousel-item"
                        style="
                            min-width: 100%;
                            height: 300px;
                            background: linear-gradient(
                                135deg,
                                #f093fb 0%,
                                #f5576c 100%
                            );
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            color: white;
                        "
                    >
                        <div style="text-align: center">
                            <h3 style="margin: 0 0 8px">Slide 2</h3>
                            <p style="margin: 0; opacity: 0.8">
                                Second slide content
                            </p>
                        </div>
                    </div>
                    <div
                        class="carousel-item"
                        style="
                            min-width: 100%;
                            height: 300px;
                            background: linear-gradient(
                                135deg,
                                #4facfe 0%,
                                #00f2fe 100%
                            );
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            color: white;
                        "
                    >
                        <div style="text-align: center">
                            <h3 style="margin: 0 0 8px">Slide 3</h3>
                            <p style="margin: 0; opacity: 0.8">
                                Third slide content
                            </p>
                        </div>
                    </div>
                </div>

                <!-- Navigation arrows -->
                <button
                    class="carousel-prev"
                    style="
                        position: absolute;
                        left: 16px;
                        top: 50%;
                        transform: translateY(-50%);
                        width: 40px;
                        height: 40px;
                        border-radius: 50%;
                        background: rgba(255, 255, 255, 0.9);
                        border: none;
                        cursor: pointer;
                        font-size: 18px;
                    "
                >
                    ←
                </button>
                <button
                    class="carousel-next"
                    style="
                        position: absolute;
                        right: 16px;
                        top: 50%;
                        transform: translateY(-50%);
                        width: 40px;
                        height: 40px;
                        border-radius: 50%;
                        background: rgba(255, 255, 255, 0.9);
                        border: none;
                        cursor: pointer;
                        font-size: 18px;
                    "
                >
                    →
                </button>

                <!-- Indicators -->
                <div
                    class="carousel-indicators"
                    style="
                        position: absolute;
                        bottom: 16px;
                        left: 50%;
                        transform: translateX(-50%);
                        display: flex;
                        gap: 8px;
                    "
                >
                    <span
                        class="active"
                        style="
                            width: 24px;
                            height: 4px;
                            border-radius: 2px;
                            background: white;
                            cursor: pointer;
                        "
                    ></span>
                    <span
                        style="
                            width: 12px;
                            height: 4px;
                            border-radius: 2px;
                            background: rgba(255, 255, 255, 0.5);
                            cursor: pointer;
                        "
                    ></span>
                    <span
                        style="
                            width: 12px;
                            height: 4px;
                            border-radius: 2px;
                            background: rgba(255, 255, 255, 0.5);
                            cursor: pointer;
                        "
                    ></span>
                </div>
            </div>

### Gallery Manager

Image gallery with navigation, selection, and lightbox integration.

HTML

    <!-- Gallery with lightbox -->
            <div
                data-ss="gallery"
                data-ss-gallery-lightbox="true"
                style="
                    display: grid;
                    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
                    gap: 12px;
                "
            >
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #667eea, #764ba2);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%23667eea' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 1"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #f093fb, #f5576c);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%23f093fb' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 2"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #4facfe, #00f2fe);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%234facfe' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 3"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #43e97b, #38f9d7);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%2343e97b' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 4"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #fa709a, #fee140);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%23fa709a' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 5"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
                <div
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(135deg, #a8edea, #fed6e3);
                        border-radius: 8px;
                        cursor: pointer;
                        overflow: hidden;
                        transition: transform 0.2s;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Crect fill='%23a8edea' width='100' height='100'/%3E%3C/svg%3E"
                        alt="Image 6"
                        style="width: 100%; height: 100%; object-fit: cover"
                    />
                </div>
            </div>

### Image Compare Slider

Before/after image comparison slider with drag support.

After
Before
⟷
Edited
Original
HTML

    <!-- Image comparison -->
            <div
                class="image__compare"
                data-ss="image-compare"
                data-ss-image-compare-position="50"
                style="
                    position: relative;
                    max-width: 600px;
                    aspect-ratio: 16/9;
                    overflow: hidden;
                    border-radius: 12px;
                    cursor: ew-resize;
                "
            >
                <!-- After image (bottom layer) -->
                <div
                    class="image__compare--image"
                    style="
                        position: absolute;
                        inset: 0;
                        background: linear-gradient(135deg, #667eea, #764ba2);
                    "
                >
                    <div
                        style="
                            position: absolute;
                            bottom: 16px;
                            right: 16px;
                            padding: 8px 16px;
                            background: rgba(0, 0, 0, 0.6);
                            color: white;
                            border-radius: 4px;
                            font-size: 14px;
                        "
                    >
                        After
                    </div>
                </div>

                <!-- Before image (top layer, clipped) -->
                <div
                    class="image__compare--overlay"
                    style="
                        position: absolute;
                        inset: 0;
                        background: linear-gradient(135deg, #1a1a2e, #16213e);
                        clip-path: inset(0 50% 0 0);
                    "
                >
                    <div
                        style="
                            position: absolute;
                            bottom: 16px;
                            left: 16px;
                            padding: 8px 16px;
                            background: rgba(0, 0, 0, 0.6);
                            color: white;
                            border-radius: 4px;
                            font-size: 14px;
                        "
                    >
                        Before
                    </div>
                </div>

                <!-- Slider handle -->
                <div
                    class="image__compare--slider"
                    style="
                        position: absolute;
                        top: 0;
                        bottom: 0;
                        left: 50%;
                        width: 4px;
                        background: white;
                        cursor: ew-resize;
                        transform: translateX(-50%);
                    "
                >
                    <div
                        style="
                            position: absolute;
                            top: 50%;
                            left: 50%;
                            transform: translate(-50%, -50%);
                            width: 40px;
                            height: 40px;
                            background: white;
                            border-radius: 50%;
                            display: flex;
                            align-items: center;
                            justify-content: center;
                            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
                        "
                    >
                        <span style="font-size: 16px">⟷</span>
                    </div>
                </div>
            </div>

            <!-- With indicator labels -->
            <div
                class="image__compare"
                data-ss="image-compare"
                data-ss-image-compare-position="30"
                style="
                    position: relative;
                    max-width: 600px;
                    aspect-ratio: 4/3;
                    overflow: hidden;
                    border-radius: 12px;
                    margin-top: 24px;
                "
            >
                <div
                    style="
                        position: absolute;
                        inset: 0;
                        background: #22c55e;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        color: white;
                        font-size: 24px;
                    "
                >
                    Edited
                </div>
                <div
                    style="
                        position: absolute;
                        inset: 0;
                        background: #ef4444;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        color: white;
                        font-size: 24px;
                        clip-path: inset(0 70% 0 0);
                    "
                >
                    Original
                </div>
                <div
                    style="
                        position: absolute;
                        top: 0;
                        bottom: 0;
                        left: 30%;
                        width: 3px;
                        background: white;
                    "
                ></div>
            </div>

### Lazy Load Manager

Lazy loading of images via IntersectionObserver.

Background loading...
HTML

    <!-- Lazy loaded image -->
            <img
                class="lazy-image"
                data-ss="lazy"
                data-src="https://picsum.photos/800/400"
                src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 800 400'%3E%3Crect fill='%23e5e7eb' width='800' height='400'/%3E%3C/svg%3E"
                alt="Lazy loaded image"
                style="
                    width: 100%;
                    max-width: 600px;
                    height: auto;
                    border-radius: 12px;
                    transition: opacity 0.3s;
                "
            />

            <!-- Lazy loaded background -->
            <div
                class="lazy-bg"
                data-ss="lazy"
                data-src="https://picsum.photos/1200/600"
                style="
                    width: 100%;
                    max-width: 600px;
                    height: 300px;
                    background: var(--color_fill_secondary);
                    border-radius: 12px;
                    margin-top: 16px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    color: var(--color_text_secondary);
                "
            >
                <span>Background loading...</span>
            </div>

            <!-- Skeleton placeholder -->
            <div
                style="
                    display: grid;
                    grid-template-columns: repeat(3, 1fr);
                    gap: 16px;
                    max-width: 600px;
                    margin-top: 24px;
                "
            >
                <div
                    class="lazy-image"
                    data-ss="lazy"
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(
                            90deg,
                            var(--color_fill_secondary) 0%,
                            #e5e7eb 50%,
                            var(--color_fill_secondary) 100%
                        );
                        background-size: 200% 100%;
                        animation: shimmer 1.5s infinite;
                        border-radius: 8px;
                    "
                ></div>
                <div
                    class="lazy-image"
                    data-ss="lazy"
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(
                            90deg,
                            var(--color_fill_secondary) 0%,
                            #e5e7eb 50%,
                            var(--color_fill_secondary) 100%
                        );
                        background-size: 200% 100%;
                        animation: shimmer 1.5s infinite;
                        border-radius: 8px;
                    "
                ></div>
                <div
                    class="lazy-image"
                    data-ss="lazy"
                    style="
                        aspect-ratio: 1;
                        background: linear-gradient(
                            90deg,
                            var(--color_fill_secondary) 0%,
                            #e5e7eb 50%,
                            var(--color_fill_secondary) 100%
                        );
                        background-size: 200% 100%;
                        animation: shimmer 1.5s infinite;
                        border-radius: 8px;
                    "
                ></div>
            </div>

            <style>
                @keyframes shimmer {
                    0% {
                        background-position: -200% 0;
                    }
                    100% {
                        background-position: 200% 0;
                    }
                }
            </style>

### Lightbox Manager

Fullscreen lightbox overlay for viewing content.

HTML

    <!-- Lightbox triggers -->
            <div style="display: flex; gap: 16px">
                <button
                    data-ss="lightbox"
                    data-ss-lightbox-src="https://picsum.photos/1200/800"
                    style="
                        padding: 0;
                        border: none;
                        cursor: pointer;
                        border-radius: 8px;
                        overflow: hidden;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 150'%3E%3Crect fill='%23667eea' width='200' height='150'/%3E%3C/svg%3E"
                        alt="Thumbnail 1"
                        style="
                            width: 200px;
                            height: 150px;
                            object-fit: cover;
                            display: block;
                        "
                    />
                </button>
                <button
                    data-ss="lightbox"
                    data-ss-lightbox-src="https://picsum.photos/1200/900"
                    style="
                        padding: 0;
                        border: none;
                        cursor: pointer;
                        border-radius: 8px;
                        overflow: hidden;
                    "
                >
                    <img
                        src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 150'%3E%3Crect fill='%23f093fb' width='200' height='150'/%3E%3C/svg%3E"
                        alt="Thumbnail 2"
                        style="
                            width: 200px;
                            height: 150px;
                            object-fit: cover;
                            display: block;
                        "
                    />
                </button>
            </div>

            <!-- Lightbox overlay structure -->
            <div
                class="lightbox"
                style="
                    position: fixed;
                    inset: 0;
                    background: rgba(0, 0, 0, 0.95);
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    z-index: 2000;
                    opacity: 0;
                    pointer-events: none;
                "
            >
                <button
                    class="lightbox__close"
                    style="
                        position: absolute;
                        top: 20px;
                        right: 20px;
                        width: 48px;
                        height: 48px;
                        background: rgba(255, 255, 255, 0.1);
                        border: none;
                        border-radius: 50%;
                        color: white;
                        font-size: 24px;
                        cursor: pointer;
                    "
                >
                    ×
                </button>
                <button
                    class="lightbox__prev"
                    style="
                        position: absolute;
                        left: 20px;
                        top: 50%;
                        transform: translateY(-50%);
                        width: 48px;
                        height: 48px;
                        background: rgba(255, 255, 255, 0.1);
                        border: none;
                        border-radius: 50%;
                        color: white;
                        font-size: 24px;
                        cursor: pointer;
                    "
                >
                    ←
                </button>
                <button
                    class="lightbox__next"
                    style="
                        position: absolute;
                        right: 20px;
                        top: 50%;
                        transform: translateY(-50%);
                        width: 48px;
                        height: 48px;
                        background: rgba(255, 255, 255, 0.1);
                        border: none;
                        border-radius: 50%;
                        color: white;
                        font-size: 24px;
                        cursor: pointer;
                    "
                >
                    →
                </button>
                <img
                    class="lightbox__image"
                    src=""
                    alt=""
                    style="max-width: 90vw; max-height: 90vh; object-fit: contain"
                />
                <div
                    class="lightbox__caption"
                    style="
                        position: absolute;
                        bottom: 20px;
                        left: 50%;
                        transform: translateX(-50%);
                        color: white;
                        text-align: center;
                    "
                ></div>
            </div>

### JavaScript API

Programmatic control of media components.

JavaScript

    <script>
                // CarouselManager
                import { CarouselManager } from "stylescape";

                const carousel = new CarouselManager(element, {
                    loop: true,
                    autoplay: 5000,
                    pauseOnHover: true,
                    slidesToShow: 1,
                    slidesToScroll: 1,
                    onChange: (index) => console.log("Slide changed:", index),
                });

                carousel.next(); // Go to next slide
                carousel.prev(); // Go to previous slide
                carousel.goTo(2); // Go to specific slide
                carousel.play(); // Start autoplay
                carousel.pause(); // Pause autoplay
                carousel.getCurrentIndex();

                // GalleryManager
                import { GalleryManager } from "stylescape";

                const gallery = new GalleryManager(element, {
                    lightbox: true,
                    thumbs: true,
                    zoom: true,
                    onSelect: (index, image) => {
                        console.log("Selected:", index);
                    },
                });

                gallery.select(0); // Select image
                gallery.openLightbox(1); // Open lightbox at index
                gallery.closeLightbox();

                // ImageCompareSlider
                import { ImageCompareSlider } from "stylescape";

                const compare = new ImageCompareSlider(element, {
                    position: 50,
                    vertical: false,
                    onChange: (position) => {
                        console.log("Position:", position + "%");
                    },
                });

                compare.setPosition(75); // Set slider position

                // LazyLoadManager
                import { LazyLoadManager } from "stylescape";

                const lazyLoader = new LazyLoadManager({
                    root: null,
                    rootMargin: "100px",
                    threshold: 0.1,
                    onLoad: (element) => {
                        element.classList.add("loaded");
                    },
                });

                lazyLoader.observe(element);
                lazyLoader.unobserve(element);
                lazyLoader.refresh();

                // LightboxManager
                import { LightboxManager } from "stylescape";

                const lightbox = new LightboxManager({
                    animation: "fade",
                    closeOnBackdrop: true,
                    keyboard: true,
                    captions: true,
                });

                lightbox.open(imageSrc, caption);
                lightbox.close();
                lightbox.next();
                lightbox.prev();
            </script>

- Latest update: Stylescape v0.1 now live!
- New components released today.
- 💡 Tip: Use mixins for modular SCSS!