<div class="header pt-5 flex items-center">
  <div class="flex-1 flex justify-around">
    <div>Our Products</div>
    <div>Process</div>
    <div>Our story</div>
  </div>
  <img src="https://assets.codepen.io/3685267/jack-daniels-logo.svg" alt="" class="h-full" />
  <div class="flex-1 flex justify-around">
    <div>Recipies</div>
    <div>Process</div>
    <div>Our Story</div>
  </div>
</div>
<div id="app" class="app h-screen w-screen">
  <div class="back-text">
    <div class="relative w-full h-full">
      <div class="absolute flex items-center justify-center inset-0">
        <div v-for="cls in clsStatic" :key="cls" :class="['back-text-actual', 'absolute', 'uppercase', `back-text-actual-${cls}`]" v-html="items[cls].name.join(' ')"></div>
      </div>
    </div>
  </div>

  <div class="bottle-name-container">
    <div class="relative w-full h-full">
      <div v-for="cls in clsStatic" :key="cls" :class="['bottle-name', 'font-bold', `bottle-name-${cls}`, 'absolute', 'uppercase']" v-html="items[cls].name.join('<br>')"></div>
    </div>
  </div>

  <div v-for="cls in clsStatic" :key="cls" :class="['bottle', `bottle-${cls}`]">
    <img class="h-full" :src="items[cls].bottleImage" alt="..." />
  </div>

  <div v-for="cls in clsStatic" :key="cls" :class="['description-container', `description-container-${cls}`]">
    <div class="description-title font-bold uppercase">
      {{items[cls].title[0]}}
    </div>
    <div class="description-title font-bold uppercase">
      {{items[cls].title[1]}}
    </div>
    <div class="description">{{items[cls].description}}</div>
    <button class="btn-read-more">Read more</button>
    <div class="video-container">
      <img class="w-full" :src="items[cls].video" alt="..." />
    </div>
  </div>

  <div class="nav-container flex items-center">
    <button class="arrow p-2">
      <img class="h-full" src="https://assets.codepen.io/3685267/jack-daniels-arow-left.svg" alt="prv" />
    </button>
    <button v-for="(item, index) in bucket" :key="item.id" class="pg-container flex items-center justify-center" :class="[index === bucket[0].id ? 'pg-container-active': '']">
      <div class="page"></div>
    </button>
    <button class="arrow p-2">
      <img class="h-full" src="https://assets.codepen.io/3685267/jack-daniels-arow-right.svg" alt="nxt" />
    </button>
  </div>
</div>
@import url("https://fonts.googleapis.com/css2?family=Libre+Baskerville:ital,wght@0,400;0,700;1,400&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap");

body {
  background: #131313;
  color: white;
  font-family: "Poppins", sans-serif;
  height: 100vh;
  overflow: hidden;
}

.header {
  height: 100px;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
}

.back-text {
  position: absolute;
  width: 50vw;
  top: 0;
  bottom: 0;
  left: 50%;
  transform: translate(-50%, 0);
  border-left: 1px solid #1c1c1c;
  border-right: 1px solid #1c1c1c;
}

.back-text-actual {
  color: #1c1c1c;
  font-size: 10vw;
  font-weight: bold;
  white-space: nowrap;
  transform: rotate(-90deg) scale(1, 2.5);
  -webkit-transform: rotate(-90deg) scale(1, 2.5);
  -moz-transform: rotate(-90deg) scale(1, 2.5);
  -ms-transform: rotate(-90deg) scale(1, 2.5);
  -o-transform: rotate(-90deg) scale(1, 2.5);
  font-family: "Libre Baskerville", serif;
}

.bottle {
  position: absolute;
  bottom: -33vh;
  left: 20vw;
  height: 120vh;
}

.bottle-name-container {
  position: absolute;
  left: 5vw;
  top: 40vh;
  overflow: hidden;
  width: 30vw;
  height: 30vh;
}
.nav-container {
  position: absolute;
  left: 5vw;
  bottom: 5vh;
}
.description-container {
  position: absolute;
  right: 10vw;
  width: 30vw;
  top: 30vh;
}

.bottle-name {
  color: #cfc357;
  font-family: "Libre Baskerville", serif;
  font-size: 4vw;
}

.description-title {
  font-size: 2.2vw;
}
.description {
  margin-top: 2rem;
  font-size: 0.8vw;
}
.btn-read-more {
  padding: 1rem;
  text-align: center;
  width: 10vw;
  border: 1px solid #cfc357;
  margin-top: 1rem;
  font-size: 0.8vw;
}
.video-container {
  margin-top: 3rem;
  width: 20vw;
  margin-left: 10vw;
}

.arrow {
  width: 40px;
  height: 40px;
  border: 2px solid #1c1c1c;
  border-radius: 100%;
  margin-right: 1rem;
  margin-left: 1rem;
}

