Creative Portfolio Showcase Slider

Creative and innovative portfolio showcase list item slider design.




The creative design of your portfolio page emphasis your creative work. In this post, we will design the work/project portfolio page using HTML, CSS, JS, and Anime.js javascript engine to animate the elements.

Elements to Design and Animate

We’ll focus on several key elements for this portfolio page:

Steps

  1. Design the Portfolio Layout: Begin by creating a basic HTML structure with a placeholder for your portfolio slider.
  2. Slider Animation: Implement a slider animation that smoothly transitions between project slides.
  3. Animate Texts: Apply animations to the project title, subtitle, and navigation elements for an engaging user experience.
  4. SVG Background Animation: Add an SVG background shape with dynamic gradient colors that change with each slide.
  5. Source Code: Combine all the HTML, CSS, and JavaScript code to create the complete portfolio page.

Design Portfolio Layout

Let’s start by creating a basic HTML layout for your portfolio page. HTML Markup

<div class="portfolio">
  <div class="portfolio-content" style="--bg: cornsilk" id="portfolio">
    <!-- Portfolio Slider -->
  </div>
</div>

In the above code snippet, we’ve our core layout. The style=“—bg: #colorcode” atribute will used to paint the background color dynamically.

Add CSS to root div.

* .portfolio {
  background: var(--bg);
}

CSS

.portfolio {
  transition: all 1.5s;
  background: var(--bg);
}
.portfolio-content {
  position: relative;
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow-x: hidden;
  transition: all 1.5s;
  z-index: 1;
}

Portfolio Slider

Now, let’s structure the portfolio slider section with its content. HTML Structure

<div class="portfolio" style="--bg: cornsilk" id="portfolio">
  . .
  <div
    class="portfolio-item"
    dd-slide="1"
    dd-background="cornsilk"
    dd-gradient='{ "c1": "#ff830066", "c2": "#9400D366" }'
  >
    <!-- Slider Content -->
  </div>
  . .
</div>

In the above code snippet, we’ve designed each slider item with its content.

The dd-slide=“slide_number” attribute will used to animate the next & privious slide from the current slide number.

The dd-background=“#color” attribute will used to update the portfolio background color.

The dd-gradient=“c1 & c2 color” attribute will used to paint the SVG background color.

All the attributes are used to update their perspective values dynamically to animate the slider.

Applying CSS

We’ll need to apply CSS styles to create the desired layout and animations.

CSS

.portfolio-item {
  position: absolute;
  display: flex;
  height: 50vh;
  min-height: var(--item-height);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  opacity: 0;
}
.portfolio-item.active {
  position: relative;
  opacity: 1;
  z-index: 9;
}

Slider Content and Animation

For the slider animation, we’ll structure the HTML content and define CSS animations. HTML Structure

<div
  class="portfolio-item"
  dd-slide="1"
  dd-background="cornsilk"
  dd-gradient='{ "c1": "#ff830066", "c2": "#9400D366" }'
>
  <h4 dd-split class="portfolio-subtitle dd-animate__subtitle">design & art</h4>
  <div class="clearfix"></div>
  <br />
  <h1 dd-split class="portfolio-title dd-animate__title">
    Artisan<br />Craft & Design
  </h1>
  <div class="clearfix"></div>
  <br />
  <a href="javascript: void(0)" class="portfolio-btn dd-animate"
    ><svg
      xmlns="http://www.w3.org/2000/svg"
      class="icon icon-tabler icon-tabler-arrow-narrow-right"
      width="44"
      height="44"
      viewBox="0 0 24 24"
      stroke-width="1"
      stroke="#000"
      fill="none"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <line x1="5" y1="12" x2="19" y2="12" />
      <line x1="15" y1="16" x2="19" y2="12" />
      <line x1="15" y1="8" x2="19" y2="12" /></svg
    ><span dd-split class="portfolio-btn__text dd-animate__span"
      >Explore</span
    ></a
  >
</div>

CSS & Animation

/*Project title*/
.portfolio-title {
  position: relative;
  margin: 0;
  font-family: var(--font);
  font-weight: 500;
  color: var(--clr-dark);
  letter-spacing: 1px;
  font-size: 7rem;
}
/* Project subtitle */
.portfolio-subtitle {
  position: absolute;
  display: inline-block;
  top: -50px;
  font-family: var(--font);
  font-weight: 400;
  font-size: 1.5rem;
}
.portfolio-btn {
  position: absolute;
  cursor: pointer;
  padding: 0;
  background: transparent;
  border: 0;
  bottom: -50px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  font-family: var(--font);
  font-weight: 600;
  color: var(--clr-dark);
  font-size: 1rem;
  outline: none;
  transform: translateX(-1.5rem);
  opacity: 0;
  transition: all 1s;
}

