Skip to content

SeamlessScroll 无缝滚动

高性能的无缝循环滚动容器,适用于大屏看板、公告轮播、榜单、合作伙伴 Logo 墙等场景。

为什么流畅

动画循环完全绕开 Vue 响应式(每帧直接写 transform,组件零重渲染)、translate3d 走 GPU 合成、速度按 px/秒 计算与刷新率无关、离开视口自动暂停(IntersectionObserver)、内容尺寸变化自动重测(ResizeObserver)。

基础用法

组件尺寸由父容器决定;把列表放进默认插槽即可,内容超出容器时自动开始滚动,悬停暂停(默认开启)。

  • 🎉 sh-design 0.0.4 发布:新增 SeamlessScroll 无缝滚动
  • 📈 ShLazyImage 支持 loader / 视口懒加载 / 轮询刷新
  • 🚀 文档站已部署至 GitHub Pages,欢迎 Star
  • 🧩 组件按需引入,全量 gzip 仅 ~9KB
  • 🔧 发布流程支持 OIDC Trusted Publishing
vue
<script setup lang="ts">
import { ShSeamlessScroll } from 'sh-design'

const news = ['公告一', '公告二', '公告三', '公告四', '公告五']
</script>

<template>
  <div style="height: 150px">
    <ShSeamlessScroll :speed="40">
      <ul>
        <li v-for="item in news" :key="item">{{ item }}</li>
      </ul>
    </ShSeamlessScroll>
  </div>
</template>

横向滚动

direction 支持 up / down / left / right。横向时插槽内容需要是横向布局(如 display: flex)。本例内容未超出容器,所以用 force 强制滚动。

VueViteTypeScriptVitePresspnpmESLintPrettier
vue
<template>
  <div style="height: 44px">
    <ShSeamlessScroll direction="left" :speed="60" force>
      <div style="display: flex; gap: 12px">
        <span v-for="l in logos" :key="l">{{ l }}</span>
      </div>
    </ShSeamlessScroll>
  </div>
</template>

步进滚动

single-step 设置为一行的高度,即可实现「滚一行 → 停一会」的公告栏效果,停顿时长由 single-wait 控制。

🎉 sh-design 0.0.4 发布:新增 SeamlessScroll 无缝滚动
📈 ShLazyImage 支持 loader / 视口懒加载 / 轮询刷新
🚀 文档站已部署至 GitHub Pages,欢迎 Star
🧩 组件按需引入,全量 gzip 仅 ~9KB
🔧 发布流程支持 OIDC Trusted Publishing
vue
<template>
  <!-- 每行 38px:滚 38px 停 1.5s -->
  <div style="height: 38px">
    <ShSeamlessScroll :speed="120" :single-step="38" :single-wait="1500">
      <div v-for="item in news" :key="item" style="height: 38px">{{ item }}</div>
    </ShSeamlessScroll>
  </div>
</template>

启停与调速

active 可动态启停;speed 是 px/秒,可实时调整。

  • 🎉 sh-design 0.0.4 发布:新增 SeamlessScroll 无缝滚动
  • 📈 ShLazyImage 支持 loader / 视口懒加载 / 轮询刷新
  • 🚀 文档站已部署至 GitHub Pages,欢迎 Star
  • 🧩 组件按需引入,全量 gzip 仅 ~9KB
  • 🔧 发布流程支持 OIDC Trusted Publishing
vue
<template>
  <button @click="active = !active">{{ active ? '暂停' : '继续' }}</button>
  <div style="height: 120px">
    <ShSeamlessScroll :active="active" :speed="speed" :hover-pause="false">
      <ul>...</ul>
    </ShSeamlessScroll>
  </div>
</template>

悬停滚轮手动滚动

开启 wheel 后,鼠标悬停(自动滚动已暂停)时可用滚轮上下翻看,滚到头会无缝循环衔接;离开后从当前位置继续自动滚。悬停期间页面不会跟着滚动。

  • 🎉 sh-design 0.0.4 发布:新增 SeamlessScroll 无缝滚动
  • 📈 ShLazyImage 支持 loader / 视口懒加载 / 轮询刷新
  • 🚀 文档站已部署至 GitHub Pages,欢迎 Star
  • 🧩 组件按需引入,全量 gzip 仅 ~9KB
  • 🔧 发布流程支持 OIDC Trusted Publishing
vue
<template>
  <div style="height: 150px">
    <ShSeamlessScroll :speed="40" wheel>
      <ul>...</ul>
    </ShSeamlessScroll>
  </div>
</template>

与 vue3-seamless-scroll 的差异

vue3-seamless-scrollShSeamlessScroll
每帧更新方式响应式 offset → 组件重渲染直接写 DOM transform,零重渲染
合成方式translateY + transition 叠加translate3d + will-change,纯 GPU 合成
速度基准px/帧(高刷屏更快)px/秒(任何刷新率一致)
离屏行为持续滚动IntersectionObserver 自动暂停
内容变化需手动调 reset/add/removeResizeObserver 自动重测
数据传入list prop + 作用域插槽直接写默认插槽,自由布局

API

Props

属性说明类型默认值
direction滚动方向'up' | 'down' | 'left' | 'right''up'
speed滚动速度(px/秒,与刷新率无关)number40
active是否滚动(可动态启停)booleantrue
hover-pause鼠标悬停时暂停booleantrue
wheel悬停时允许滚轮手动滚动(建议搭配 hover-pausebooleanfalse
force内容未超出容器时也强制滚动booleanfalse
single-step单步滚动距离(px),> 0 启用步进模式number0
single-wait步进模式每步停顿时长(ms)number1000
delay开始滚动前的延迟(ms)number0

Events

事件名说明回调参数
loop完整滚过一轮内容时触发(count: number) 累计轮数

Slots

插槽名说明
default滚动内容(组件会自动复制以实现无缝衔接)

Expose

方法说明
reset()回到起点并清零轮数

使用注意

  • 组件自身 width/height: 100%父容器必须有确定的尺寸
  • 插槽内容会被复制 1~N 份用于无缝衔接,避免在插槽内使用带唯一 id 的元素
  • 内容未超出容器时默认不滚动(避免无意义动画),需要时用 force 强制开启。

Released under the MIT License.