LISN.js

Edit on StackBlitz

"use client";
import {
  PagerComponent,
  PagerPageComponent,
  PagerSwitchComponent,
  PagerPrevSwitchComponent,
  PagerNextSwitchComponent,
} from "@lisn.js/react";
import "lisn.js/pager.css";

import Image from "next/image";

import styles from "./demo.module.css";

export default function Page() {
  return (
    <>
      <div className={styles.wrapper}>
        <PagerComponent
          className={styles.demo}
          config={{ horizontal: true, parallax: true, useGestures: false }}
        >
          <div className={styles.switches} data-switches="prev-next">
            <PagerPrevSwitchComponent
              className={styles.switch}
              data-switch="prev"
              aria-label="Previous"
            ></PagerPrevSwitchComponent>
            <PagerNextSwitchComponent
              className={styles.switch}
              data-switch="next"
              aria-label="Next"
            ></PagerNextSwitchComponent>
          </div>

          <div className={styles.switches} data-switches="select">
            <PagerSwitchComponent
              className={styles.switch}
              aria-label="Page 1"
            ></PagerSwitchComponent>
            <PagerSwitchComponent
              className={styles.switch}
              aria-label="Page 2"
            ></PagerSwitchComponent>
            <PagerSwitchComponent
              className={styles.switch}
              aria-label="Page 3"
            ></PagerSwitchComponent>
            <PagerSwitchComponent
              className={styles.switch}
              aria-label="Page 4"
            ></PagerSwitchComponent>
          </div>

          <div className={styles.pages}>
            <PagerPageComponent>
              {/* https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 */}
              <Image
                className={styles.background}
                src="/images/abstract-1.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent>
              {/* https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 */}
              <Image
                className={styles.background}
                src="/images/abstract-2.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent>
              {/* https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM */}
              <Image
                className={styles.background}
                src="/images/abstract-3.jpg"
                alt=""
              />
            </PagerPageComponent>

            <PagerPageComponent>
              {/* https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ */}
              <Image
                className={styles.background}
                src="/images/abstract-4.jpg"
                alt=""
              />
            </PagerPageComponent>
          </div>
        </PagerComponent>
      </div>
    </>
  );
}
/* Container */
.wrapper {
  --animate-duration: 0.4s;
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  width: 100dvw;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

/* Pager and pages */
.demo {
  width: 800px;
  max-width: 100%;
  box-shadow: var(--lisn-shadow);
  position: relative;
}

.pages {
  height: 400px;
  max-height: 100%;
}

.demo,
.background {
  border-radius: 15px;
}

.background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}

/* Buttons (common) */
.switches {
  position: absolute;
  left: 0;
  width: 100%;
  z-index: 100;
  display: flex;
}

.switch {
  --btn-color: #ddd;
  background: none;
  padding: 0;
  margin: 10px;
  width: 0;
  height: 0;
  border-style: solid;
  opacity: 0.8;
  cursor: pointer;
}

.switch:hover {
  --btn-color: #fff;
}

.switch[data-lisn-page-state="current"],
.switch[data-lisn-page-state="disabled"] {
  --btn-color: #777;
  cursor: default;
  pointer-events: none;
}

/* Page select circles */
.switches[data-switches="select"] .switch {
  border-width: 7px;
  border-radius: 50%;
  border-color: var(--btn-color);
}

.switches[data-switches="select"] {
  bottom: 10px;
  justify-content: center;
  gap: 15px;
}

/* Prev/next arrows */
.demo[data-lisn-current-page-is-first-enabled="true"] [data-switch="prev"],
.demo[data-lisn-current-page-is-last-enabled="true"] [data-switch="next"] {
  visibility: hidden;
}

.switches[data-switches="prev-next"] {
  top: 45%;
  justify-content: space-between;
}

.switches[data-switches="prev-next"] .switch {
  border-width: 13px;
  border-color: transparent var(--btn-color);
}

.switch[data-switch="prev"] {
  border-left: none !important;
}

.switch[data-switch="next"] {
  border-right: none !important;
}

Edit on CodePen

document.addEventListener("DOMContentLoaded", () => {
  const pager = document.getElementById("demo");
  const pages = pager.querySelectorAll(".page");
  const switches = pager.querySelectorAll(".switch");
  const prevSwitch = pager.querySelector(".prev-switch");
  const nextSwitch = pager.querySelector(".next-switch");
  new LISN.widgets.Pager(pager, {
    pages,
    switches,
    prevSwitch,
    nextSwitch,
    horizontal: true,
    parallax: true,
    useGestures: false,
  });
});
<div id="demo">
  <div class="buttons prev-next-buttons">
    <button class="prev-switch" aria-label="Previous"></button>
    <button class="next-switch" aria-label="Next"></button>
  </div>

  <div class="buttons page-select-buttons">
    <button class="switch" aria-label="Page 1"></button>
    <button class="switch" aria-label="Page 2"></button>
    <button class="switch" aria-label="Page 3"></button>
    <button class="switch" aria-label="Page 4"></button>
  </div>

  <div class="pages">
    <div class="page">
      <!-- https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 -->
      <img class="background" src="images/abstract-1.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 -->
      <img class="background" src="images/abstract-2.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM -->
      <img class="background" src="images/abstract-3.jpg" alt="" />
    </div>

    <div class="page">
      <!-- https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ -->
      <img class="background" src="images/abstract-4.jpg" alt="" />
    </div>
  </div>
