Jump to content

Make image as background cover (PixiJS Slider)


Perdixo
 Share

Recommended Posts

I've made a custom PIXI.js slider for my wordpress website. It works pretty damn fine but i've got an issue : i'm trying to make the images that are loaded `background-size: cover` and centered. Right now on mobile, the images are stretched. But i can't find out how to do this ... Any help would be much much appreciated !Here is my js :

window.onload = function () {
  class PIXIScene {
    constructor(container) {
      this.container = container;

      if (!this.container) return;
      this.init();
    }

    init() {
      this.state();
      this.setup();
      this.animate();
    }

    state() {
      this.isAnimating = false;
      this.currentIndex = 0;
      this.slides = [];
      this.dom = {
        next: document.querySelector('.slider__count .next'),
        current: document.querySelector('.slider__count .current'),
        firstSlide: document.querySelector('.slider__title-1'),
        secondSlide: document.querySelector('.slider__title-2'),
        fistSub: document.querySelector('.slider__subtitle-1'),
        secondSub: document.querySelector('.slider__subtitle-2'),
        // text1: document.querySelector('.')
      };
      this.firstSlideCount = 0;
      this.secondSlideCount = 1;
      this.firstSubCount = 0;
      this.secondSubCount = 1;
    }

    setup() {
      this.app = new PIXI.Application({
        width: this.viewport.width,
        height: this.viewport.height,
        resolution: window.devicePixelRatio,
        autoDensity: true,
        autoResize: true,
        transparent: true,
      });

      this.loadImages();
    }

    loadImages() {
      //Getting the original images
      this.originalImages = [...this.container.querySelectorAll('img')];
      this.imageSrc = this.originalImages.map((image) => image.getAttribute('src'));

      //Clearing the container & appending the canvas into it
      this.container.innerHTML = '';
      this.container.appendChild(this.app.view);

      //Defining the loader
      const loader = new PIXI.Loader();

      //Adding the image src
      this.images = [...this.imageSrc];

      //Loading each image
      this.images.forEach((image, i) => {
        loader.add(image, this.images[i]);
      });

      loader.load((loader, resources) => {
        this.resources = resources;
        this.createSlider();
      });
    }

    createSlider() {
      //Container for all the images
      this.slider = new PIXI.Container();
      this.slider.width = this.app.screen.width;
      this.slider.height = this.app.screen.height;
      this.app.stage.addChild(this.slider);

      //Defining the area for the filter
      this.clipRect = new PIXI.Rectangle(0, 0, this.app.screen.width, this.app.screen.height);
      this.slider.filterArea = this.clipRect;
      this.app.stage.interactive = true;

      this.addSlides();
      this.createFilters();
      this.slider.filters = [this.displacementFilter];

      this.events();
    }

    addSlides() {
      let i = 0;

      Object.keys(this.resources).forEach((key) => {
        const slide = new PIXI.Sprite(this.resources[key].texture);

        //Setting initial slide position
        slide.width = this.app.screen.width;
        slide.height = this.app.screen.height;
        slide.y = 0;
        slide.x = i === 0 ? 0 : -this.app.screen.width;

        //Adding all slides to the array in state
        this.slides[i] = slide;
        this.slider.addChild(slide);

        i++;
      });
    }

    createFilters() {
      this.displacement = new PIXI.Sprite.from(
        'https://s3-us-west-2.amazonaws.com/s.cdpn.io/2479807/displacementWave.jpg'
      );

      this.displacement.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;

      this.displacementFilter = new PIXI.filters.DisplacementFilter(this.displacement, 0);
      this.RGBFilter = new PIXI.filters.RGBSplitFilter([0, 0], [0, 0], [0, 0]);

      return this.displacementFilter, this.RGBFilter;
    }

    nextSlide() {
      if (this.nextButton.getAttribute('disabled') || this.isAnimating) return false;

      this.prevButton.removeAttribute('disabled');

      if (this.currentIndex + 2 >= this.images.length) {
        this.nextButton.setAttribute('disabled', 'disabled');
      }

      const currentSlide = this.slides[this.currentIndex];
      const nextSlide = this.slides[this.currentIndex + 1];
      this.dom.next.textContent = '0' + (this.currentIndex + 2);

      const tl = gsap.timeline({
        onStart: () => {
          this.isAnimating = true;
        },
        onComplete: () => {
          this.currentIndex++;
          this.isAnimating = false;
        },
      });

      ////////////////////////////////
      // Change slider text contents

      let nextSlideContent;
      let currentSlideContent;

      // Titre 1
      if (this.currentIndex + 1 == this.firstSlideCount) {
        nextSlideContent = this.dom.firstSlide;
      } else if (this.currentIndex + 1 == this.secondSlideCount) {
        nextSlideContent = this.dom.secondSlide;
      }

      if (this.currentIndex == this.firstSlideCount) {
        currentSlideContent = this.dom.firstSlide;
      } else if (this.currentIndex + 1 == this.secondSlideCount) {
        currentSlideContent = this.dom.secondSlide;
      }

      // console.log(currentSlideContent);
      // console.log(nextSlideContent);

      tl.to(
        currentSlide,
        {
          x: -this.app.screen.width,
          duration: 1.5,
          ease: 'Expo.easeInOut',
        },
        0
      )
        .fromTo(
          nextSlide,
          {
            x: this.app.screen.width,
          },
          {
            x: 0,
            ease: 'Expo.easeInOut',
            duration: 1.5,
          },
          0
        )
        .to(
          this.displacementFilter.scale,
          {
            x: 40,
            y: 40,
            duration: 1,
          },
          0
        )
        .to(
          this.displacementFilter.scale,
          {
            duration: 1,
            x: 0,
            y: 0,
          },
          0.5
        )
        .set(this.dom.current, {
          opacity: 0,
          y: 0,
        })
        .set(currentSlideContent, {
          opacity: 0,
          y: 0,
        })
        .set(
          this.dom.next,
          {
            y: '-100%',
          },
          0
        )
        .set(
          nextSlideContent,
          {
            opacity: 0,
            y: '-100%',
          },
          0
        )
        .to(
          this.dom.current,
          {
            opacity: 1,
            y: '100%',
          },
          0
        )
        .to(
          currentSlideContent,
          {
            opacity: 0,
            y: '100%',
          },
          0
        )
        .to(
          this.dom.next,
          {
            y: 0,
          },
          '-=1'
        )
        .to(
          nextSlideContent,
          {
            opacity: 1,
            y: 0,
          },
          '-=1'
        );

      return tl;
    }

    prevSlide() {
      if (this.prevButton.getAttribute('disabled') || this.isAnimating) return false;

      this.nextButton.removeAttribute('disabled');

      if (this.currentIndex - 2 < 0) {
        this.prevButton.setAttribute('disabled', 'disabled');
      }

      this.dom.next.textContent = '0' + this.currentIndex;

      const tl = gsap.timeline({
        onStart: () => {
          this.isAnimating = true;
        },
        onComplete: () => {
          this.currentIndex--;
          this.isAnimating = false;
        },
      });

      const currentSlide = this.slides[this.currentIndex];
      const prevSlide = this.slides[this.currentIndex - 1];

      ////////////////////////////////
      // Change slider text contents

      let prevSlideContent;
      let currentSlideContent;

      // Titre 1
      if (this.currentIndex - 1 == this.firstSlideCount) {
        prevSlideContent = this.dom.firstSlide;
      } else if (this.currentIndex - 1 == this.secondSlideCount) {
        prevSlideContent = this.dom.secondSlide;
      }

      if (this.currentIndex == this.firstSlideCount) {
        currentSlideContent = this.dom.firstSlide;
      } else if (this.currentIndex == this.secondSlideCount) {
        currentSlideContent = this.dom.secondSlide;
      }

      tl.to(
        currentSlide,
        {
          x: this.app.screen.width,
          duration: 1.5,
          ease: 'Expo.easeInOut',
        },
        0
      )
        .fromTo(
          prevSlide,
          {
            x: -this.app.screen.width,
          },
          {
            x: 0,
            ease: 'Expo.easeInOut',
            duration: 1.5,
          },
          0
        )
        .to(
          this.displacementFilter.scale,
          {
            x: 50,
            y: 50,
            duration: 1,
          },
          0
        )
        .to(
          this.displacementFilter.scale,
          {
            duration: 1,
            x: 0,
            y: 0,
          },
          0.5
        )
        .set(this.dom.current, {
          y: 0,
        })
        .set(currentSlideContent, {
          opacity: 0,
          y: 0,
        })
        .set(
          this.dom.next,
          {
            y: '100%',
          },
          0
        )
        .set(
          prevSlideContent,
          {
            opacity: 0,
            y: '100%',
          },
          0
        )
        .to(
          this.dom.current,
          {
            y: '-100%',
          },
          0
        )
        .to(
          currentSlideContent,
          {
            opacity: 0,
            y: '-100%',
          },
          0
        )
        .to(
          this.dom.next,
          {
            y: 0,
          },
          '-=1'
        )
        .to(
          prevSlideContent,
          {
            opacity: 1,
            y: 0,
          },
          '-=1'
        );

      return tl;
    }

    events() {
      this.nextButton = document.querySelector('.slider__next');
      this.prevButton = document.querySelector('.slider__prev');

      this.nextButton.addEventListener('click', this.nextSlide.bind(this));
      this.prevButton.addEventListener('click', this.prevSlide.bind(this));
    }

    animate() {
      requestAnimationFrame(() => {
        this.animate();
      });

      this.app.render();
    }

    get viewport() {
      const width = this.container.clientWidth;
      const height = this.container.clientHeight;
      return {
        width,
        height,
      };
    }
  }

  const slideshowCanvas = document.querySelector('.slider__canvas');
  const scene = new PIXIScene(slideshowCanvas);
};

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...