Skip to content

Commit

Permalink
添加滚动,切换两种歌词显示
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaohuohumax committed Mar 5, 2024
1 parent a05ce26 commit 9150e6a
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 98 deletions.
5 changes: 5 additions & 0 deletions .changeset/nasty-snakes-matter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lrc/example-vue": patch
---

添加滚动,切换的简单歌词显示 Demo
2 changes: 2 additions & 0 deletions examples/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"dependencies": {
"@xiaohuohumax/lrc-parser": "workspace:^",
"@xiaohuohumax/lrc-util": "workspace:^",
"bootstrap": "^5.3.3",
"sass": "^1.71.1",
"vue": "^3.4.19"
},
"devDependencies": {
Expand Down
114 changes: 32 additions & 82 deletions examples/vue/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,91 +1,41 @@
<template>
<div class="info">
<pre>{{ lrcSource }}</pre>
<pre>{{ lrcUtil.getLrc() }}</pre>
</div>
<div class="controls">
<audio ref="audio" :src="musicUrl" controls></audio>
<div class="lyrics">
<div v-html="lyricsHtml(nowLyric)"></div>
<div v-html="lyricsHtml(nextLyric)"></div>
<div class="h3 text-center mt-4">LRC歌词解析器简单使用</div>
<div class="d-flex fs-6 m-4">
<div class="w-25 flex-grow-1">
<div class="card p-4 mb-4">
<div class="h4">切换</div>
<hr>
<HandoverLyrics />
</div>
<div class="card p-4">
<div class="h4">滚动</div>
<hr>
<RollLyrics />
</div>
</div>
<div class="me-4"></div>
<div class="w-25 flex-grow-1">
<div class="card p-4 mb-4">
<div class="h4">LRC数据</div>
<hr>
<pre style="height:15em;">{{ lrcSource }}</pre>
</div>
<div class="card p-4">
<div class="h4">解析结果</div>
<hr>
<pre style="height:30em;">{{ lrc }}</pre>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import lrcSource from './assets/lrc/The Myth.lrc?raw';
import musicUrl from './assets/music/The Myth.mp3';
import { LrcUtil, Lyric } from '@xiaohuohumax/lrc-util';
import HandoverLyrics from './component/HandoverLyrics.vue';
import RollLyrics from './component/RollLyrics.vue';
import lrcSource from '@/assets/lrc/The Myth.lrc?raw';
import { LrcUtil } from '@xiaohuohumax/lrc-util';
const lrcUtil = new LrcUtil(lrcSource, { fuzzy: true, parserConfig: { lyricAddOffset: true } });
const audio = ref<HTMLAudioElement>(null!);
const nowLyric = ref<Lyric>();
const nextLyric = ref<Lyric>();
const tagMap = {
M: '', F: '', D: '合唱'
};
function lyricsHtml(lyric: Lyric | undefined) {
let res = '';
if (lyric) {
res = `[${lyric.time}]: ${lyric.lyric}`;
if (lyric.tag) {
res = tagMap[lyric.tag] + res;
}
}
return res;
}
onMounted(() => audio.value.addEventListener('timeupdate', () => {
const time = audio.value.currentTime * 1000;
lrcUtil.setTime(time);
nowLyric.value = lrcUtil.getLyric();
nextLyric.value = lrcUtil.getNextLyric();
}));
</script>

<style scoped>
.info {
display: flex;
margin: 5em;
font-size: 1.25em;
font-weight: 800;
}
.info pre {
flex: 1 1;
}
.controls {
position: fixed;
bottom: 0;
width: 100svw;
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
padding: 1em 10em;
background: rgba(0, 0, 0, 0.5);
font-size: 1.5em;
color: white;
}
.lyrics {
margin-top: 1em;
width: 100%;
}
.lyrics div:first-child {
text-align: left;
}
.lyrics div:last-child {
text-align: right;
}
</style>
const lrc = lrcUtil.getLrc();
</script>
37 changes: 37 additions & 0 deletions examples/vue/src/component/HandoverLyrics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<template>
<div class="controls text-lg">
<audio class="w-100" ref="audio" :src="musicUrl" controls></audio>
<div class="lyrics mt-4">
<div v-html="lyricsHtml(nowLyric)"></div>
<div class="text-end" v-html="lyricsHtml(nextLyric)"></div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import lrcSource from '@/assets/lrc/The Myth.lrc?raw';
import musicUrl from '@/assets/music/The Myth.mp3';
import { lyricsHtml } from '../util/lyricTag';
import { LrcUtil, Lyric } from '@xiaohuohumax/lrc-util';
const lrcUtil = new LrcUtil(lrcSource, { fuzzy: true, parserConfig: { lyricAddOffset: true } });
const audio = ref<HTMLAudioElement>(null!);
const nowLyric = ref<Lyric>();
const nextLyric = ref<Lyric>();
function timeUpdate() {
const time = audio.value.currentTime * 1000;
lrcUtil.setTime(time);
nowLyric.value = lrcUtil.getLyric();
nextLyric.value = lrcUtil.getNextLyric();
}
onMounted(() => {
timeUpdate();
audio.value.addEventListener('timeupdate', timeUpdate);
});
</script>
78 changes: 78 additions & 0 deletions examples/vue/src/component/RollLyrics.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template>
<div class="controls">
<audio class="w-100" ref="audio" :src="musicUrl" controls></audio>
<div ref="lyricsMain" class="card overflow-y-hidden position-relative mt-4" style="height:20em;">
<div ref="lyricBody" class="lyric-body w-100 position-absolute text-center fw-blod">
<div ref="items" :class="lyric.tag?.toLocaleLowerCase()" :id="lyric.time + ''" class="item mt-2"
v-for="lyric in lrc.lyrics.filter(l => l.lyric != '')" :key="lyric.time">
{{ lyricsHtml(lyric) }}
</div>
</div>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import lrcSource from '@/assets/lrc/The Myth.lrc?raw';
import musicUrl from '@/assets/music/The Myth.mp3';
import { lyricsHtml } from '../util/lyricTag';
import { LrcUtil, Lyric } from '@xiaohuohumax/lrc-util';
const lrcUtil = new LrcUtil(lrcSource, { fuzzy: true, parserConfig: { lyricAddOffset: true } });
const audio = ref<HTMLAudioElement>(null!);
const lyricsMain = ref<HTMLDivElement>(null!);
const lyricBody = ref<HTMLDivElement>(null!);
const items = ref<HTMLDivElement[]>(null!);
const lrc = lrcUtil.getLrc();
const nowLyric = ref<Lyric>(null!);
onMounted(() => {
const bodyHeight = lyricsMain.value.clientHeight;
lyricBody.value.style.top = bodyHeight / 2 + 'px';
watch(() => nowLyric.value, () => {
if (nowLyric.value.lyric == '') {
return;
}
items.value.forEach(item => item.classList.remove('now'));
const nowItem = items.value.find(item => item.id == nowLyric.value.time + '');
if (nowItem) {
nowItem?.classList.add('now');
lyricBody.value.style.top = (-1 * nowItem.offsetTop + bodyHeight / 2 - nowItem.clientHeight / 2) + 'px';
}
});
audio.value.addEventListener('timeupdate', () => {
lrcUtil.setTime(audio.value.currentTime * 1000);
nowLyric.value = lrcUtil.getLyric();
});
});
</script>

<style scoped>
.lyric-body {
animation: top 1s ease-in-out;
transition: all 1s;
}
.item {
transition: all .5s ease-in-out;
opacity: .4;
}
.now {
font-size: 1.2em !important;
color: red;
opacity: 1;
}
</style>
3 changes: 2 additions & 1 deletion examples/vue/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { createApp } from 'vue';
import App from './App.vue';
import './styles.css';

import './styles.sass';

createApp(App).mount('#app');
5 changes: 0 additions & 5 deletions examples/vue/src/styles.css

This file was deleted.

1 change: 1 addition & 0 deletions examples/vue/src/styles.sass
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import "bootstrap/scss/bootstrap"
16 changes: 16 additions & 0 deletions examples/vue/src/util/lyricTag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Lyric } from '@xiaohuohumax/lrc-util';

const tagMap = {
M: '男', F: '女', D: '合唱'
};

export function lyricsHtml(lyric: Lyric | undefined) {
let res = '';
if (lyric) {
res = `[${lyric.time}]: ${lyric.lyric}`;
if (lyric.tag) {
res = tagMap[lyric.tag] + res;
}
}
return res;
}
3 changes: 3 additions & 0 deletions examples/vue/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
"types": [
"vite/client"
],
/* Linting */
"strict": true,
"noUnusedLocals": true,
Expand Down
6 changes: 6 additions & 0 deletions examples/vue/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import path from 'node:path';

// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': path.resolve(__dirname, 'src')
}
}
});
Loading

0 comments on commit 9150e6a

Please sign in to comment.