npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lyrics-scrolling

v0.1.16

Published

A Vue 3 + TypeScript lyrics scrolling library with LRC parsing utilities.

Readme

lyrics-scrolling 🎵

🌐 English

一个基于 Vue 3 + TypeScript 的 LRC 歌词滚动组件库。

如果要让 AI 工具基于本库生成或集成代码,请参考 AI 使用指引

📦 安装

vuepeer dependency,需要在使用方项目中一并安装。

npm

npm install lyrics-scrolling

pnpm

pnpm add lyrics-scrolling

bun

bun add lyrics-scrolling

🚀 使用方式

先引入组件 API 和样式文件:

import 'lyrics-scrolling/style.css';

基础组件用法

<script setup lang="ts">
import { computed, ref } from 'vue';
import { LyricsScroller, parseLrc } from 'lyrics-scrolling';

const currentTimeMs = ref(0);

const parsedLyrics = parseLrc(`[ti:Demo Song]
[ar:Codex]
[00:00.00]First line
[00:05.20]Second line`);

const lines = computed(() => parsedLyrics.lines);
</script>

<template>
  <LyricsScroller
    :lines="lines"
    :current-time-ms="currentTimeMs"
    align="center"
    highlight-mode="karaoke"
    karaoke-mode="width-fill"
    :karaoke-fallback-duration-ms="2200"
    highlight-color="#fff8eb"
    highlight-glow-color="rgba(255, 201, 105, 0.16)"
    scroll-mode="smooth"
  />
</template>

与原生 Audio 联动

useAudioPlaybackTime 是库层提供的 composable,用来把已有的 HTMLAudioElementplaybackTimeMs 同步起来。它会监听音频事件,在播放时用 requestAnimationFrame 做平滑同步,并提供播放、暂停、重置和拖动定位相关的辅助方法。

<script setup lang="ts">
import { computed, ref } from 'vue';
import {
  LyricsScroller,
  parseLrc,
  useAudioPlaybackTime,
} from 'lyrics-scrolling';
import 'lyrics-scrolling/style.css';

const audioElement = ref<HTMLAudioElement | null>(null);

const parsedLyrics = parseLrc(`[ti:Demo Song]
[ar:Codex]
[00:00.00]First line
[00:05.20]Second line`);

const totalDurationMs = computed(() => {
  const lastLine = parsedLyrics.lines.at(-1);
  return lastLine ? lastLine.timeMs + 2200 : 60_000;
});

const {
  isPlaying,
  playbackTimeMs,
  restartPlayback,
  seekToTimeMs,
  timelineMaxMs,
  togglePlayback,
} = useAudioPlaybackTime({
  audioElement,
  fallbackMaxTimeMs: totalDurationMs,
});

function handleTimelineInput(event: Event): void {
  seekToTimeMs(Number((event.target as HTMLInputElement).value));
}
</script>

<template>
  <audio ref="audioElement" controls preload="metadata" />

  <button type="button" @click="togglePlayback">
    {{ isPlaying ? 'Pause' : 'Play' }}
  </button>
  <button type="button" @click="restartPlayback">Reset</button>

  <input
    :value="playbackTimeMs"
    type="range"
    min="0"
    :max="timelineMaxMs"
    step="10"
    @input="handleTimelineInput"
  />

  <LyricsScroller
    :lines="parsedLyrics.lines"
    :current-time-ms="playbackTimeMs"
    highlight-mode="karaoke"
    karaoke-mode="width-fill"
  />
</template>

🎛 显示模式

  • align="center":当前歌词行保持垂直居中。
  • align="start":当前歌词行靠近顶部显示。
  • highlight-mode="line":使用整行高亮。
  • highlight-mode="karaoke":仅对当前激活行做 karaoke 填充高亮。
  • karaoke-mode="width-fill":按宽度连续填充,允许单个字被部分填亮。
  • karaoke-mode="char-step":按字符离散推进高亮,使用 grapheme 分段。
  • scroll-mode="smooth":按 scrollDurationMs 做平滑滚动。
  • scroll-mode="step":直接跳到下一行,不做过渡动画。

🧩 组件属性

  • lines:解析后的歌词行数组。
  • currentTimeMs:当前播放时间,单位毫秒。
  • align'center' | 'start'
  • highlightMode'line' | 'karaoke'
  • karaokeMode'width-fill' | 'char-step'
  • karaokeFallbackDurationMs:当前行没有可用下一时间戳时的回退时长,最后一行同样使用这个值。
  • highlightColor:整行高亮或 karaoke 填充时的高亮颜色。
  • highlightGlowColor:整行高亮或 karaoke 填充时的辉光颜色。
  • scrollMode'smooth' | 'step'
  • visibleLineCount:可视区域内显示的歌词行数。
  • lineHeight:每行高度,单位像素。
  • inactiveOpacity:非激活行透明度。
  • scrollDurationMs:平滑滚动模式下的位移动画时长。
  • hideEmptyLines:是否隐藏带时间戳的空白歌词行。
  • placeholder:无歌词时的占位文案。

Composable API

useAudioPlaybackTime(options)

参数:

  • audioElementRef<HTMLAudioElement | null>,外部传入的原生音频元素引用。
  • fallbackMaxTimeMsnumber | Ref<number> | (() => number),在音频元数据尚未可用时,用作 timeline 上限的回退值。

返回值:

  • isPlaying:音频是否处于播放状态。
  • playbackTimeMs:当前同步后的播放时间,单位毫秒。
  • timelineMaxMs:拖动和时间轴可用的最大值。
  • togglePlayback():播放或暂停已绑定的音频元素。
  • restartPlayback():暂停并跳回 0
  • seekToTimeMs(timeMs):拖动定位并同步响应式时间。

📝 LRC 解析行为

  • 支持 [ti:][ar:][al:][by:][offset:] 等元信息标签。
  • 支持同一行包含多个时间标签。
  • 保留带时间戳的空白歌词行,方便参与时间同步。
  • 会把 LRC 中的 offset 应用到最终解析结果中。