jquerywordpresstwitter-bootstrapvisual-composer

Visual Composer image carousel doesn't loop properly


It's my first post, so please be forgiving for my english.

I have an issue with Image Carousel VC component. I need to set up something like logotypes slider (5 logos in a row) and when i set it up to display 5 from 6 images there is a gap on the end (like 4 empty spaces).

My seting:

6 images added, Slides per view: 5, Slider loop: yes

Goal is to set up carouse to be looped, without any empty spaces between images.

There is also a responsive issue. When i resize browser window images losing their ratio (width is scaling percentage and height is fixed).

Can anyone help me deal with that?


Solution

  • Porting Humberto Silva's post into a Stack Overflow answer, it seems there's no built-in way to do this, but there's a workaround in JavaScript.

    First, add an extra class vc_custominfiniteloop to the carousel element.

    visual composer carousel infinite loop

    Then, add this JavaScript code after jQuery and Visual Composer javascript has been loaded:

    /*
    Turn Visual Composer Image Carousel into Visual Composer Infinite Image Carousel
    Include before the </head> tag on yout theme's header.php 
    Read the detailed step-by-step at https://humbertosilva.com/visual-composer-infinite-image-carousel/
    */
    
    // auxiliary code to create triggers for the add and remove class for later use
    (function($){
    $.each(["addClass","removeClass"],function(i,methodname){
        var oldmethod = $.fn[methodname];
        $.fn[methodname] = function(){
              oldmethod.apply( this, arguments );
              this.trigger(methodname+"change");
              return this;
        }
    });
    })(jQuery);
    
    // main function for the infinite loop
    function vc_custominfiniteloop_init(vc_cil_element_id){
    
      var vc_element = '#' + vc_cil_element_id; // because we're using this more than once let's create a variable for it
      window.maxItens = jQuery(vc_element).data('per-view'); // max visible items defined
      window.addedItens = 0; // auxiliary counter for added itens to the end 
    
      // go to slides and duplicate them to the end to fill space
      jQuery(vc_element).find('.vc_carousel-slideline-inner').find('.vc_item').each(function(){
        // we only need to duplicate the first visible images
        if (window.addedItens < window.maxItens) {
          if (window.addedItens == 0 ) {
            // the fisrt added slide will need a trigger so we know it ended and make it "restart" without animation
            jQuery(this).clone().addClass('vc_custominfiniteloop_restart').removeClass('vc_active').appendTo(jQuery(this).parent());            
          } else {
            jQuery(this).clone().removeClass('vc_active').appendTo(jQuery(this).parent());         
          }
          window.addedItens++;
        }
      });
    
      // add the trigger so we know when to "restart" the animation without the user knowing about it
      jQuery('.vc_custominfiniteloop_restart').bind('addClasschange', null, function(){
    
        // navigate to the carousel element , I know, its ugly ...
        var vc_carousel = jQuery(this).parent().parent().parent().parent();
    
        // first we temporarily change the animation speed to zero
        jQuery(vc_carousel).data('vc.carousel').transition_speed = 0;
    
        // make the slider go to the first slide without animation and because the fist set of images shown
        // are the same that are being shown now the slider is now "restarted" without that being visible 
        jQuery(vc_carousel).data('vc.carousel').to(0);
    
        // allow the carousel to go to the first image and restore the original speed 
        setTimeout("vc_cil_restore_transition_speed('"+jQuery(vc_carousel).prop('id')+"')",100);
      });
    
    }
    
    // restore original speed setting of vc_carousel
    function vc_cil_restore_transition_speed(element_id){
    // after inspecting the original source code the value of 600 is defined there so we put back the original here
    jQuery('#' + element_id).data('vc.carousel').transition_speed = 600; 
    }
    
    // init     
    jQuery(document).ready(function(){    
      // find all vc_carousel with the defined class and turn them into infine loop
      jQuery('.vc_custominfiniteloop').find('div[data-ride="vc_carousel"]').each(function(){
        // allow time for the slider to be built on the page
        // because the slider is "long" we can wait a bit before adding images and events needed  
        var vc_cil_element = jQuery(this).prop("id");
        setTimeout("vc_custominfiniteloop_init('"+vc_cil_element+"')",2000);      
      });    
    });
    

    If you're having trouble, try enqueuing it with PHP_INT_MAX and depending on jQuery, example:

    function enqueue_my_scripts()
    {
        // This example expects you to create a file with the JavaScript above in wp-content/themes/yourtheme/assets/js/infinite_visualcomposer_carousel.js
        wp_enqueue_script('infinite-vs-carousel',  get_stylesheet_directory_uri() . 'assets/js/infinite_visualcomposer_carousel.js', array('jquery'), filemtime(get_stylesheet_directory() . '/assets/js/infinite_visualcomposer_carousel.js'), true);
    }
    add_action('wp_enqueue_scripts', 'enqueue_my_scripts', PHP_INT_MAX);
    

    All credits to Humberto Silva, I'm just porting this answer here to save the solution in case the blog goes offline.