Have your say in Community Polls: What was/is your greatest motivation to start your own business?

Re: Trying to create an "infinite logo scroller/carousell" section for Dawn theme

Trying to create an "infinite logo scroller/carousell" section for Dawn theme

LucasAyee
Visitor
1 0 0

Hi there, so for the past few hours i've been trying to figure out how to get this code to work. I know absolutely nothing about code so i went to ChatGPT for help (i know...). They have somewhat created a foundation for the code, however it isn't working correctly at all.

I'm trying to create an endless loop of logos which appear "infinite" and scroll forever. However right a few sets of logos appear in the middle of the screen, they just scroll off to the left leaving a big gap of white, then they re-appear again.

Any help is very appreciated!

CODE - - - - - - - -

{% schema %}
{
  "name": "Infinite Logo Scroller",
  "settings": [
    {
      "type": "image_picker",
      "id": "logo_1",
      "label": "Logo 1"
    },
    {
      "type": "range",
      "id": "logo_1_size",
      "label": "Logo 1 Size",
      "default": 100,
      "min": 50,
      "max": 300,
      "step": 5
    },
    {
      "type": "image_picker",
      "id": "logo_2",
      "label": "Logo 2"
    },
    {
      "type": "range",
      "id": "logo_2_size",
      "label": "Logo 2 Size",
      "default": 100,
      "min": 50,
      "max": 300,
      "step": 5
    },
    {
      "type": "image_picker",
      "id": "logo_3",
      "label": "Logo 3"
    },
    {
      "type": "range",
      "id": "logo_3_size",
      "label": "Logo 3 Size",
      "default": 100,
      "min": 50,
      "max": 300,
      "step": 5
    },
    {
      "type": "range",
      "id": "logo_spacing",
      "label": "Logo Spacing (px)",
      "default": 10,
      "min": 0,
      "max": 50,
      "step": 1
    },
    {
      "type": "range",
      "id": "animation_speed",
      "label": "Animation Speed (seconds)",
      "default": 10,
      "min": 1,
      "max": 30,
      "step": 1
    },
    {
      "type": "color",
      "id": "background_color",
      "label": "Background Color",
      "default": "#ffffff"
    }
  ],
  "presets": [
    {
      "name": "Infinite Logo Scroller",
      "category": "Custom"
    }
  ]
}
{% endschema %}

<div class="infinite-logo-scroller" style="background-color: {{ section.settings.background_color }};">
  <div class="logo-track">
    {% for i in (1..2) %}
      {% for j in (1..3) %}
        {% assign logo_key = 'logo_' | append: j %}
        {% assign logo_size_key = 'logo_' | append: j | append: '_size' %}
        {% assign logo = section.settings[logo_key] %}
        {% assign logo_size = section.settings[logo_size_key] %}
        {% if logo != blank %}
          <div class="logo-slide" style="width: {{ logo_size }}px; margin-right: {{ section.settings.logo_spacing }}px;">
            <img src="{{ logo | img_url: '200x' }}" alt="Brand logo {{ j }}" style="width: 100%; height: auto;">
          </div>
        {% endif %}
      {% endfor %}
    {% endfor %}
  </div>
</div>

<style>
.infinite-logo-scroller {
  overflow: hidden;
  width: 100%;
  position: relative;
}

.logo-track {
  display: flex;
  animation: scroll {{ section.settings.animation_speed }}s linear infinite;
}

.logo-slide {
  flex: 0 0 auto;
}

@keyframes scroll {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}
</style>

<script>
document.addEventListener('DOMContentLoaded', function () {
  var track = document.querySelector('.logo-track');
  var logoSlides = document.querySelectorAll('.logo-slide');
  var totalWidth = 0;

  logoSlides.forEach(function (slide) {
    totalWidth += slide.offsetWidth + parseInt(window.getComputedStyle(slide).marginRight);
  });

  // Set the width of the track to be twice the total width of the logos to ensure seamless scrolling
  track.style.width = totalWidth * 2 + 'px';

  // Adjust the duration of the animation based on the total width and the desired animation speed
  var duration = totalWidth / (track.offsetWidth / {{ section.settings.animation_speed }});
  track.style.animationDuration = duration + 's';
});
</script>



Replies 3 (3)

tim
Shopify Partner
3911 394 1435

Need to make them wider, but anyway.
Had a go with Chat myself and here is the result. Works ok'ish for me:

{% schema %}
{
  "name": "Infinite Logo Scroller",
  "blocks": [
    {
      "type": "logo",
      "name": "Logo",
      "settings": [
        {
          "type": "image_picker",
          "id": "logo",
          "label": "Logo"
        }
      ]
    }
  ],
  "settings": [
    {
      "type": "range",
      "id": "logos_shown",
      "label": "Number of Logos Shown at Once",
      "default": 3,
      "min": 1,
      "max": 5,
      "step": 1
    },
    {
      "type": "range",
      "id": "logo_spacing",
      "label": "Logo Spacing px)",
      "default": 10,
      "min": 0,
      "max": 50,
      "step": 5
    },
    {
      "type": "range",
      "id": "animation_speed",
      "label": "Animation Speed (seconds)",
      "default": 10,
      "min": 1,
      "max": 30,
      "step": 1
    },
    {
      "type": "color",
      "id": "background_color",
      "label": "Background Color",
      "default": "#ffffff"
    },
    {
      "type": "text",
      "id": "image_size",
      "label": "Image Size (e.g., 500x500)",
      "default": "200x200"
    }
  ],
  "presets": [
    {
      "name": "Infinite Logo Scroller",
      "category": "Custom"
    }
  ]
}
{% endschema %}

