Jump to content
Search Community

Draggable Carousel with Slidebar using Angular

saibat
Moderator Tag

Recommended Posts

Posted
Hello everybody
I would like to create a Carousel slider which should show the current item enlarged with a short description. (picture below)
The whole thing should be draggable and if the user is inactive it should run in a loop. 
In addition, there should be a scrollbar at the end with which you can move the carousel. 
I have not worked with gsap very often, but I was recommended to do something like that with gsap. 
Does anyone have an idea how to create something like that?
Thank you very much

gsap_example.png

Posted

Hey saibat and welcome to the GreenSock forums! 

 

I recommend that you start with our "Getting Started" article:

 

Then I recommend that you modify an existing carousel using GSAP to fit your needs. Maybe start with this? You could search for others as well.

Unfortunately we don't have the capacity to make every project that people post about in the forums. But we're happy to help you if you get stuck somewhere! Just let us know.

Posted

Hello Zach Saucier
Thank you for your answer.
I tried to incorporate the Sahil slider into my Angular project.

The slider works but if I drag a slide and I want to go to the next position it does not slide to the next slide automatically.

Another problem is that if i change the position of the slidebar the slider does not change.

Does anyone know what the problem is?

 

Here is my code:

 

.html

<div class="controls">
    <div id="prev" (click)="prevElement()">prev</div>
    <div id="next" (click)="nextElement()">next</div>
  </div>
  <div id="container">
    <div id="slider">
      <div class="slide one sliderItem">1</div>
      <div class="slide one sliderItem">2</div>
      <div class="slide one sliderItem">3</div>
      <div class="slide one sliderItem">4</div>
      <div class="slide one sliderItem">5</div>
      <div class="slide one sliderItem">6</div>
      <div class="slide one sliderItem">7</div>
    </div>
  </div>
  <div #scrubber id="scrubber">
    <div #handle id="handle"></div>
  </div>

 

.scss

  #container {
    positionrelative;
    height50vh;
    width80vw;
    background-color#111;
    border-radius10px;
    box-sizingborder-box;
    overflowhidden;
    margin20px auto;
    displayflex;
  }
  
  #slider {
    displayblock;
    positionrelative;
    box-sizingborder-box;
    height100%;
    displayflex;
  }
  
  .slide {
    displayflex;
    positionrelative;
    height100%;
    background-color#c80000;
    border-radius10px;
    bordersolid 1px #aaa;
    floatleft;
    box-sizingborder-box;
    justify-contentcenter;
    align-contentcenter;
    align-itemscenter;
    font-size40px;
    colorwhite;
    background-sizecover;
    background-positioncenter center;
  }
  
  #progress {
    displayblock;
    positionrelative;
    height1px;
    width60%;
    background-color#fff;
    margin0 auto;
  }
  
  .controls{
    displayflex;
    overflowhidden;
    justify-contentcenter;
    padding50px 0 0 0;
  }
  
  .controls div{
    displayflex;
    positionrelative;
    floatleft;
    text-transformlowercase;
    background-color#5923a5;
    margin0 20px;
    padding5px 20px 10px;
    color#aaa;
    font-size17px;
    font-familyinherit;
    bordernone;
  }
  
  #scrubber{
    displayblock;
    positionrelative;
    width80vw;
    height10px;
    bordersolid 1px #aaa;
    margin0 auto;
    overflowhidden;  
  }
  
  #handle{
    displayblock;
    positionrelative;
    width100px;
    height100%;
    background#5923a5;
  }

 

.ts

import { ComponentOnInitInject } from '@angular/core';
import { gsapTweenMax } from 'gsap';
import { Draggable } from 'gsap/Draggable';
import { DOCUMENT } from '@angular/common';
 
@Component({
  selector: 'product-slider',
  templateUrl: './product-slider.component.html',
  styleUrls: ['./product-slider.component.scss']
})
export class ProductSliderComponent implements OnInit {
  slidesany;
  containerany;
  sliderany;
  scrubberany;
  handleany;
 
  slideCountany;
 
  boxWidthany;
  sliderWidthany;
  targetX = 0;
  lastTarget = 0;
  draggableany;
 
  ratioany;
 
  ratioXany;
 
  constructor(@Inject(DOCUMENTprivate _document) { }
 
  ngOnInit(): void {
    gsap.registerPlugin(Draggable);
  }
 
  ngAfterViewInit() {
 
    this.slides = this._document.querySelectorAll('.sliderItem');
    this.container = this._document.querySelector('#container');
    this.slider = this._document.querySelector('#slider');
    this.scrubber = this._document.querySelector('#scrubber');
    this.handle = this._document.querySelector('#handle');
    
 
    this.slideCount = this._document.getElementsByClassName('sliderItem').length;
 
    this.boxWidth = this.container.offsetWidth;
    this.sliderWidth = this.boxWidth * this.slideCount;
 
    console.log("slides");
    console.log(this.slider);
 
    for(var i = 0i < this.slides.lengthi++){
      this.slides[i].style.width = this.boxWidth + "px";
    }
 
    this.slider.style.width = this.sliderWidth;
 
    Draggable.create(this.slider, {
      type: "x",
      edgeResistance: 0.6,
      bounds: "#container",
      throwProps: true,
      onDrag: this.setProgess,
      onThrowUpdate: this.setProgess,
    });
 
    this.initScrollBar();
 
  }
 
  setProgess() {
    var x = gsap.getProperty("#slider""x");
 
    this.targetX = Math.round((x as number) / this.boxWidth);
    this.targetX =
      this.targetX < -1 * (this.slideCount - 1) ? -1 * (this.slideCount - 1) : this.targetX;
 
    gsap.set(this.scrubber, { x: -this.ratioX * this.ratio });
    this.lastTarget = this.targetX;
 
  }
 
  prevElement() {
    if (this.targetX < 0) {
      this.targetX++;
 
      TweenMax.to(this.slider1, {
        x: this.boxWidth * this.targetX,
        onUpdate: this.setProgess
      });
    }
  }
 
  nextElement() {
    if (this.targetX > -1 * (this.slideCount - 1)) {
      this.targetX--;
 
      TweenMax.to(this.slider1, {
        x: this.boxWidth * this.targetX,
        onUpdate: this.setProgess
      });
    }
  }
 
  initScrollBar() {
 
    //Select width of the scrubber
    var scrubWidth = this.scrubber.getBoundingClientRect().width;
 
    // Use scrubWidth to calculate handleWidth and use handleWidth wherever needed to keep your slides snap correctly, handleWidth depends on number of slides
    var handleWidth = scrubWidth / this.slideCount;
 
    // ratio to calculate x translate
    this.ratio = scrubWidth / this.sliderWidth;
 
    gsap.set(this.handle, { width: handleWidth });
 
    var self = this;
 
    Draggable.create(this.handle, {
      type: "x",
      //Calculate minX and maxX to set bounds
      //bounds: { minX: 0, maxX: 5 },
      throwProps: true,
      snap: {
        x: function (value) {
          self.ratioX = Math.round(value / handleWidth) * handleWidth;
          return self.ratioX;
        }
      },
      onDrag: this.updateSlides,
      onThrowUpdate: this.updateSlides
    });
  }
 
  updateSlides() {
    // Set the position of slider by calculating ratio
    //this.slider = document.querySelector('#slider');
    gsap.set(this.slider, { x: -this.ratioX / this.ratio });
  }


 
}
ZachSaucier
Posted

@saibat Again, please make a minimal demo if you'd like help debugging your project. Please only include the relevant code and use something like CodePen to exemplify the issue.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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