Animation CSS

/* Animations */
/* Project title animation */
.dd-animate__title span {
  opacity: 0;
  display: inline-block;
  transform: translateY(2.5rem) scale(0.75);
}
.portfolio-item.active .dd-animate__title span {
  transition: var(--transition);
  transition-delay: var(--delay);
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* Project subtitle animation */
.dd-animate__subtitle span {
  display: inline-block;
  transform: translateX(20px);
  transition: var(--transition);
  transition-delay: var(--delay) !important;
  opacity: 0;
}
.portfolio-item.active .dd-animate__subtitle span {
  transform: translateX(0);
  opacity: 1;
}
/* Project subtitle underline */
.dd-animate__subtitle::after {
  position: absolute;
  content: "";
  top: calc(50% + 4px);
  left: 0;
  width: 0;
  height: 2px;
  background: var(--clr-dark);
  transform-origin: right;
  transition-delay: 0.75s !important;
  transition: all 1s;
}
/* Project subtitle underline animation */
.portfolio-item.active .dd-animate__subtitle::after {
  width: 100px;
  left: -120px;
}
/* Char / letters hover animation */
.dd-animate__span span {
  position: relative;
  display: inline-block;
  transform: translateY(5px) scale(0.75);
  transition: all 0.75s;
  opacity: 0;
  transition-delay: var(--delay);
  letter-spacing: 2px;
}
/* Explore btn hover animation */
.dd-animate:hover .dd-animate__span span {
  opacity: 1;
  transform: translateY(0) scale(1);
}

Letter / Character Animation

For the leeter/char animation we have to first split the string into char list. The below js function will split the string and add the required attributes.

let item_list = document.querySelectorAll(".portfolio-item");
// Total items
let total_item = item_list.length;
// Fetch all animated texts
let dd_splits = document.querySelectorAll("[dd-split]");
// Split and animate every letters
dd_splits.forEach((str) => {
  let span = "";
  // split string into chars
  let chars = str.innerText.split("");
  let reverse = false;
  let default_delay = 0.075;
  let default_duration = 1;
  // Duration: check if durations is set or not (if not then set the default value)
  let duration = str.attributes["dd-duration"]
    ? str.attributes["dd-duration"].value.toFixed(2)
    : default_duration;
  // Delay: check if delay is set or not (if not then set the default value)
  let delay = str.attributes["dd-delay"]
    ? str.attributes["dd-delay"].value.toFixed(2)
    : default_delay;
  // Delay between two transition
  let transition_delay = 0;
  // Total length
  let char_len = chars.length;
  // If transition is reverse
  if (str.attributes["dd-delay-reverse"]) {
    reverse = true;
    transition_delay = char_len / 10;
  } else reverse = false;
  // Create span node, set transition & delay attributes dynamically and append it to span var
  chars.forEach((ch, key) => {
    if (ch == "\n") {
      span += '<div class="clearfix"></div>';
    } else if (ch == " ") {
      span += " ";
    } else {
      span +=
        '<span style="--delay: ' +
        transition_delay +
        's" dd-char="' +
        ch +
        '">' +
        ch +
        "</span>";
    }
    str.style = "--transition: " + duration + "s";
    if (reverse) transition_delay = transition_delay - default_delay;
    else transition_delay += Number(delay);
  });
  // Replace the text content with converted span
  str.innerHTML = span;
});

Slider & Background SVG Shapes

After creating the content we will add the previous & next arrows to animate the slide. HTML structure

<div class="portfolio-nav prev" id="prev" dd-slide>
  <svg
    xmlns="http://www.w3.org/2000/svg"
    class="icon icon-tabler icon-tabler-arrow-left"
    width="38"
    height="38"
    viewBox="0 0 24 24"
    stroke-width="1"
    stroke="#000000"
    fill="none"
    stroke-linecap="round"
    stroke-linejoin="round"
  >
    <path stroke="none" d="M0 0h24v24H0z" fill="none" />
    <line x1="5" y1="12" x2="19" y2="12" />
    <line x1="5" y1="12" x2="11" y2="18" />
    <line x1="5" y1="12" x2="11" y2="6" />
  </svg>
  <span dd-split>Prev</span>
</div>

CSS

.portfolio-nav {
  position: absolute;
  display: inline-flex;
  align-items: center;
  font-family: var(--font);
  font-weight: 500;
  font-size: 1.5rem;
  transition: all 0.5s;
  cursor: pointer;
  top: 50%;
  transform: translateY(-50%);
  z-index: 9;
}
.portfolio-nav.prev {
  left: 100px;
}
.portfolio-nav.next {
  right: 100px;
}

Background SVG Shape

HTML Structure

<div class="portfolio-content">
  <!-- Background Animated Shape -->
  <svg
    class="background-shape"
    viewBox="0 0 100 100"
    fill="none"
    xmlns="http://www.w3.org/2000/svg"
  >
    <!-- Background gradient -->
    <linearGradient id="gradient1" x1="0" x2="0" y1="0" y2="1">
      <stop id="stop1" offset="0%" stop-color="#ff830066" />
      <stop id="stop2" offset="100%" stop-color="#9400D366" />
    </linearGradient>
    <path
      id="svg_path"
      fill-rule="evenodd"
      clip-rule="evenodd"
      d="M52.5616 1.05626C64.6583 0.513218 78.5175 -2.5156 87.7611 5.03785C96.9478 12.5447 95.4872 26.2692 97.4469 37.7343C99.0839 47.3122 101.849 57.0875 98.2039 66.1344C94.6629 74.9234 85.85 80.0148 78.0998 85.7542C70.1123 91.6693 62.6066 99.3013 52.5616 99.9349C42.2547 100.585 31.64 96.3227 24.4782 89.1365C17.8244 82.46 19.8838 71.7615 16.0282 63.2768C11.4887 53.2869 -0.686653 46.2228 0.0303648 35.3356C0.775686 24.0187 9.93179 14.4447 19.6625 8.09493C29.2022 1.86977 41.0599 1.5726 52.5616 1.05626Z"
      fill="url(#gradient1)"
    />
  </svg>
  . .
</div>

CSS

/* Background SVG Shape */
.background-shape {
  position: absolute;
  width: var(--svg-shape-width);
  height: var(--svg-shape-height);
  z-index: -1;
}

Next, we will add the javascript event to animate the slider.

Slider(next/prev) Javascript Event & Bg Shape Animation

let slide_number;
// Next slide
next.addEventListener("click", function () {
  slide_number = current_slide == total_item ? 1 : current_slide + 1;
  // Update slide
  updateSlide(slide_number);
  // Update svg background color
  updateSvgBackground(slide_number);
});
// Previous slide
prev.addEventListener("click", function () {
  slide_number = current_slide == 1 ? total_item : current_slide - 1;
  // Update slide
  updateSlide(slide_number);
  // Update svg background color
  updateSvgBackground(slide_number);
});

// Animate svg shape
function updateSlide(slide_number) {
  // SVG path set(array list)
  const paths = [
    "M52.5616 1.05626C64.6583 0.513218 78.5175 -2.5156 87.7611 5.03785C96.9478 12.5447 95.4872 26.2692 97.4469 37.7343C99.0839 47.3122 101.849 57.0875 98.2039 66.1344C94.6629 74.9234 85.85 80.0148 78.0998 85.7542C70.1123 91.6693 62.6066 99.3013 52.5616 99.9349C42.2547 100.585 31.64 96.3227 24.4782 89.1365C17.8244 82.46 19.8838 71.7615 16.0282 63.2768C11.4887 53.2869 -0.686653 46.2228 0.0303648 35.3356C0.775686 24.0187 9.93179 14.4447 19.6625 8.09493C29.2022 1.86977 41.0599 1.5726 52.5616 1.05626Z",
    "M47.6845 0.820792C57.8312 2.21574 65.9096 9.5486 74.5227 15.7811C83.7903 22.4873 97.4811 26.2741 99.7139 38.4698C101.975 50.8225 90.2594 60.3113 84.6735 71.226C80.4944 79.3917 78.0658 88.9225 71.1758 94.2321C64.3994 99.4543 55.8437 100.615 47.6845 99.7309C40.0806 98.9069 34.1505 93.1749 27.2472 89.4716C18.235 84.637 5.34967 84.9763 1.1178 74.7503C-3.06639 64.6394 5.67406 53.8657 8.02464 43.0215C10.6411 30.9508 7.65585 16.1987 15.6542 7.68797C23.7721 -0.950018 36.6267 -0.699423 47.6845 0.820792Z",
    "M49.8483 0.603104C57.7254 1.34548 64.7302 4.5352 72.0188 7.92353C81.8333 12.4861 96.9533 12.3867 99.6864 23.772C102.468 35.3619 85.905 42.058 82.9848 53.6062C79.8306 66.0801 89.8659 81.3935 82.5574 91.5114C75.4119 101.404 61.2672 100.322 49.8483 99.4802C39.0108 98.6811 28.8724 94.0877 20.1597 86.9108C11.5294 79.8017 3.73608 70.769 1.01119 59.2515C-1.63467 48.068 1.25521 36.2787 5.70651 25.8202C9.74851 16.3234 16.3239 8.28436 24.7531 3.46895C32.4131 -0.906989 41.2589 -0.206403 49.8483 0.603104Z",
    "M50.3391 0.0424737C61.472 0.903899 63.5849 15.9442 72.3722 22.3011C80.6051 28.2569 96.019 26.4284 99.4213 35.5492C102.811 44.6355 90.3541 52.1243 86.8758 61.182C83.5399 69.8686 86.1043 80.3301 79.5514 87.2906C72.3191 94.9726 61.3726 99.7318 50.3391 99.9908C39.1686 100.253 28.96 94.8708 20.0251 88.6879C11.2105 82.5883 1.67897 75.3267 0.158963 65.2666C-1.30862 55.5534 7.74548 47.6883 12.5051 38.9167C16.4015 31.7358 19.6256 24.6469 25.4428 18.6699C32.7589 11.1526 39.4192 -0.802475 50.3391 0.0424737Z",
  ];
  // SVG Shape animation using Anime js.
  let timeline = anime({
    duration: 1250,
    targets: "#svg_path",
    d: [
      {
        value: paths[slide_number - 1],
      },
    ],
    easing: "easeOutCubic",
  });
  // Fetch current slide from slide_number
  let current_item = document.querySelector(
    '[dd-slide="' + slide_number + '"]'
  );
  item_list.forEach((i) => {
    // Reset default activated slide
    i.classList.remove("active");
    // Activate the current slide
    current_item.classList.add("active");
  });
  current_slide = slide_number;
}
// Animate svg shape color(gradient)
function updateSvgBackground(slide_number) {
  let item = document.querySelector('[dd-slide="' + slide_number + '"]');
  let bg_value = item.attributes["dd-background"].value;
  portfolio.attributes["style"].value = "--bg: " + bg_value;
  let gradient_set = item.attributes["dd-gradient"].value;
  let color1 = JSON.parse(gradient_set).c1;
  let color2 = JSON.parse(gradient_set).c2;
  stop1.attributes["stop-color"].value = color1;
  stop2.attributes["stop-color"].value = color2;
}

The slider is accessible via arrow keys.

Add the below code to actiavte the key navigation

// Arrow key(left & right arrow) function to animate the slider.
document.onkeydown = (e) => {
  if (e.keyCode == 37) prev.click();
  else if (e.keyCode == 39) next.click();
};

Now call the init() funtion to initialize the first slide.

// Init function
function init() {
  // Select item 1
  let item_1 = document.querySelector('[dd-slide="1"]');
  item_1.classList.add("active");
}
// Init
document.onload = init();

Let’s combine all the snippets together =>

Source Code

HTML

<div class="portfolio" style="--bg: cornsilk" id="portfolio">
  <!-- Portfolio Slider -->
  <div class="portfolio-content">
    <!-- Background Animated Shape -->
    <svg
      class="background-shape"
      viewBox="0 0 100 100"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <!-- Background gradient -->
      <linearGradient id="gradient1" x1="0" x2="0" y1="0" y2="1">
        <stop id="stop1" offset="0%" stop-color="#ff830066" />
        <stop id="stop2" offset="100%" stop-color="#9400D366" />
      </linearGradient>
      <path
        id="svg_path"
        fill-rule="evenodd"
        clip-rule="evenodd"
        d="M52.5616 1.05626C64.6583 0.513218 78.5175 -2.5156 87.7611 5.03785C96.9478 12.5447 95.4872 26.2692 97.4469 37.7343C99.0839 47.3122 101.849 57.0875 98.2039 66.1344C94.6629 74.9234 85.85 80.0148 78.0998 85.7542C70.1123 91.6693 62.6066 99.3013 52.5616 99.9349C42.2547 100.585 31.64 96.3227 24.4782 89.1365C17.8244 82.46 19.8838 71.7615 16.0282 63.2768C11.4887 53.2869 -0.686653 46.2228 0.0303648 35.3356C0.775686 24.0187 9.93179 14.4447 19.6625 8.09493C29.2022 1.86977 41.0599 1.5726 52.5616 1.05626Z"
        fill="url(#gradient1)"
      />
    </svg>
    <!-- Slide 1 -->
    <div
      class="portfolio-item"
      dd-slide="1"
      dd-background="cornsilk"
      dd-gradient='{ "c1": "#ff830066", "c2": "#9400D366" }'
    >
      <h4 dd-split class="portfolio-subtitle dd-animate__subtitle">
        design & art
      </h4>
      <div class="clearfix"></div>
      <br />
      <h1 dd-split class="portfolio-title dd-animate__title">
        Artisan<br />Craft & Design
      </h1>
      <div class="clearfix"></div>
      <br />
      <a href="javascript: void(0)" class="portfolio-btn dd-animate"
        ><svg
          xmlns="http://www.w3.org/2000/svg"
          class="icon icon-tabler icon-tabler-arrow-narrow-right"
          width="44"
          height="44"
          viewBox="0 0 24 24"
          stroke-width="1"
          stroke="#000"
          fill="none"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <path stroke="none" d="M0 0h24v24H0z" fill="none" />
          <line x1="5" y1="12" x2="19" y2="12" />
          <line x1="15" y1="16" x2="19" y2="12" />
          <line x1="15" y1="8" x2="19" y2="12" /></svg
        ><span dd-split class="portfolio-btn__text dd-animate__span"
          >Explore</span
        ></a
      >
    </div>
    <!-- Slide 2 -->
    <div
      class="portfolio-item"
      dd-slide="2"
      dd-background="#ffc0cb99"
      dd-gradient='{"c1": "#537AE366", "c2": "#2F817966"}'
    >
      <h4 dd-split class="portfolio-subtitle dd-animate__subtitle">
        graphics & illustration
      </h4>
      <div class="clearfix"></div>
      <h1 dd-split class="portfolio-title dd-animate__title">
        Abc<br />Sports
      </h1>
      <a href="javascript: void(0)" class="portfolio-btn dd-animate"
        ><svg
          xmlns="http://www.w3.org/2000/svg"
          class="icon icon-tabler icon-tabler-arrow-narrow-right"
          width="44"
          height="44"
          viewBox="0 0 24 24"
          stroke-width="1"
          stroke="#000"
          fill="none"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <path stroke="none" d="M0 0h24v24H0z" fill="none" />
          <line x1="5" y1="12" x2="19" y2="12" />
          <line x1="15" y1="16" x2="19" y2="12" />
          <line x1="15" y1="8" x2="19" y2="12" /></svg
        ><span dd-split class="portfolio-btn__text dd-animate__span"
          >Explore</span
        ></a
      >
    </div>
    <!-- Slide 3 -->
    <div
      class="portfolio-item"
      dd-slide="3"
      dd-background="#8BD3B922"
      dd-gradient='{"c1": "#F5AD1D66", "c2": "#21414466"}'
    >
      <h4 dd-split class="portfolio-subtitle dd-animate__subtitle">
        website & app
      </h4>
      <div class="clearfix"></div>
      <h1 dd-split class="portfolio-title dd-animate__title">
        Z Beauty<br />& Spa
      </h1>
      <a href="javascript: void(0)" class="portfolio-btn dd-animate"
        ><svg
          xmlns="http://www.w3.org/2000/svg"
          class="icon icon-tabler icon-tabler-arrow-narrow-right"
          width="44"
          height="44"
          viewBox="0 0 24 24"
          stroke-width="1"
          stroke="#000"
          fill="none"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <path stroke="none" d="M0 0h24v24H0z" fill="none" />
          <line x1="5" y1="12" x2="19" y2="12" />
          <line x1="15" y1="16" x2="19" y2="12" />
          <line x1="15" y1="8" x2="19" y2="12" /></svg
        ><span dd-split class="portfolio-btn__text dd-animate__span"
          >Explore</span
        ></a
      >
    </div>
    <!-- Slide 4 -->
    <div
      class="portfolio-item"
      dd-slide="4"
      dd-background="#8b000033"
      dd-gradient='{"c1": "#ed6ea0", "c2": "#ec8c69"}'
    >
      <h4 dd-split class="portfolio-subtitle dd-animate__subtitle">
        website design
      </h4>
      <div class="clearfix"></div>
      <h1 dd-split class="portfolio-title dd-animate__title">Admin Theme</h1>
      <a href="javascript: void(0)" class="portfolio-btn dd-animate"
        ><svg
          xmlns="http://www.w3.org/2000/svg"
          class="icon icon-tabler icon-tabler-arrow-narrow-right"
          width="44"
          height="44"
          viewBox="0 0 24 24"
          stroke-width="1"
          stroke="#000"
          fill="none"
          stroke-linecap="round"
          stroke-linejoin="round"
        >
          <path stroke="none" d="M0 0h24v24H0z" fill="none" />
          <line x1="5" y1="12" x2="19" y2="12" />
          <line x1="15" y1="16" x2="19" y2="12" />
          <line x1="15" y1="8" x2="19" y2="12" /></svg
        ><span dd-split class="portfolio-btn__text dd-animate__span"
          >Explore</span
        ></a
      >
    </div>
  </div>
  <!-- Slider Nav -->
  <!-- Btn:Previous -->
  <div class="portfolio-nav prev dd-animate" id="prev" dd-slide>
    <svg
      xmlns="http://www.w3.org/2000/svg"
      class="icon icon-tabler icon-tabler-arrow-left"
      width="38"
      height="38"
      viewBox="0 0 24 24"
      stroke-width="1"
      stroke="#000000"
      fill="none"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <line x1="5" y1="12" x2="19" y2="12" />
      <line x1="5" y1="12" x2="11" y2="18" />
      <line x1="5" y1="12" x2="11" y2="6" />
    </svg>
    <span class="dd-animate__span" dd-split>Prev</span>
  </div>
  <!-- Btn:Next -->
  <div class="portfolio-nav next dd-animate" id="next" dd-slide>
    <span class="dd-animate__span" dd-split dd-delay-reverse>Next</span>
    <svg
      xmlns="http://www.w3.org/2000/svg"
      class="icon icon-tabler icon-tabler-arrow-right"
      width="38"
      height="38"
      viewBox="0 0 24 24"
      stroke-width="1"
      stroke="#000000"
      fill="none"
      stroke-linecap="round"
      stroke-linejoin="round"
    >
      <path stroke="none" d="M0 0h24v24H0z" fill="none" />
      <line x1="5" y1="12" x2="19" y2="12" />
      <line x1="13" y1="18" x2="19" y2="12" />
      <line x1="13" y1="6" x2="19" y2="12" />
    </svg>
  </div>
</div>

CSS

/* CSS variables */
:root {
  --clr-dark: #121212;
  --bg: cornsilk;
  --font: "Playfair Display", serif;
  --item-height: 500px;
  --svg-shape-width: 400px;
  --svg-shape-height: 400px;
}
/* Reset default browser properties. */
body {
  margin: 0;
  padding: 0;
}
.clearfix::after {
  content: "";
  clear: both;
  display: table;
}
.portfolio {
  transition: all 1.5s;
  background: var(--bg);
}
.portfolio-content {
  position: relative;
  height: 100vh;
  width: 100vw;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  overflow-x: hidden;
  transition: all 1.5s;
  z-index: 1;
}
.portfolio-item {
  position: absolute;
  display: flex;
  height: 50vh;
  min-height: var(--item-height);
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  opacity: 0;
}
.portfolio-item.active {
  position: relative;
  opacity: 1;
  z-index: 9;
}
/*Project title*/
.portfolio-title {
  position: relative;
  margin: 0;
  font-family: var(--font);
  font-weight: 500;
  color: var(--clr-dark);
  letter-spacing: 1px;
  font-size: 7rem;
}
/* Project subtitle */
.portfolio-subtitle {
  position: absolute;
  display: inline-block;
  top: -50px;
  font-family: var(--font);
  font-weight: 400;
  font-size: 1.5rem;
}
/* Explore button */
.portfolio-btn {
  position: absolute;
  cursor: pointer;
  padding: 0;
  background: transparent;
  border: 0;
  bottom: -50px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  font-family: var(--font);
  font-weight: 600;
  color: var(--clr-dark);
  font-size: 1rem;
  outline: none;
  transform: translateX(-1.5rem);
  opacity: 0;
  transition: all 1s;
}
.portfolio-item.active .portfolio-btn {
  opacity: 1;
  transform: translateX(0);
}
/* Background SVG Shape */
.background-shape {
  position: absolute;
  width: var(--svg-shape-width);
  height: var(--svg-shape-height);
  z-index: -1;
}
/* Project slider nav */
/* Prev / Next */
.portfolio-nav {
  position: absolute;
  display: inline-flex;
  align-items: center;
  font-family: var(--font);
  font-weight: 500;
  font-size: 1.5rem;
  transition: all 0.5s;
  cursor: pointer;
  top: 50%;
  transform: translateY(-50%);
  z-index: 9;
}
.portfolio-nav.prev {
  left: 100px;
}
.portfolio-nav.next {
  right: 100px;
}
/* Animations */
/* Project title animation */
.dd-animate__title span {
  opacity: 0;
  display: inline-block;
  transform: translateY(2.5rem) scale(0.75);
}
.portfolio-item.active .dd-animate__title span {
  transition: var(--transition);
  transition-delay: var(--delay);
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* Project subtitle animation */
.dd-animate__subtitle span {
  display: inline-block;
  transform: translateX(20px);
  transition: var(--transition);
  transition-delay: var(--delay) !important;
  opacity: 0;
}
.portfolio-item.active .dd-animate__subtitle span {
  transform: translateX(0);
  opacity: 1;
}
/* Project subtitle underline */
.dd-animate__subtitle::after {
  position: absolute;
  content: "";
  top: calc(50% + 4px);
  left: 0;
  width: 0;
  height: 2px;
  background: var(--clr-dark);
  transform-origin: right;
  transition-delay: 0.75s !important;
  transition: all 1s;
}
/* Project subtitle underline animation */
.portfolio-item.active .dd-animate__subtitle::after {
  width: 100px;
  left: -120px;
}
/* Char / letters hover animation */
.dd-animate__span span {
  position: relative;
  display: inline-block;
  transform: translateY(5px) scale(0.75);
  transition: all 0.75s;
  opacity: 0;
  transition-delay: var(--delay);
  letter-spacing: 2px;
}
/* Explore btn hover animation */
.dd-animate:hover .dd-animate__span span {
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* Media query */
@media (max-width: 768px) {
  /* Project items */
  .portfolio-item {
    height: 70vh;
    min-height: auto;
  }
  .portfolio-title {
    font-size: 3rem;
  }
  /* SVG shape */
  .background-shape {
    width: 75%;
    height: auto;
  }
  /* Nav */
  .portfolio-nav {
    top: 100px;
  }
  .portfolio-nav.prev {
    left: 0;
  }
  .portfolio-nav.next {
    right: 0;
  }
}

Javascript

<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.min.js"></script>
<script>
  let current_slide = 1;
  // Fetch all itmes
  let item_list = document.querySelectorAll('.portfolio-item');
  // Total items
  let total_item = item_list.length;
  // Fetch all animated texts
  let dd_splits = document.querySelectorAll('[dd-split]');
  // Split and animate every letters
  dd_splits.forEach(str => {
    let span = '';
    // split string into chars
    let chars = str.innerText.split('');
    let reverse = false;
    let default_delay = .075;
    let default_duration = 1;
    // Duration: check if durations is set or not (if not then set the default value)
    let duration = str.attributes['dd-duration'] ? str.attributes['dd-duration'].value.toFixed(2) : default_duration;
    // Delay: check if delay is set or not (if not then set the default value)
    let delay = str.attributes['dd-delay'] ? str.attributes['dd-delay'].value.toFixed(2) : default_delay;
    // Delay between two transition
    let transition_delay = 0;
    // Total length
    let char_len = chars.length;
    // If transition is reverse
    if( str.attributes['dd-delay-reverse'] ) {
      reverse = true;
      transition_delay = char_len / 10;
    }
    else reverse = false;
    // Create span node, set transition & delay attributes dynamically and append it to span var
    chars.forEach((ch, key) => {
      if(ch == '\n' ) {
        span += '<div class="clearfix"></div>';
      } else if( ch == ' ' ) {
        span += ' ';
      } else {
        span += '<span style="--delay: '+transition_delay+'s" dd-char="'+(ch)+'">'+ch+'</span>';
      }
      str.style = '--transition: '+(duration)+'s';
      if( reverse ) transition_delay = transition_delay - default_delay;
      else transition_delay += Number(delay);
    })
    // Replace the text content with converted span
    str.innerHTML = span;
  });
  let slide_number;
  // Next slide
  next.addEventListener('click', function() {
    slide_number = ( current_slide == total_item ? 1 : current_slide + 1);
    // Update slide
    updateSlide(slide_number);
    // Update svg background color
    updateSvgBackground(slide_number);
  });
  // Previous slide
  prev.addEventListener('click', function() {
    slide_number = ( current_slide == 1 ? total_item : current_slide - 1);
    // Update slide
    updateSlide(slide_number);
    // Update svg background color
    updateSvgBackground(slide_number);
  });
  // Update & Animate svg shape
  function updateSlide(slide_number) {
    // SVG path set(array list)
    const paths = [
    'M52.5616 1.05626C64.6583 0.513218 78.5175 -2.5156 87.7611 5.03785C96.9478 12.5447 95.4872 26.2692 97.4469 37.7343C99.0839 47.3122 101.849 57.0875 98.2039 66.1344C94.6629 74.9234 85.85 80.0148 78.0998 85.7542C70.1123 91.6693 62.6066 99.3013 52.5616 99.9349C42.2547 100.585 31.64 96.3227 24.4782 89.1365C17.8244 82.46 19.8838 71.7615 16.0282 63.2768C11.4887 53.2869 -0.686653 46.2228 0.0303648 35.3356C0.775686 24.0187 9.93179 14.4447 19.6625 8.09493C29.2022 1.86977 41.0599 1.5726 52.5616 1.05626Z',
    'M47.6845 0.820792C57.8312 2.21574 65.9096 9.5486 74.5227 15.7811C83.7903 22.4873 97.4811 26.2741 99.7139 38.4698C101.975 50.8225 90.2594 60.3113 84.6735 71.226C80.4944 79.3917 78.0658 88.9225 71.1758 94.2321C64.3994 99.4543 55.8437 100.615 47.6845 99.7309C40.0806 98.9069 34.1505 93.1749 27.2472 89.4716C18.235 84.637 5.34967 84.9763 1.1178 74.7503C-3.06639 64.6394 5.67406 53.8657 8.02464 43.0215C10.6411 30.9508 7.65585 16.1987 15.6542 7.68797C23.7721 -0.950018 36.6267 -0.699423 47.6845 0.820792Z',
    'M49.8483 0.603104C57.7254 1.34548 64.7302 4.5352 72.0188 7.92353C81.8333 12.4861 96.9533 12.3867 99.6864 23.772C102.468 35.3619 85.905 42.058 82.9848 53.6062C79.8306 66.0801 89.8659 81.3935 82.5574 91.5114C75.4119 101.404 61.2672 100.322 49.8483 99.4802C39.0108 98.6811 28.8724 94.0877 20.1597 86.9108C11.5294 79.8017 3.73608 70.769 1.01119 59.2515C-1.63467 48.068 1.25521 36.2787 5.70651 25.8202C9.74851 16.3234 16.3239 8.28436 24.7531 3.46895C32.4131 -0.906989 41.2589 -0.206403 49.8483 0.603104Z',
    'M50.3391 0.0424737C61.472 0.903899 63.5849 15.9442 72.3722 22.3011C80.6051 28.2569 96.019 26.4284 99.4213 35.5492C102.811 44.6355 90.3541 52.1243 86.8758 61.182C83.5399 69.8686 86.1043 80.3301 79.5514 87.2906C72.3191 94.9726 61.3726 99.7318 50.3391 99.9908C39.1686 100.253 28.96 94.8708 20.0251 88.6879C11.2105 82.5883 1.67897 75.3267 0.158963 65.2666C-1.30862 55.5534 7.74548 47.6883 12.5051 38.9167C16.4015 31.7358 19.6256 24.6469 25.4428 18.6699C32.7589 11.1526 39.4192 -0.802475 50.3391 0.0424737Z'
    ];
    // Shape animation using Anime js.
    let timeline = anime({
      duration: 1250,
      targets: '#svg_path',
      d: [{
        value: paths[slide_number - 1]
      }],
      easing: 'easeOutCubic',
    });
    // Fetch current slide from slide_number
    let current_item = document.querySelector('[dd-slide="'+slide_number+'"]');
    item_list.forEach(i => {
      // Reset default activated slide
      i.classList.remove('active');
      // Activate the current slide
      current_item.classList.add('active');
    });
    current_slide = slide_number;
  }
  // Animate svg shape color
  function updateSvgBackground(slide_number) {
    let item = document.querySelector('[dd-slide="'+slide_number+'"]');
    let bg_value = item.attributes['dd-background'].value;
    portfolio.attributes['style'].value = '--bg: '+bg_value;
    let gradient_set = item.attributes['dd-gradient'].value;
    let color1 = JSON.parse(gradient_set).c1;
    let color2 = JSON.parse(gradient_set).c2;
    stop1.attributes['stop-color'].value = color1;
    stop2.attributes['stop-color'].value = color2;
  }
  // Arrow key(left & right arrow) function to animate the slider.
  document.onkeydown = e => {
    if(e.keyCode == 37) prev.click();
    else if(e.keyCode == 39) next.click();
  }
  // Init function
  function init() {
    // Select item 1
    let item_1 = document.querySelector('[dd-slide="1"]');
    item_1.classList.add('active');
  }
  // Init
  document.onload = init();
</script>

I trust you found value in the tutorial. Feel free to share them with others.