.pg-container {
  width: 16px;
  height: 16px;
  border-radius: 100%;
  margin-right: 0.4rem;
}
.page {
  width: 6px;
  height: 6px;
  border-radius: 100%;
  background-color: #444343;
}

.pg-container-active {
  border: 1px solid #cfc357;
}
/*
 * Nikolay Bondar's Dribble shot
 * https://dribbble.com/shots/11746571-Jack-Daniels
 */

const initialItems = [
  {
    id: 0,
    bottleImage: "https://assets.codepen.io/3685267/jack-daniels-b1.png",
    name: ["Old No. 7"],
    title: ["charcoal mellowed.", "drop by drop"],
    description: `Mellowed drop by drop through 10-feet of sugar maple charcol, then matured in handcrafted barrels of our own making, And our Tennesse Whiskey doesn't follow a calendar. It's only ready when our tasters say it is`,
    video: "https://assets.codepen.io/3685267/jack-daniels-v1.jpg"
  },
  {
    id: 1,
    bottleImage: "https://assets.codepen.io/3685267/jack-daniels-b2.png",
    name: ["tennessee", "rye"],
    title: ["rye whiskey.", "jack's way."],
    description: `Introducing rye whiskey made Jack's way. Crafted with ouur 70-precent rye grain bill, natural spring water from our own Cave Spring Hollow, and Jack's time-honored charcoal mellowing process, Jack Daniel's Tennessee Rye is a whiskey that could only come from Lynchburg, Tennessee.`,
    video: "https://assets.codepen.io/3685267/jack-daniels-v2.jpg"
  },
  {
    id: 2,
    bottleImage: "https://assets.codepen.io/3685267/jack-daniels-b3.png",
    name: ["tennessee", "fire"],
    title: ["warm cinnamon.", "exceptionally smooth."],
    description: `Sometimes, mixing fire and whiskey is a good thing. Our Tennessee Fire blends warm cinnamon liqueur with the bold character of Jack Daniel's Old No. 7 for a classic spirit with a surprisingly smooth finish`,
    video: "https://assets.codepen.io/3685267/jack-daniels-v3.jpg"
  }
];

var app = new Vue({
  el: "#app",
  data: {
    clsStatic: ["a", "b"],
    clsArray: ["a", "b"],
    bucket: initialItems,
    items: {
      a: initialItems[initialItems.length - 2],
      b: initialItems[initialItems.length - 1]
    }
  },
  methods: {
    tick: function () {
      const [a, b] = this.clsArray;
      const tl = gsap.timeline({
        onComplete: () => {
          const [first, ...rest] = this.bucket;
          this.items[a] = first;
          this.bucket = [...rest, first];
          this.clsArray = [b, a];
          this.tick();
        }
      });
      tl.to(`.bottle-name-${a}`, { x: "-100vw", duration: 2 });
      tl.to(`.bottle-name-${a}`, { x: "100vw", duration: 0 });
      tl.to(`.bottle-name-${b}`, { x: "0vw", duration: 2 }, 0);

      tl.to(
        `.description-container-${a}`,
        { x: "-10vw", duration: 1, opacity: 0 },
        0
      );
      tl.to(`.description-container-${a}`, { x: "10vw", duration: 0 });
      tl.to(
        `.description-container-${b}`,
        { x: "0vw", duration: 1, opacity: 1 },
        1
      );

      tl.to(`.back-text-actual-${a}`, { y: "200vh", duration: 2 }, 0);
      tl.to(`.back-text-actual-${a}`, { y: "-200vh", duration: 0 });
      tl.to(`.back-text-actual-${b}`, { y: "0vh", duration: 2 }, 0);

      tl.to(
        `.bottle-${a}`,
        { rotation: "-=180", duration: 2, transformOrigin: "50% bottom" },
        0
      );
      tl.to(
        `.bottle-${b}`,
        { rotation: "-=180", duration: 2, transformOrigin: "50% bottom" },
        0
      );
      tl.set({}, {}, "+=1");
    }
  },
  mounted: function () {
    gsap.to(".bottle-name-b", { x: "100vw", duration: 0 });
    gsap.to(".description-container-b", { x: "10vw", duration: 0, opacity: 0 });
    gsap.to(".back-text-actual-b", { y: "-200vh", duration: 0 });
    gsap.to(".bottle-b", {
      rotation: 195,
      duration: 0,
      transformOrigin: "50% bottom"
    });
    gsap.to(".bottle-a", {
      rotation: 15,
      duration: 0,
      transformOrigin: "50% bottom"
    });

    gsap.to({}, { duration: 1.5, onComplete: this.tick });
  }
});

External CSS

  1. https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/1.4.6/tailwind.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.6/gsap.min.js
  2. https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.min.js