html
<div class="slide-scroller-wrapper">
<ul ref="refScroller" class="slide-scroller" @animationiteration="eventHandler.animation">
<li class="slide-scroller-item">{{ items[0] }}</li>
<li class="slide-scroller-item">{{ items[1] }}</li>
<li class="slide-scroller-item">{{ items[2] }}</li>
</ul>
</div>
scss
@keyframes slide-scroll {
0% { transform: translate3d(0, 0px, 0); }
10% { transform: translate3d(0, -32px, 0); }
50% { transform: translate3d(0, -32px, 0); }
60% { transform: translate3d(0, -64px, 0); }
100% { transform: translate3d(0, -64px, 0); }
}
.slide-scroller {
display: flex; flex-direction: column; align-items: center; white-space: nowrap; color: red; animation: slide-scroll 15s linear infinite forwards;
&-wrapper { width: fit-content; max-width: 200px; --item-height: 32px; height: var(--item-height); overflow: hidden; }
&-item {max-width: 100%; line-height: var(--item-height); overflow: hidden; text-overflow: ellipsis; }
}
js
import {shallowReactive} from "vue";
const items = shallowReactive([]);
const allItems = [];
const eventHandler = {
animation(evt) {
if (evt.type === 'animationiteration') {
updateItems();
}
}
}
const updateItems = () => {
const len = allItems.length;
if (len < 2) {
items[0] = items[1] = items[2] = allItems?.[0] ?? '';
} else if (len === 2) {
items[0] = allItems[0];
items[1] = allItems[1];
items[2] = items[0];
} else {
let idx = allItems.findIndex(it => it === items[1]);
if (idx === len - 3) {
items[0] = allItems[idx + 1];
items[1] = allItems[idx + 2];
items[2] = allItems[0];
return
} else if (idx === len - 2) {
items[0] = allItems[idx + 1];
items[1] = allItems[0];
items[2] = allItems[1];
return
} else if (idx === len - 1) {
idx = -1;
}
items[0] = allItems[idx + 1];
items[1] = allItems[idx + 2];
items[2] = allItems[idx + 3];
}
}
updateItems();