You are currently viewing Curved Arc Slider Carousel –  Elementor SwiperJS Slider Tutorial

Curved Arc Slider Carousel – Elementor SwiperJS Slider Tutorial

(This page includes affiliate links. If you click and purchase, I receive a small commission at no extra cost from you and that way you can support me. I only recommend tools that I have personally used and loved.)

Don’t want to make from scratch? Get the template instead 🙂

Introduction – Making Curved Arc Slider Carousel with Elementor and SwiperJS 

In this tutorial, we will create a custom swiperjs slider from scratch in elementor and use javascript to have a nice curve. I referenced this code available on codepen to create the curved effect in Elementor.

Layout for containers or DIV: 

Swiperjs layout in elementor

 Curve Slider Code

  1. .dm-curve-swiper is the CSS class for the main container that has all the slides, navigation, and pagination.
  2. direction allows you to choose between horizontal and vertical direction for your slider.
  3. loop can be set to true/false to enable or disable looping.
  4. slidesPerView is set to auto, so slider automatically checks how many slides it can fit in this container. So the number of slides shown on different screen width sizes would be different as it tries to check how many it can show in a container. For “auto”, slides should have custom width, in the below code you can check the width that I have set for my slides. If you want specific number of slides no matter the screen width, then simply remove the line slidesPerView and move it to breakpoints part so that you can control how many slides to shown for desktop, talbet and mobile. (Example: slidesPerView: 3)
  5. To add more features, refer to the “Custom Carousel” blog post or its video to learn how to customize further. Link – https://dmmotionarts.com/custom-base-slider-with-autoplay-elementor-swiperjs-slider-tutorial/
  6. wrapperClass is used to use custom CSS class for our swiper-wrapper. This is important as we don’t want elementor swiper styling to be applied here.
  7. slideClass is used to use custom CSS class for our slides. Important for the same reason as above.
  8. nextEl and prevEl is the CSS class that we use for navigation buttons. It can be added to any icon, image or text.
  9. In pagination, el: allows us to specify which container/div is our pagination container.
  10. We have different pagination types available. You can read or watch video on “Custom Carousel Blog Post” page.
  11. multiplier at line 56, rotate decides how much rotation per slide, keep this value low. translate decides how much offset is needed for the curved effect.
  12. Important: This slider only works for full width sliders i.e it stretches from left to right of your viewport.  it is because of line 65 where we use window.innerwidth javascript to calculate our wheel size.
				
					<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.css" integrity="sha512-pmAAV1X4Nh5jA9m+jcvwJXFQvCBi3T17aZ1KWkqXr7g/O2YMvO8rfaa5ETWDuBvRq6fbDjlw4jHL44jNTScaKg==" crossorigin="anonymous" referrerpolicy="no-referrer" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/11.0.5/swiper-bundle.min.js" integrity="sha512-Ysw1DcK1P+uYLqprEAzNQJP+J4hTx4t/3X2nbVwszao8wD+9afLjBQYjz7Uk4ADP+Er++mJoScI42ueGtQOzEA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>


<script>
  window.addEventListener("load", (event) => {
      
    const swiper = new Swiper('.dm-curve-swiper', {
      // Optional parameters
      direction: 'horizontal',
      loop: false,
      grabCursor: true,
      
      // Custom class names
      wrapperClass: 'dm-curve-swiper-wrapper', // instead of 'swiper-wrapper'
      slideClass: 'dm-curve-swiper-slide',     // instead of 'swiper-slide'
      
      // Show 3 slides per view and center the main slide
      slidesPerView: 'auto',
      centeredSlides: true,
      
     navigation: {
    nextEl: ".dm-curve-swiper-next",
    prevEl: ".dm-curve-swiper-prev",
  },
  pagination: {
    el: ".dm-curve-swiper-pagination",
    type: "fraction",
  },
  
  breakpoints: {
       
       1024: {
           
           spaceBetween: 100,
       },
       
        767: {
            
          spaceBetween: 80,
        },
        
        0: {
            
          spaceBetween: 50,
          
        },
      },
  
    });
    
    
    
    //Curve Carousel Effect
    const multiplier = {
    translate: .1,
    rotate: .01
}
    
    function calculateWheel() {
    const slides = document.querySelectorAll('.dm-curve-swiper-slide')
    slides.forEach((slide, i) => {
        const rect = slide.getBoundingClientRect()
        const r = window.innerWidth * .5 - (rect.x + rect.width * .5)
        let ty = Math.abs(r) * multiplier.translate - rect.width * multiplier.translate

        if (ty < 0) {
            ty = 0
        }
        const transformOrigin = r < 0 ? 'left top' : 'right top'
        slide.style.transform = `translate(0, ${ty}px) rotate(${-r * multiplier.rotate}deg)`
        slide.style.transformOrigin = transformOrigin
    })
}

function raf() {
    requestAnimationFrame(raf)
    calculateWheel()
}

raf();
    
    
  });  
</script>


<style>
    
    .dm-curve-swiper-wrapper .e-con.e-flex{
        
        flex-shrink: 0 !important;
    }
    
    .dm-curve-swiper-slide {
        
        transition: opacity 0.3s !important;
        
    }
    
    .dm-curve-swiper-slide {
        
      transition: opacity 0.3s !important;
      width: 400px;
      opacity: 0.8;
      
    }
    
    /*Mobile slide width*/
    
    @media(max-width:767px) {
        
    .dm-curve-swiper-slide {
     
      width: 70vw;
      
    }
        
    }
    
    
    .dm-curve-swiper-slide.swiper-slide-active {
        
        opacity: 1 !important;
    }
    
    .dm-curve-swiper {
        
        max-width: 100vw !important;
        overflow-x:clip;
        
    }
 
    
    .dm-curve-swiper-prev,
    .dm-curve-swiper-next{
        
        cursor:pointer;
    }
  
 
    .dm-curve-swiper-pagination {
        
        max-width: 100% !important;
        width:fit-content !important;
        
    }
    
</style>

				
			

Leave a Reply