Search code examples
htmlcssinfinite-carousel

Infinite carousel weird behavior when moving faster


I wanna make something like a infinite carousel with "moving circle". It does work but I wanna that the circles move faster when I hover over the left field. That does work also but it have a weird behavior: it looks like there is another line of circles that move faster the whole time and one that moves normal, and when I hover over the field, the "normal" circles are invisible and the faster-moving ones are visible and when I move out it's vice versa. (I hope you guys understand what I mean.)

I would like that the circles move faster when I hover over the field, but without this strange behavior.

var left = document.querySelector(".left");
var one = document.querySelector("#one");
var two = document.querySelector("#two");

left.addEventListener("mouseover", () => {
  one.style.animationDuration = "10s";
  two.style.animationDuration = "10s";
})

left.addEventListener("mouseout", () => {
  one.style.animationDuration = "30s";
  two.style.animationDuration = "30s";
})
@keyframes slide {
  from {
    transform: translateX(0);
  }
  to {
    transform: translateX(-100%);
  }
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.left {
  position: absolute;
  top: 0;
  left: 0;
  width: 250px;
  height: 100%;
  background: linear-gradient(to left, rgba(255, 255, 255, 0), #f80606);
  z-index: 10;
}

.moving-circles {
  overflow: hidden;
  margin: 24px -128px;
  padding: 24px 0;
  white-space: nowrap;
  background: #fff;
  position: relative;
}

.first-row {
  display: inline-block;
  animation: 30s slide infinite linear;
}

.first-row a {
  margin: 0 4px;
  text-decoration: none;
}

.first-row span {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font-size: 40px;
  height: 120px;
  width: 120px;
  border-radius: 1000px;
  border: 1px solid #000;
  margin: 0 40px;
}
<nav class="moving-circles">
  <div class="left"></div>
  <div class="first-row" id="one">
    <a href="#">
      <span>0</span>
    </a>
    <a href="#">
      <span>1</span>
    </a>
    <a href="#">
      <span>2</span>
    </a>
    <a href="#">
      <span>3</span>
    </a>
    <a href="#">
      <span>4</span>
    </a>
    <a href="#">
      <span>5</span>
    </a>
    <a href="#">
      <span>6</span>
    </a>
    <a href="#">
      <span>7</span>
    </a>
    <a href="#">
      <span>8</span>
    </a>
    <a href="#">
      <span>9</span>
    </a>
  </div>
  <div class="first-row" id="two">
    <a href="#">
      <span>0</span>
    </a>
    <a href="#">
      <span>1</span>
    </a>
    <a href="#">
      <span>2</span>
    </a>
    <a href="#">
      <span>3</span>
    </a>
    <a href="#">
      <span>4</span>
    </a>
    <a href="#">
      <span>5</span>
    </a>
    <a href="#">
      <span>6</span>
    </a>
    <a href="#">
      <span>7</span>
    </a>
    <a href="#">
      <span>8</span>
    </a>
    <a href="#">
      <span>9</span>
    </a>
  </div>
</nav>

<script src="move-faster.js"></script>


Solution

  • If you want to do it with css only, you need to use one more <div>, which will have a speeded upanimation, but on a pause. And on hover you will start it. You may also need more duplicate .row.
    Something like this:

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    .left {
      position: absolute;
      inset: 0 auto 0 -128px;
      width: 250px;
      background: linear-gradient(to left, rgba(255, 255, 255, 0), #f80606);
      z-index: 10;
    }
    
    .moving-circles {
      overflow: hidden;
      margin: 24px 0;
      padding: 24px 0;
      white-space: nowrap;
      position: relative;
      display: flex;
      &:has(.left:hover) {
        .rows-wrapp {
          animation-play-state: running;
        }
        .rows {
          animation-play-state: paused;
        }
      }
    }
    
    .rows-wrapp {
      animation: 5s slide infinite linear paused;
      display: flex;
    }
    
    .rows {
      display: flex;
      animation: 10s slide infinite linear;
    }
    
    .row {
      display: flex;
      flex: none;
      a {
        margin: 0 44px;
        text-decoration: none;
        display: grid;
        place-items: center;
        font-size: 40px;
        height: 120px;
        width: 120px;
        border-radius: 50%;
        color: inherit;
        border: 1px solid;
      }
    }
    
    @keyframes slide {
      from {
        transform: translateX(0);
      }
      to {
        transform: translateX(-33.333%);
      }
    }
    <nav class="moving-circles">
      <div class="left"></div>
      <div class="rows-wrapp">
        <div class="rows">
          <div class="row">
            <a href="#">0</a>
            <a href="#">1</a>
            <a href="#">2</a>
            <a href="#">3</a>
            <a href="#">4</a>
            <a href="#">5</a>
            <a href="#">6</a>
            <a href="#">7</a>
            <a href="#">8</a>
            <a href="#">9</a>
          </div>
          <div class="row">
            <a href="#">0</a>
            <a href="#">1</a>
            <a href="#">2</a>
            <a href="#">3</a>
            <a href="#">4</a>
            <a href="#">5</a>
            <a href="#">6</a>
            <a href="#">7</a>
            <a href="#">8</a>
            <a href="#">9</a>
          </div>
          <div class="row">
            <a href="#">0</a>
            <a href="#">1</a>
            <a href="#">2</a>
            <a href="#">3</a>
            <a href="#">4</a>
            <a href="#">5</a>
            <a href="#">6</a>
            <a href="#">7</a>
            <a href="#">8</a>
            <a href="#">9</a>
          </div>
        </div>
      </div>
    </nav>