Как сделать 2 бесконечно, по очереди бегущие строки
Есть массив строк и они должны по очереди выежать и заезжать за контейнер
Первый выезжает сверху слева и заезжает за контейнер, двигаясь направо, потом второй снизу справа выезжает и заезжает за контейнер, двигаясь налево и так по кругу, но по очереди
На данный момент, имеется только вёрстка этого макета как на видео, но скидывать наверное не нужно. Можете пожалуйста показать примером или же если есть готовое решение, буду сильно благодарен
Ответы (1 шт):
Можно сделать так:
Запоминаем наши
div-ы в переменные и на их основе создаём словарик. Это нам понадобится чтобы легко и просто переключаться между правым и левымdiv-омС помощью getComputedStyle достаём значение переменной
--animation-duration, который объявлен в CSSДостаем оттуда число и делим пополам. На пополам надо делить, чтобы скрипт успевал обновлять значения для каждой из сторон. Иначе он будет либо слишком быстро менять либо слишком медленно, а нам надо чтобы прямо перед началом очередной стороны текст менялся
Т.к. нам надо циклически гулять по массиву, то я использую формулу
(currIndex + 1) % arrayLength. Именно% arrayLengthпозволяет гулять циклически по массиву, т.к. он возвращает значения от 0 доarrayLength - 1. P.S. Но эта формула верна только если вы всегда увеличиваете индекс. Если вы будете уменьшать, то в более общем виде формула будет такой:(arrayLength + currIndex +/- 1) % arrayLength
const texts = [
'Right text one',
'Left text one',
'Right text two',
'Left text two',
'Right text three',
'Left text three',
];
const rightSide = document.querySelector('.text-from-right');
const leftSide = document.querySelector('.text-from-left');
const sidesMap = new Map([
[rightSide, leftSide],
[leftSide, rightSide]
]);
const animationDurationInSecs = getComputedStyle(document.body).getPropertyValue('--animation-duration'); // '4s'
const animationDurationHalf = parseFloat(animationDurationInSecs) / 2; // 2
let currTextIndex = -1;
let currSide = leftSide;
setInterval(() => {
currTextIndex = (currTextIndex + 1) % texts.length;
currSide = sidesMap.get(currSide);
currSide.innerHTML = texts[currTextIndex];
}, animationDurationHalf * 1000);
:root {
--animation-duration: 4s;
}
body {
margin: 0;
}
.section {
display: flex;
width: 100%;
}
.block {
width: 100%;
}
.center-block {
height: 180px;
border: 1px solid black;
}
.left-block,
.right-block {
display: flex;
flex-direction: column;
overflow: hidden;
}
.left-block {
justify-content: start;
}
.right-block {
justify-content: end;
}
.text-from-left,
.text-from-right {
white-space: nowrap;
width: fit-content;
padding-left: 100%;
}
.text-from-left {
animation: right-stream var(--animation-duration) linear infinite;
}
.text-from-right {
animation: left-stream var(--animation-duration) linear infinite;
}
@keyframes right-stream {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
@keyframes left-stream {
0% {
transform: translateX(100%);
}
100% {
transform: translateX(-100%);
}
}
<div class="section">
<div class="block left-block">
<div class="text-from-left">Left text onee</div>
</div>
<div class="block center-block"></div>
<div class="block right-block">
<div class="text-from-right">Right text onee</div>
</div>
</div>