LumaSlide

Go down to see the code.

Technology

GPT-3

GPT-3BERTDALL·EAlphaGo
Action
Active
ActiveUsedEmergingInnovative
slider image 1slider image 2slider image 3slider image 4

PixelMorph Slider

Slider Documentation - React & HTML Code Implementation

Easily switch between different code implementations.

JSX
import React, { useEffect, useRef, useState } from 'react';
import imagesLoaded from 'imagesloaded';
import * as THREE from 'three';
import gsap from 'gsap';

const Slider1 = () => {
  const sliderRef = useRef(null); // DOM referansı
  const [isLoaded, setIsLoaded] = useState(false); // Yükleme durumu

  useEffect(() => {
    // Optimizasyon için imagesLoaded sadece bir kez çalışacak
    imagesLoaded(sliderRef.current.querySelectorAll('img'), () => {
      setIsLoaded(true); // Yükleme tamamlandığında state güncelleniyor
    });
  }, []);

  useEffect(() => {
    const displacementSlider = function (opts) {
      let vertex = `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
        }
      `;

      let fragment = `
        varying vec2 vUv;
        uniform sampler2D currentImage;
        uniform sampler2D nextImage;
        uniform float dispFactor;
        void main() {
          vec2 uv = vUv;
          vec4 _currentImage;
          vec4 _nextImage;
          float intensity = 0.3;
          vec4 orig1 = texture2D(currentImage, uv);
          vec4 orig2 = texture2D(nextImage, uv);
          _currentImage = texture2D(currentImage, vec2(uv.x, uv.y + dispFactor * (orig2 * intensity)));
          _nextImage = texture2D(nextImage, vec2(uv.x, uv.y + (1.0 - dispFactor) * (orig1 * intensity)));
          vec4 finalTexture = mix(_currentImage, _nextImage, dispFactor);
          gl_FragColor = finalTexture;
        }
      `;

      let images = opts.images, image, sliderImages = [];
      let canvasWidth = images[0].clientWidth;
      let canvasHeight = images[0].clientHeight;
      let parent = opts.parent;
      let renderWidth = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
      let renderHeight = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);

      let renderer = new THREE.WebGLRenderer({
        antialias: false,
      });

      renderer.setPixelRatio(window.devicePixelRatio);
      renderer.setClearColor(0x23272A, 1.0);
      renderer.setSize(renderWidth, renderHeight);
      parent.appendChild(renderer.domElement);

      let loader = new THREE.TextureLoader();
      loader.crossOrigin = 'anonymous';

      images.forEach((img) => {
        image = loader.load(img.getAttribute('src') + '?v=' + Date.now());
        image.magFilter = image.minFilter = THREE.LinearFilter;
        image.anisotropy = renderer.capabilities.getMaxAnisotropy();
        sliderImages.push(image);
      });

      let scene = new THREE.Scene();
      scene.background = new THREE.Color(0x000000);

      // Perspective Camera kullanımı
      let camera = new THREE.PerspectiveCamera(
        75, // Field of view (görüş açısı)
        renderWidth / renderHeight, // Aspect ratio
        0.1, // Near plane
        1000 // Far plane
      );

      camera.position.z = 500; // Kamera pozisyonu

      let mat = new THREE.ShaderMaterial({
        uniforms: {
          dispFactor: { type: 'f', value: 0.0 },
          currentImage: { type: 't', value: sliderImages[0] },
          nextImage: { type: 't', value: sliderImages[1] },
        },
        vertexShader: vertex,
        fragmentShader: fragment,
        transparent: true,
        opacity: 1.0,
      });

      let geometry = new THREE.PlaneGeometry(
        parent.offsetWidth,
        parent.offsetHeight,
        1
      );

      let object = new THREE.Mesh(geometry, mat);
      object.position.set(0, 0, 0);
      scene.add(object);

      let addEvents = function () {
        let pagButtons = Array.from(document.getElementById('pagination').querySelectorAll('button'));
        let isAnimating = false;

        pagButtons.forEach((el) => {
          el.addEventListener('click', function () {
            if (!isAnimating) {
              isAnimating = true;
              document.getElementById('pagination').querySelectorAll('.active')[0].className = '';
              this.className = 'active';
              let slideId = parseInt(this.dataset.slide, 10);
              mat.uniforms.nextImage.value = sliderImages[slideId];
              mat.uniforms.nextImage.needsUpdate = true;

              gsap.to(mat.uniforms.dispFactor, {
                duration: 1,
                value: 1,
                ease: 'expo.inOut',
                onComplete: function () {
                  mat.uniforms.currentImage.value = sliderImages[slideId];
                  mat.uniforms.currentImage.needsUpdate = true;
                  mat.uniforms.dispFactor.value = 0.0;
                  isAnimating = false;
                },
              });

              let slideTitleEl = document.getElementById('slide-title');
              let slideStatusEl = document.getElementById('slide-status');
              let nextSlideTitle = document.querySelectorAll(`[data-slide-title='${slideId}']`)[0].innerHTML;
              let nextSlideStatus = document.querySelectorAll(`[data-slide-status='${slideId}']`)[0].innerHTML;

              gsap.fromTo(
                slideTitleEl,
                0.5,
                {
                  autoAlpha: 1,
                  y: 0,
                },
                {
                  autoAlpha: 0,
                  y: 20,
                  ease: 'Expo.easeIn',
                  onComplete: function () {
                    slideTitleEl.innerHTML = nextSlideTitle;
                    gsap.to(slideTitleEl, 0.5, {
                      autoAlpha: 1,
                      y: 0,
                    });
                  },
                }
              );

              gsap.fromTo(
                slideStatusEl,
                0.5,
                {
                  autoAlpha: 1,
                  y: 0,
                },
                {
                  autoAlpha: 0,
                  y: 20,
                  ease: 'Expo.easeIn',
                  onComplete: function () {
                    slideStatusEl.innerHTML = nextSlideStatus;
                    gsap.to(slideStatusEl, 0.5, {
                      autoAlpha: 1,
                      y: 0,
                      delay: 0.1,
                    });
                  },
                }
              );
            }
          });
        });
      };

      addEvents();

      window.addEventListener('resize', function () {
        const renderW = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
        const renderH = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
        renderer.setSize(renderW, renderH);
      });

      let animate = function () {
        requestAnimationFrame(animate);
        renderer.render(scene, camera);
      };

      animate();
    };

    imagesLoaded(document.querySelectorAll('img'), () => {
      document.body.classList.remove('loading');
      const el = document.getElementById('slider');
      const imgs = Array.from(el.querySelectorAll('img'));
      if (imgs.length > 0) {
        new displacementSlider({
          parent: el,
          images: imgs,
        });
      }
    });
  }, []);

  return (
    <div ref={sliderRef} className='overflow-hidden pt-14 '>
      <main className='relative w-full h-[40rem] overflow-hidden '>
        <div id='slider' className='w-full h-[40rem] max-w-[1000px] relative mx-auto overflow-hidden border border-white shadow-2xl'>
          <div className='slider-inner relative flex items-center max-w-[1200px] h-full z-10  overflow-hidden'>
            <div id='slider-content' className='px-4 md:px-10'>
              <div className='meta relative text-[#88888a] uppercase text-md font-semibold tracking-wider'>
                Technology
              </div>
              <h2 id='slide-title' className='text-white font-light text-3xl md:text-8xl mt-10 mb-20 tracking-tight'>
                GPT-3
              </h2>
              <span data-slide-title='0' className='text-xl font-semibold text-white'>GPT-3</span>
              <span data-slide-title='1' className='text-xl font-semibold text-white'>BERT</span>
              <span data-slide-title='2' className='text-xl font-semibold text-white'>DALL·E</span>
              <span data-slide-title='3' className='text-xl font-semibold text-white'>AlphaGo</span>

              <div className='meta relative text-[#88888a] text-md  tracking-wider'>
                Status
              </div>

              <div id='slide-status' className='text-white text-lg mt-2 font-medium'>
                Active
              </div>
              <span data-slide-status='0' className='text-lg font-medium text-white'>Active</span>
              <span data-slide-status='1' className='text-lg font-medium text-white'>Inactive</span>

              <div id='pagination' className='pagination mt-10 mb-10 flex gap-x-4 items-center'>
                <button data-slide='0' className='active bg-gray-300 rounded-full w-3 h-3'></button>
                <button data-slide='1' className='bg-gray-300 rounded-full w-3 h-3'></button>
                <button data-slide='2' className='bg-gray-300 rounded-full w-3 h-3'></button>
                <button data-slide='3' className='bg-gray-300 rounded-full w-3 h-3'></button>
              </div>
            </div>
          </div>
        </div>
      </main>
    </div>
  );
};

export default Slider1;
CSS
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@100;200;300;400;500;600;700;800;900&display=swap');

@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');

#slider canvas {
  width: 100% !important;
  height: 100% !important;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  overflow: hidden !important;
}

#slider-content h2 {
  font-family: 'Lexend', sans-serif;
}

#slider-content span {
  display: none;
}

#slider-content #slide-status {
  font-family: 'Lexend', sans-serif;
}

#slider-content .meta {
  display: inline-block;
  font-family: 'Roboto', sans-serif;
}

#slider-content .meta {
  display: inline-block;
  font-family: 'Roboto', sans-serif;
}

#slider-content .meta:after {
  content: "";
  display: block;
  position: absolute;
  top: 10px;
  right: -55px;
  width: 45px;
  height: 2px;
  background-color: #393d40;
}
Dependencies:

tailwind, gsap , imagesloaded, three.js