Анимация текста как у Spotify

Рейтинг: -1Ответов: 1Опубликовано: 23.05.2023

Подскажите, как сделать такую анимацию?введите сюда описание изображения

Ответы

▲ 0

Если всегда известен цвет заднего фона, то можно сделать вот так на чистом CSS/HTML:

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

.title {
  --bg: rgb(20, 20, 25);
  --transparency-width: 30px;
  --title-width: 100vw;

  background-color: var(--bg);
  color: rgb(255, 255, 255);
  padding: 1em;
  font-size: 32px;
  overflow: hidden;
  position: relative;
}

.title::before,
.title::after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  height: 100%;
  width: var(--transparency-width);
  z-index: 10;
}

.title::before {
  background-image: linear-gradient(to right, var(--bg), transparent);
  left: 0;
}

.title::after {
  background-image: linear-gradient(to left, var(--bg), transparent);
  right: 0;
}

.title__text {
  width: -webkit-max-content; /* Для поддержки старых браузеров */
  width: max-content;
  animation: movingTitleText infinite 6s alternate ease-in-out running;
}

@keyframes movingTitleText {
  0%, 20% {
    transform: translate(0px);
  }

  40%, 60% {
    transform: translate(calc(-100% + var(--title-width) - var(--transparency-width) * 2));
  }

  80%, 100% {
    transform: translate(0px);
  }
}
<div class="title">
  <div class="title__text">
    1234567890123456789012345678901234567890
  </div>
</div>

Конечно, у такого способа есть свои минусы, допустим:

  • Нужно заранее знать ширину .title.
  • Даже если строку видно полностью, анимация всё равно будет работать.

Хотя данные проблемы можно решить JavaScript-ом

  • Можно взять ширину .title и сохранить её, чтобы не нужно было указывать ещё в ручную
  • animation-play-state: paused можно добавить если, ширина .title__text < ширина .title

document.querySelectorAll('.title').forEach(title => {
  const titleText = title.querySelector('.title__text')

  if(titleText.offsetWidth < title.offsetWidth) {
    titleText.style.animationPlayState = 'paused'
  }

  title.style.setProperty('--title-width', title.offsetWidth + 'px')
})
* {
  margin: 0;
  padding: 0;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
}

.title {
  --bg: rgb(20, 20, 25);
  --transparency-width: 30px;

  background-color: var(--bg);
  color: rgb(255, 255, 255);
  padding: 1em;
  font-size: 32px;
  overflow: hidden;
  position: relative;
}

.title::before,
.title::after {
  content: '';
  display: block;
  position: absolute;
  top: 0;
  height: 100%;
  width: var(--transparency-width);
  z-index: 10;
}

.title::before {
  background-image: linear-gradient(to right, var(--bg), transparent);
  left: 0;
}

.title::after {
  background-image: linear-gradient(to left, var(--bg), transparent);
  right: 0;
}

.title__text {
  width: -webkit-max-content; /* Для поддержки старых браузеров */
  width: max-content;
  animation: movingTitleText infinite 6s alternate ease-in-out running;
}

@keyframes movingTitleText {
  0%, 20% {
    transform: translate(0px);
  }

  40%, 60% {
    transform: translate(calc(-100% + var(--title-width) - var(--transparency-width) * 2));
  }

  80%, 100% {
    transform: translate(0px);
  }
}
<div class="title">
  <div class="title__text">
    1234567890123456789012345678901234567890
  </div>
</div>

<div class="title">
  <div class="title__text">
    12345678901234567890
  </div>
</div>