</div>
/* Pager and pages */
#demo {
  width: 800px;
  max-width: 100%;
  box-shadow: var(--lisn-shadow);
  position: relative;
}

#demo .pages {
  height: 400px;
  max-height: 100%;
}

#demo,
#demo .page .background {
  border-radius: 15px;
}

#demo .page .background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}

/* Buttons (common) */
#demo .buttons {
  position: absolute;
  left: 0;
  width: 100%;
  z-index: 100;
  display: flex;
}

#demo .buttons button {
  --btn-color: #ddd;
  background: none;
  padding: 0;
  margin: 10px;
  width: 0;
  height: 0;
  border-style: solid;
  opacity: 0.8;
  cursor: pointer;
}

#demo .buttons button:hover {
  --btn-color: #fff;
}

/* Switch circles */
#demo .buttons .switch[data-lisn-page-state="current"],
#demo .buttons .switch[data-lisn-page-state="disabled"] {
  --btn-color: #777;
  cursor: default;
  pointer-events: none;
}

#demo .page-select-buttons button {
  border-width: 7px;
  border-radius: 50%;
  border-color: var(--btn-color);
}

#demo .page-select-buttons {
  bottom: 10px;
  justify-content: center;
  gap: 15px;
}

/* Prev/next arrows */
#demo[data-lisn-current-page-is-first-enabled="true"] .prev-switch,
#demo[data-lisn-current-page-is-last-enabled="true"] .next-switch {
  visibility: hidden;
}

#demo .prev-next-buttons {
  top: 45%;
  justify-content: space-between;
}

#demo .prev-next-buttons button {
  border-width: 13px;
  border-color: transparent var(--btn-color);
}

#demo .prev-switch {
  border-left: none !important;
}

#demo .next-switch {
  border-right: none !important;
}

Edit on CodePen

<div
  id="demo"
  data-lisn-pager="horizontal | parallax | use-gestures=false"
>
  <div class="buttons prev-next-buttons">
    <button data-lisn-pager-prev-switch aria-label="Previous"></button>
    <button data-lisn-pager-next-switch aria-label="Next"></button>
  </div>

  <div class="buttons page-select-buttons">
    <button data-lisn-pager-switch aria-label="Page 1"></button>
    <button data-lisn-pager-switch aria-label="Page 2"></button>
    <button data-lisn-pager-switch aria-label="Page 3"></button>
    <button data-lisn-pager-switch aria-label="Page 4"></button>
  </div>

  <div class="pages">
    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-close-up-of-a-red-and-black-substance-OOFSqPWjCt0 -->
      <img class="background" src="images/abstract-1.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-very-long-line-of-yellow-lines-on-a-black-background-YeUVDKZWSZ4 -->
      <img class="background" src="images/abstract-2.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/purple-black-and-orange-abstract-paintin-arwTpnIUHdM -->
      <img class="background" src="images/abstract-3.jpg" alt="" />
    </div>

    <div data-lisn-pager-page>
      <!-- https://unsplash.com/photos/a-purple-and-green-abstract-background-with-lots-of-lines-pEgsWN0kwbQ -->
      <img class="background" src="images/abstract-4.jpg" alt="" />
    </div>
  </div>
</div>
/* Pager and pages */
#demo {
  width: 800px;
  max-width: 100%;
  box-shadow: var(--lisn-shadow);
  position: relative;
}

#demo .pages {
  height: 400px;
  max-height: 100%;
}

#demo,
#demo [data-lisn-pager-page] .background {
  border-radius: 15px;
}

#demo [data-lisn-pager-page] .background {
  pointer-events: none;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  overflow-clip-margin: unset;
}

/* Buttons (common) */
#demo .buttons {
  position: absolute;
  left: 0;
  width: 100%;
  z-index: 100;
  display: flex;
}

#demo .buttons button {
  --btn-color: #ddd;
  background: none;
  padding: 0;
  margin: 10px;
  width: 0;
  height: 0;
  border-style: solid;
  opacity: 0.8;
  cursor: pointer;
}

#demo .buttons button:hover {
  --btn-color: #fff;
}

/* Switch circles */
#demo .buttons [data-lisn-pager-switch][data-lisn-page-state="current"],
#demo .buttons [data-lisn-pager-switch][data-lisn-page-state="disabled"] {
  --btn-color: #777;
  cursor: default;
  pointer-events: none;
}

#demo .page-select-buttons button {
  border-width: 7px;
  border-radius: 50%;
  border-color: var(--btn-color);
}

#demo .page-select-buttons {
  bottom: 10px;
  justify-content: center;
  gap: 15px;
}

/* Prev/next arrows */
#demo[data-lisn-current-page-is-first-enabled="true"]
  [data-lisn-pager-prev-switch],
#demo[data-lisn-current-page-is-last-enabled="true"]
  [data-lisn-pager-next-switch] {
  visibility: hidden;
}

#demo .prev-next-buttons {
  top: 45%;
  justify-content: space-between;
}

#demo .prev-next-buttons button {
  border-width: 13px;
  border-color: transparent var(--btn-color);
}

#demo [data-lisn-pager-prev-switch] {
  border-left: none !important;
}

#demo [data-lisn-pager-next-switch] {
  border-right: none !important;
}