# Logo Loop

> Draggable looping marquee of logos with a soft transparent fade, an intro, wave, arc and 3D orbit paths, a center lens, dock-style magnify, stepping, labels and tilt.

A seamless, endless strip of brand or tech logos. Hover it to pause, drag or swipe it to fling it, and tab through the links to bring each one into view. Pick a path (line, wave, arc or orbit), add a center lens or dock-style magnify, or step one logo at a time.

<demo-logo-loop>



</demo-logo-loop>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/logo-loop.json"
```

## Usage

```vue
<script setup lang="ts">
  import { LogoLoop } from '~/components/ui/logo-loop';
  import type { LogoItem } from '~/components/ui/logo-loop';

  const logos: LogoItem[] = [
    {
      icon: 'simple-icons:vuedotjs',
      title: 'Vue',
      href: 'https://vuejs.org',
      hoverColor: '#42b883',
    },
    { icon: 'simple-icons:nuxtdotjs', title: 'Nuxt', href: 'https://nuxt.com' },
    { src: '/logos/acme.svg', alt: 'Acme', href: 'https://acme.com' },
  ];
</script>

<template>
  <div class="relative h-50 w-full overflow-hidden">
    <LogoLoop
      :logos="logos"
      :speed="100"
      :logo-height="48"
      :gap="56"
      :hover-speed="0"
      layout="wave"
      labels="hover"
      scale-on-hover
      aria-label="Our tech stack"
    />
  </div>
</template>
```

Each logo is either `{ icon }` (any Iconify name, rendered with `<Icon>`) or `{ src, alt }` for an image. Both take an optional `title`, `href` and `hoverColor`. The fade is a mask, not a colored overlay, so it works on any background. Vertical loops (`direction="up"` or `"down"`) take the height of their parent.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        logos
      </code>
    </td>
    
    <td>
      <code>
        LogoItem[]
      </code>
    </td>
    
    <td>
      required
    </td>
    
    <td>
      Logos to show: <code>
        { icon }
      </code>
      
       or <code>
        { src, alt }
      </code>
      
      , each with optional <code>
        title
      </code>
      
      , <code>
        href
      </code>
      
       and <code>
        hover-color
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        120
      </code>
    </td>
    
    <td>
      Speed in pixels per second. Negative values reverse the direction.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        direction
      </code>
    </td>
    
    <td>
      <code>
        'left' | 'right' | 'up' | 'down'
      </code>
    </td>
    
    <td>
      <code>
        'left'
      </code>
    </td>
    
    <td>
      Which way the logos travel.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        width
      </code>
    </td>
    
    <td>
      <code>
        number | string
      </code>
    </td>
    
    <td>
      <code>
        '100%'
      </code>
    </td>
    
    <td>
      Width of the loop.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        logo-height
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        28
      </code>
    </td>
    
    <td>
      Height of each logo in pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        gap
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        32
      </code>
    </td>
    
    <td>
      Space between logos in pixels.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        hover-speed
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        undefined
      </code>
    </td>
    
    <td>
      Speed while hovered or while a logo has keyboard focus. <code>
        0
      </code>
      
       pauses, a small value slows. Pauses by default.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        pause-on-hover
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        undefined
      </code>
    </td>
    
    <td>
      Set to <code>
        false
      </code>
      
       to keep full speed on hover. Ignored when <code>
        hover-speed
      </code>
      
       is set.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade-out
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Fades the logos out softly at both ends with a transparent mask.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        fade-out-width
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.12
      </code>
    </td>
    
    <td>
      Size of each fade as a fraction of the length, from 0 to 0.5.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scale-on-hover
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Grows the hovered logo slightly.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        layout
      </code>
    </td>
    
    <td>
      <code>
        'line' | 'wave' | 'arc' | 'orbit'
      </code>
    </td>
    
    <td>
      <code>
        'line'
      </code>
    </td>
    
    <td>
      Path the logos travel along: a line, a wave, an arc, or a ring that turns in 3D.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        bend
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      How strongly the path bends, from -1 to 1 (wave height, arc curve, orbit tilt). Negative flips it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        focus
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      A center lens, from 0 to 1. Logos grow and make room as they pass the center; outer ones dim.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        magnify
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Dock-style magnify under the cursor, from 0 to 1. Nearby logos move aside.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-x
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Tilts the loop back or forward in 3D, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tilt-y
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Turns the loop to the side in 3D, in degrees.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        step
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Moves one logo at a time and pauses, centering each in turn. <code>
        speed
      </code>
      
       sets the pace.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        muted
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Greys out and dims logos until one is hovered or centered, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        labels
      </code>
    </td>
    
    <td>
      <code>
        'none' | 'inline' | 'below' | 'hover'
      </code>
    </td>
    
    <td>
      <code>
        'none'
      </code>
    </td>
    
    <td>
      Shows each title beside the logo, below it, or as a caption on hover or when centered.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        draggable
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Drag or swipe the loop and fling it. Links still open with a normal click.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        scroll-boost
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0
      </code>
    </td>
    
    <td>
      Speeds the loop up while the page scrolls and reverses it when scrolling up, from 0 to 1.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        intro
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Logos fade and rise in from left to right the first time the loop comes into view.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aria-label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'Partner logos'
      </code>
    </td>
    
    <td>
      Accessible name for the loop region.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the container.
    </td>
  </tr>
</tbody>
</table>

## Slots

<table>
<thead>
  <tr>
    <th>
      Slot
    </th>
    
    <th>
      Props
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        item
      </code>
    </td>
    
    <td>
      <code>
        { item, index, copy }
      </code>
    </td>
    
    <td>
      Replaces the default icon or image for each logo (React Bits' <code>
        renderItem
      </code>
      
      ).
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- The loop is a labelled `region` containing a list. Only one copy of the list is exposed to assistive tech; the repeats are `aria-hidden` and their links are removed from the tab order.
- Keyboard focus on a link pauses the loop and glides that logo into view; the focus ring uses `currentColor`.
- A drag never triggers a link click; a plain click still opens it.
- With `prefers-reduced-motion: reduce` the loop stops, the intro is skipped and transitions are disabled.
- Ported from [React Bits](https://reactbits.dev/animations/logo-loop) by David Haz.
