Examples

Some examples of how to use the library are shown below.

Text marquee

<template>
    <Vue3Marquee>
        <span
            v-for="(word, index) in helloArray"
            :key="index"
        >
            {{ word }}
        </span>
    </Vue3Marquee>
</template>

<script setup>
const helloArray = ['hello', 'こんにちは', 'bonjour', ...]
</script>

Image marquee

<template>
    <Vue3Marquee>
        <img
            v-for="img in imgArray"
            :key="img"
            :src="img"
        />
    </Vue3Marquee>
</template>

<script setup>
const imgArray = [
    'https://sponsors.vuejs.org/images/vueschool.avif',
    'https://sponsors.vuejs.org/images/vehikl.avif',
    'https://sponsors.vuejs.org/images/dronahq.avif',
    ...
]
</script>

Cards marquee

<template>
    <Vue3Marquee>
        <div class="card" v-for="avatar in avatarArray" :key="avatar">
            <img :src="avatar" />
            <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                tempor incididunt ut labore et dolore magna aliqua.
            </p>
        </div>
    </Vue3Marquee>
</template>

<script setup>
const avatarArray = [
    'https://avatars.dicebear.com/api/avataaars/1.svg',
    'https://avatars.dicebear.com/api/avataaars/2.svg',
    'https://avatars.dicebear.com/api/avataaars/3.svg',
    ...
]
</script>

Image marquee with a gradient

You can add a gradient to the marquee so that the sides of the marquee are more pleasant to look at.

In this example the following props are used:

  • gradient: true
  • gradientColor: [255, 255, 255] (light)
  • gradientColor: [0, 0, 0] (dark)
  • gradientLength: 30%
<template>
    <Vue3Marquee
        :gradient="true"
        :gradient-color="colorMode.value === 'light' ? [255, 255, 255] : [0, 0, 0]"
        gradient-length="30%"
    >
        <img
            v-for="img in imgArray"
            :key="img"
            :src="img"
        />
    </Vue3Marquee>
</template>

<script setup>
const colorMode = useColorMode()

const imgArray = [
    'https://sponsors.vuejs.org/images/vueschool.avif',
    'https://sponsors.vuejs.org/images/vehikl.avif',
    'https://sponsors.vuejs.org/images/dronahq.avif',
    ...
]
</script>

Card marquee with pauseOnHover

The marquee can pause when you hover over the content. This is useful if you want the ability to run additional actions inside the content. For this example the pauseOnHover prop is used.

<template>
    <Vue3Marquee :pause-on-hover="true">
        <div class="card" v-for="avatar in avatarArray" :key="avatar">
            <img :src="avatar" />
            <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                tempor incididunt ut labore et dolore magna aliqua.
            </p>
        </div>
    </Vue3Marquee>
</template>

<script setup>
const avatarArray = [
    'https://avatars.dicebear.com/api/avataaars/1.svg',
    'https://avatars.dicebear.com/api/avataaars/2.svg',
    'https://avatars.dicebear.com/api/avataaars/3.svg',
    ...
]
</script>

Image marquee with pauseOnClick

You can also use the right click button to momentarily pause the animation. Hold the right click button to pause the animation. Releasing the mouse button will resume the animation. In this example the pauseOnClick prop is used.

If you need more functionality than this, using a carousel component might be better for your use case. Two that I would suggest are the vue3-carousel or egjs/vue-flicking.
<template>
    <Vue3Marquee :pause-on-click="true">
        <img
            v-for="img in imgArray"
            :key="img"
            :src="img"
        />
    </Vue3Marquee>
</template>

<script setup>
const imgArray = [
    'https://sponsors.vuejs.org/images/vueschool.avif',
    'https://sponsors.vuejs.org/images/vehikl.avif',
    'https://sponsors.vuejs.org/images/dronahq.avif',
    ...
]
</script>

Image marquee with animateOnOverflowOnly New

