You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

react-native-lyric如何实现歌词逐字绿色高亮播放效果

逐字高亮歌词实现方案

逐字高亮效果参考

核心逻辑:你当前使用的歌词组件仅支持行级激活状态,没有内置逐字渲染能力,要实现参考动图的卡拉OK效果,需要在自定义行渲染函数里自行拆分单字做状态判断,具体实现步骤如下:

  • 前置准备:逐字高亮的精准度依赖时间戳精度,如果有带逐字时间标签的歌词数据(比如KRC格式转换后的逐字歌词)效果最好;如果只有普通行级LRC歌词,可以按行总时长平均分配每个字的播放时间,实现近似效果。
  • 行渲染改造:非当前播放行直接渲染整行灰色文字即可,当前激活行把整句歌词拆成单字数组,结合全局播放进度currentTime判断每个字是否已经播放完成,播放完成的字设置为绿色,未播放的保持灰色。
  • 丝滑效果优化:如果要实现动图里逐字扫过、不是整字突然变色的效果,可以给正在播放的单字加一层同内容的绿色文字遮罩,用动画驱动遮罩宽度从0到100%增长,配合overflow: hidden就能实现颜色从左到右平滑过渡的效果。

基础实现代码

以下是基于你现有代码改造的基础版本,采用行时长平均分配的方案,如果你有逐字时间戳,替换掉单字时间计算逻辑即可:

<Lyric
  style={{ height: 500 }}
  lrc={lrc}
  currentTime={this.state.currentTime}
  lineHeight={40}
  activeLineHeight={50}
  lineRenderer={({
    lrcLine: { millisecond, content },
    index,
    active,
  }) => {
    // 非激活行直接渲染灰色文字
    if (!active) {
      return (
        <Text
          style={{
            fontSize: 30,
            textAlign: "center",
            color:  "gray",
          }}
        >
          {content}
        </Text>
      )
    }

    // 计算当前行总时长:取下一行起始时间作为当前行结束时间,最后一行兜底3秒
    const currentLineEnd = parsedLrcList[index + 1] 
      ? parsedLrcList[index + 1].millisecond 
      : millisecond + 3000
    const lineTotalDuration = currentLineEnd - millisecond
    const charArray = content.split('')
    const perCharDuration = lineTotalDuration / charArray.length

    // 逐字渲染判断高亮状态
    return (
      <Text style={{ fontSize: 30, textAlign: "center" }}>
        {charArray.map((char, charIndex) => {
          const charEndTime = millisecond + (charIndex + 1) * perCharDuration
          const isPlayed = this.state.currentTime >= charEndTime
          return (
            <Text 
              key={charIndex}
              style={{ color: isPlayed ? '#22c55e' : 'gray' }}
            >
              {char}
            </Text>
          )
        })}
      </Text>
    )
  }}
/>

注意:代码里的parsedLrcList是你把LRC文本解析后得到的行数组,结构和组件回调里的lrcLine一致,为[{millisecond: 数字时间戳, content: 歌词文本}]格式,你可以用任意LRC解析工具提前解析好传入。

进阶平滑效果实现思路

如果要完全匹配参考动图的扫字效果,不要用整字切换颜色的逻辑:

  • 每个激活行的底层渲染整行灰色文字
  • 上层盖一个overflow: hidden的同尺寸容器,内部放整行绿色文字
  • 用当前播放时间计算当前行的播放进度,驱动上层容器的宽度从0到整行宽度线性增长,就能实现字从左到右逐像素变绿的丝滑效果,性能比逐字做动画更好。

内容的提问来源于stack exchange,提问作者user998405

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:21:37