Hello All
I am working on a Vue3 component with two parallel vertical carousels. The one on the left is moving from top to bottom, while the other on the right is moving from bottom to top. My problem is that the left carousel is working well with an infinite loop of the cards, but the right carousel is not infinite.
Thank your for your help in advance!
<template>
<div
class="100vh overflow-hidden"
:class="`wrapper-${name}`"
>
<div
:class="`pictures-${name}`"
class=""
>
<img
v-for="(card, idx) in props.cards"
:key="idx"
class="w-[14vw] block py-3"
:class="`picture-${name}`"
:src="cardURL(card)"
alt="card"
>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue';
import { gsap } from 'gsap';
import { Draggable } from 'gsap/all'
import { InertiaPlugin } from 'gsap/all';
gsap.registerPlugin(Draggable, InertiaPlugin)
const props = defineProps({
cards: {
type: Array,
required: true,
},
name: {
type: String,
required: true,
},
reverse: {
type: Boolean,
required: false,
default: false,
}
});
const cardURL = (img) => {
return `/card/${img}.png`
}
const pictures = ref(null);
let counter = ref(0);
function startAnim() {
const totalHeight = pictures.value.querySelector(`.pictures-${props.name}`).offsetHeight;
pictures.value.querySelectorAll(`.picture-${props.name}`).forEach((picture, i) => {
const pictureHeight = picture.offsetHeight;
const pictureOffset = picture.offsetTop;
const pictureDistance = pictureHeight + pictureOffset;
const tl = gsap.timeline({ repeat: -1, defaults: { ease: "none", duration: 20 } });
if (props.reverse) {
tl.to(picture, {
y: `+=${totalHeight}`,
modifiers: {
y: function (y, target) {
y = parseFloat(y);
if (y >= pictureDistance) {
y -= totalHeight;
}
return y + "px";
},
},
}, 0);
} else {
tl.to(picture, {
y: `-=${totalHeight}`,
modifiers: {
y: function (y, target) {
y = parseFloat(y);
if (y < -pictureDistance) {
y += totalHeight;
}
return y + "px";
},
},
}, 0);
}
});
}
function incrementCounter() {
counter.value++;
if (counter.value === pictures.value.querySelectorAll(`.picture-${props.name}`).length) {
startAnim();
}
}
onMounted(() => {
pictures.value = document.querySelector(`.wrapper-${props.name}`);
const allPictures = document.querySelectorAll(`.picture-${props.name}`);
allPictures.forEach((picture) => {
if (picture.complete) {
incrementCounter();
} else {
picture.addEventListener('load', incrementCounter);
}
});
});
</script>