You can use the animateOnOverflowOnly prop to animate the marquee only when the content overflows the container. You can adjust the size of the window to see the effect.

This prop does not work with vertical marquee animations. Since a fixed height parent container is required for vertical animations, this feature is not supported.
The animation snaps back to the start when the content overflow is resolved. You can use the justify-content css property to control the alignment of the content in this instance.
You could try this system for items like stock tickers for a static on start but adding on more items as the content grows. This could also work for music players where the song title is displayed. The animation would only start when the song title is too long to fit in the container.
<template>
    <Vue3Marquee :animate-on-overflow-only="true">
        <img
            v-for="img in imgArray"
            :key="img"
            :src="img"
        />
    </Vue3Marquee>
    <button @click="addImages">Add images</button>
</template>

<script setup>
const allImages = [
    'https://sponsors.vuejs.org/images/vueschool.avif',
    'https://sponsors.vuejs.org/images/vehikl.avif',
    'https://sponsors.vuejs.org/images/dronahq.avif',
    ...
]

const imgArray = [
    'https://sponsors.vuejs.org/images/layer0.avif',
    'https://sponsors.vuejs.org/images/plaid__inc_.svg',
]

const addImages = () => {
    imgArray.value.push(
        allImages[Math.floor(Math.random() * allImages.length)],
        allImages[Math.floor(Math.random() * allImages.length)],
    )
}
</script>

Vertical marquee New

With this component you can also create a vertical marquee. This is useful if you want to create a vertical scrolling list of items.

You will need to put your marquee inside a parent container with a defined height. You can also use a fixed width if you want to limit the width of the marquee. The marquee component will otherwise take up the full width of the parent container.

Vertical marquees are still experimental. All props and events are supported, but there may be some bugs. Please open an issue if you find any.
All props (including clone) and events are supported for vertical marquees. The only difference is that the vertical prop needs to be set to true.
<template>
    <div style="height: 50px; width: max-content">
       <Vue3Marquee :vertical="true">
            <img
                :src="img"
                v-for="img in imgArray"
                :key="img"
            />
        </Vue3Marquee>
    </div>
</template>

<script setup>
const imgArray = [
    'https://sponsors.vuejs.org/images/vueschool.avif',
    'https://sponsors.vuejs.org/images/vehikl.avif',
    'https://sponsors.vuejs.org/images/dronahq.avif',
    ...
]
</script>

Listening for events

This animation is playing.

<template>
    <Vue3Marquee
        :pause-on-hover="true"
        @on-pause="playState = 'paused'"
        @on-resume="playState = 'playing'"
    >
        <div class="card" v-for="avatar in avatarArray" :key="avatar">
            <img :src="avatar" />
            <p>
                Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                tempor incididunt ut labore et dolore magna aliqua.
            </p>
        </div>
    </Vue3Marquee>
    <p>
        This animation is {{ playState }}.
    </p>
</template>

<script setup>
const playState = ref('playing')

const avatarArray = [
    'https://avatars.dicebear.com/api/avataaars/1.svg',
    'https://avatars.dicebear.com/api/avataaars/2.svg',
    'https://avatars.dicebear.com/api/avataaars/3.svg',
    ...
]
</script>

Cloning content

If your marquee content is too small to take the width of the full container it will leave an empty space.

You can use the clone prop to workaround this issue. With this option, vue3-marquee will automatically calculate the content and container widths and clone your content to fill the container completely.

This option is also responsive to the container width. If you resize the window, the content will be cloned again to fill the container.
<template>
    <Vue3Marquee :clone="true" :duration="5" :direction="'reverse'">
        <img
            v-for="img in imgArray"
            :key="img"
            :src="img"
        />
    </Vue3Marquee>
</template>

<script setup>
const imgArray = [
    'https://sponsors.vuejs.org/images/layer0.avif',
    'https://sponsors.vuejs.org/images/plaid__inc_.svg',
]
</script>

Disclaimer