<div class="infinite-logo-scroller" style="background-color: {{ section.settings.background_color }};">
  <div class="logo-track">
    {% assign images_count = 0 %}
    {% capture slides %}
    {% for block in section.blocks %}
      {% assign logo = block.settings.logo %}
      {% if logo %}
        {% assign images_count = images_count | plus: 1 %}
        <div class="logo-slide">
          <img src="{{ logo | img_url: section.settings.image_size }}" alt="{{ logo.alt }}">
        </div>
      {% endif %}
    {% endfor %}
    {%  endcapture %}
    {{  slides }}
    <!-- copy for smooth scrolling -->
    {{  slides }}   
    {%  if images_count < section.settings.logos_shown %} 
    <!-- another copy if show more per line than have images -->
    {{  slides }}   
    {% endif %} 
  </div>
</div>

<style>
  .infinite-logo-scroller {
    overflow: hidden;
    width: 100%;
    position: relative;
  }
  
  .logo-track {
    display: flex;
    animation: scroll {{ section.settings.animation_speed }}s linear infinite;
    width: 200%; /* Adjusted width for infinite scrolling */
  }
  
  .logo-slide {
    flex: 0 0 calc(50% / {{ section.settings.logos_shown }} - {{ section.settings.logo_spacing }}px);
    margin-right: {{ section.settings.logo_spacing }}px;
  }
  
  .logo-slide img {
    width: 100%;
    height: auto;
  }
  @keyframes scroll {
    0% {
      transform: translateX(0);
    }
    100% {
      {%  assign animation_stop_at = 1.0 | times: images_count | divided_by: section.settings.logos_shown %}
      transform: translateX(calc( -50% * {{ animation_stop_at }})); /* Adjusted to half'ish of the track's width for infinite scrolling */
    }
  }
</style>
If my post is helpful, consider liking it -- it will help others with similar problem to find a solution.
I can be reached via e-mail tairli@yahoo.com

lf-ecom-shops
Explorer
58 2 7

Hey @LucasAyee , I created one yesterday because I'm working on my new Shopify Theme lol, so it isn't finished yet. For now, it's just for mobile view, but I'll update you when it's finished. The code is: 

{% schema %}
{
  "name": "Logo Carousel",
  "settings": [
    {
      "type": "range",
      "id": "scroll_speed",
      "label": "Scroll Speed (seconds)",
      "default": 20,
      "min": 5,
      "max": 60,
      "step": 1
    },
    {
      "type": "color",
      "id": "background_color",
      "label": "Background Color",
      "default": "#ffffff"
    }
  ],
  "blocks": [
    {
      "type": "logo",
      "name": "Logo",
      "settings": [
        {
          "type": "image_picker",
          "id": "logo_image",
          "label": "Logo Image"
        },
        {
          "type": "text",
          "id": "logo_alt_text",
          "label": "Alt Text",
          "default": "Logo"
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Logo Carousel",
      "category": "Custom"
    }
  ]
}
{% endschema %}
<div class="logo-carousel-wrapper" style="background-color: {{ section.settings.background_color }};">
  <div class="logo-carousel" id="logo-carousel">
    <div class="logos">
      {% for block in section.blocks %}
        <div class="logo-item">
          <img src="{{ block.settings.logo_image | img_url: 'medium' }}" alt="{{ block.settings.logo_alt_text }}">
        </div>
      {% endfor %}
      {% for block in section.blocks %}
        <div class="logo-item">
          <img src="{{ block.settings.logo_image | img_url: 'medium' }}" alt="{{ block.settings.logo_alt_text }}">
        </div>
      {% endfor %}
    </div>
  </div>
</div>

<style>
  .logo-carousel-wrapper {
    overflow: hidden;
    position: relative;
    width: 100%;
    background-color: {{ section.settings.background_color }};
  }
  .logo-carousel {
    display: flex;
    align-items: center;
  }
  .logos {
    display: flex;
    animation: scroll-logos {{ section.settings.scroll_speed }}s linear infinite;
  }
  .logo-item {
    padding: 0 20px;
  }
  .logo-item img {
    max-height: 20px; 
    display: block;
  }
  @keyframes scroll-logos {
    0% {
      transform: translateX(0);
    }
    100% {
      transform: translateX(-50%);
    }
  }
</style>

<script>
  document.addEventListener('DOMContentLoaded', function () {
    const logosContainer = document.querySelector('.logos');
    const logoItems = document.querySelectorAll('.logo-item');
    const totalWidth = Array.from(logoItems).reduce((total, item) => total + item.offsetWidth, 0) / 2;
    const speed = {{ section.settings.scroll_speed }} * 1000; 
    logosContainer.style.animationDuration = `${speed / 1000}s`;

    const keyframes = `
      @keyframes scroll-logos {
        0% {
          transform: translateX(0);
        }
        100% {
          transform: translateX(-${totalWidth}px);
        }
      }
    `;

    const styleSheet = document.createElement('style');
    styleSheet.type = 'text/css';
    styleSheet.innerText = keyframes;
    document.head.appendChild(styleSheet);
  });
</script>
greenvalleycode
Explorer
46 0 7

Nice work! I'm looking to use this for my "as seen on" social proof section. Did you ever get this launched for both mobile and desktop views?