修改桌面歌词为逐字播放

pull/459/head
lyswhut 2021-03-02 18:10:12 +08:00
parent 040fcfba4f
commit aef0ffa506
6 changed files with 152 additions and 53 deletions

14
package-lock.json generated
View File

@ -5084,7 +5084,7 @@
},
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
"resolved": "https://registry.npm.taobao.org/buffer-crc32/download/buffer-crc32-0.2.13.tgz",
"integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
"dev": true
},
@ -8736,7 +8736,7 @@
},
"fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"resolved": "https://registry.npm.taobao.org/fd-slicer/download/fd-slicer-1.1.0.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
"dev": true,
"requires": {
@ -12191,7 +12191,7 @@
},
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
"resolved": "https://registry.npm.taobao.org/pend/download/pend-1.2.0.tgz",
"integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
"dev": true
},
@ -12208,7 +12208,7 @@
},
"pify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
"resolved": "https://registry.npm.taobao.org/pify/download/pify-3.0.0.tgz",
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
"dev": true,
"optional": true
@ -13076,7 +13076,7 @@
},
"proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
"resolved": "https://registry.npm.taobao.org/proto-list/download/proto-list-1.2.4.tgz",
"integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=",
"dev": true,
"optional": true
@ -14095,7 +14095,7 @@
},
"semver-compare": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz",
"resolved": "https://registry.npm.taobao.org/semver-compare/download/semver-compare-1.0.0.tgz",
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
"dev": true,
"optional": true
@ -17808,7 +17808,7 @@
},
"yauzl": {
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"resolved": "https://registry.npm.taobao.org/yauzl/download/yauzl-2.10.0.tgz",
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
"dev": true,
"requires": {

View File

@ -1,7 +1,8 @@
<template lang="pug">
div(:class="[$style.lyric, lyricEvent.isMsDown ? $style.draging : null]" :style="lrcStyles" @wheel="handleWheel" @mousedown="handleLyricMouseDown" ref="dom_lyric")
div(:class="$style.lyricSpace")
div(v-for="(info, index) in lyricLines" :key="index" :class="[$style.lineContent, lyric.line == index ? (lrcConfig.style.isZoomActiveLrc ? $style.lrcActiveZoom : $style.lrcActive) : null]")
div(:class="[$style.lyricText]" ref="dom_lyric_text")
//- div(v-for="(info, index) in lyricLines" :key="index" :class="[$style.lineContent, lyric.line == index ? (lrcConfig.style.isZoomActiveLrc ? $style.lrcActiveZoom : $style.lrcActive) : null]")
p(:class="$style.lrcLine") {{info.text}}
div(:class="$style.lyricSpace")
</template>
@ -9,7 +10,7 @@ div(:class="[$style.lyric, lyricEvent.isMsDown ? $style.draging : null]" :style=
<script>
import { rendererOn, rendererSend, NAMES } from '../../../common/ipc'
import { scrollTo } from '../../../renderer/utils'
import Lyric from 'lrc-file-parser'
import Lyric from '@renderer/utils/lyric-font-player'
let cancelScrollFn = null
@ -65,6 +66,7 @@ export default {
lyrics: {
lyric: '',
tlyric: '',
lxlyric: '',
},
}
},
@ -85,7 +87,7 @@ export default {
if (n.length) {
this.lyricLines = n
this.$nextTick(() => {
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('.lrc-content')
this.handleScrollLrc()
})
} else {
@ -97,7 +99,7 @@ export default {
if (this.lyricLines === this._lyricLines && this._lyricLines.length) return
this.lyricLines = this._lyricLines
this.$nextTick(() => {
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('.lrc-content')
this.handleScrollLrc()
})
}, 50)
@ -105,7 +107,7 @@ export default {
} else {
this.lyricLines = n
this.$nextTick(() => {
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('p')
this.dom_lines = this.$refs.dom_lyric.querySelectorAll('.lrc-content')
this.handleScrollLrc()
})
}
@ -129,6 +131,10 @@ export default {
created() {
rendererOn(NAMES.winLyric.set_lyric_info, (event, data) => this.handleSetInfo(data))
window.lrc = new Lyric({
className: 'lrc-content',
shadowClassName: 'shadow',
shadowContent: true,
activeLineClassName: 'active',
onPlay: (line, text) => {
this.lyric.text = text
this.lyric.line = line
@ -136,6 +142,12 @@ export default {
},
onSetLyric: lines => { // listening lyrics seting event
// console.log(lines) // lines is array of all lyric text
this.$refs.dom_lyric_text.textContent = ''
const dom_lines = document.createDocumentFragment()
for (const line of lines) {
dom_lines.appendChild(line.dom_line)
}
this.$refs.dom_lyric_text.appendChild(dom_lines)
this.lyric.lines = lines
this.lyric.line = 0
},
@ -159,6 +171,7 @@ export default {
case 'lyric':
this.lyrics.lyric = data.lrc
this.lyrics.tlyric = data.tlrc
this.lyrics.lxlyric = data.lxlrc
this.setLyric()
break
case 'play':
@ -171,8 +184,9 @@ export default {
break
case 'info':
// console.log('info', data)
this.lyrics.lyric = data.lyric
this.lyrics.tlyric = data.tlyric
this.lyrics.lyric = data.lrc
this.lyrics.tlyric = data.tlrc
this.lyrics.lxlyric = data.lxlrc
this.setLyric()
this.$nextTick(() => {
this.lyric.line = data.line
@ -279,7 +293,10 @@ export default {
rendererSend(NAMES.winLyric.close)
},
setLyric() {
window.lrc.setLyric((this.isShowLyricTransition && this.lyrics.tlyric ? (this.lyrics.tlyric + '\n') : '') + (this.lyrics.lyric || ''))
window.lrc.setLyric(
this.lyrics.lxlyric ? this.lyrics.lxlyric : this.lyrics.lyric,
// (this.isShowLyricTransition && this.lyrics.tlyric ? (this.lyrics.tlyric + '\n') : '') + (this.lyrics.lyric || ''),
)
},
},
}
@ -292,34 +309,77 @@ export default {
text-align: center;
height: 100%;
overflow: hidden;
font-size: 68px;
padding: 0 5px;
opacity: .6;
transition: opacity @transition-theme;
font-size: 16px;
cursor: grab;
color: @color-theme-lyric;
&.draging {
.lrc-line {
cursor: grabbing;
cursor: grabbing;
}
:global {
.lrc-content {
line-height: 1.2;
margin: 16px 0;
overflow-wrap: break-word;
.line {
transition-property: font-size, color !important;
background: none !important;
-webkit-text-fill-color: unset;
// -webkit-text-fill-color: none !important;
}
&.active {
.line {
color: @color-theme;
}
span {
// color: @color-theme;
font-size: 1.2em;
}
}
span {
transition: @transition-theme !important;
transition-property: font-size !important;
font-size: 1em;
background-repeat: no-repeat;
background-color: @color-theme-lyric;
background-image: -webkit-linear-gradient(top, @color-theme, @color-theme);
-webkit-text-fill-color: transparent;
-webkit-background-clip: text;
background-size: 0 100%;
}
}
.shadow {
text-shadow: 1px 1px 2px rgb(32, 32, 32);
}
}
// p {
// padding: 8px 0;
// line-height: 1.2;
// overflow-wrap: break-word;
// transition: @transition-theme !important;
// transition-property: color, font-size;
// }
}
.lrc-line {
display: inline-block;
padding: 8px 0;
line-height: 1.2;
overflow-wrap: break-word;
transition: @transition-theme;
transition-property: color, font-size, text-shadow;
cursor: grab;
// font-weight: bold;
// background-clip: text;
color: @color-theme-lyric;
text-shadow: 1px 1px 2px #000;
// background: linear-gradient(@color-theme-lyric, @color-theme-lyric);
// background-clip: text;
// -webkit-background-clip: text;
// -webkit-text-fill-color: #fff;
// -webkit-text-stroke: thin #124628;
}
// .lrc-line {
// display: inline-block;
// padding: 8px 0;
// line-height: 1.2;
// overflow-wrap: break-word;
// transition: @transition-theme;
// transition-property: color, font-size, text-shadow;
// cursor: grab;
// // font-weight: bold;
// // background-clip: text;
// color: @color-theme-lyric;
// text-shadow: 1px 1px 2px #000;
// // background: linear-gradient(@color-theme-lyric, @color-theme-lyric);
// // background-clip: text;
// // -webkit-background-clip: text;
// // -webkit-text-fill-color: #fff;
// // -webkit-text-stroke: thin #124628;
// }
.lyric-space {
height: 70%;
}
@ -348,14 +408,30 @@ export default {
each(@themes, {
:global(#container.@{value}) {
.lrc-line {
color: ~'@{color-@{value}-theme-lyric}';
}
// .lrc-line {
// color: ~'@{color-@{value}-theme-lyric}';
// }
.lrc-active, .lrc-active-zoom {
.lrc-line {
color: ~'@{color-@{value}-theme-lyric_2}';
}
}
.lyric {
color: ~'@{color-@{value}-theme-lyric}';
:global {
.lrc-content {
&.active {
.line {
color: ~'@{color-@{value}-theme}';
}
}
span {
// background-color: ~'@{color-@{value}-theme_2-font}';
background-image: -webkit-linear-gradient(top, ~'@{color-@{value}-theme}', ~'@{color-@{value}-theme}');
}
}
}
}
}
})

View File

@ -215,8 +215,9 @@ export default {
singer: this.musicInfo.singer,
name: this.musicInfo.name,
album: this.musicInfo.album,
lyric: this.musicInfo.lrc,
tlyric: this.musicInfo.tlrc,
lrc: this.musicInfo.lrc,
tlrc: this.musicInfo.tlrc,
lxlrc: this.musicInfo.lxlrc,
isPlay: this.isPlay,
line: this.lyric.line,
played_time: audio.currentTime * 1000,
@ -648,7 +649,7 @@ export default {
}).catch(() => {
this.status = this.statusText = this.$t('core.player.lyric_error')
}).finally(() => {
this.handleUpdateWinLyricInfo('lyric', { lrc: this.musicInfo.lrc, tlrc: this.musicInfo.tlrc })
this.handleUpdateWinLyricInfo('lyric', { lrc: this.musicInfo.lrc, tlrc: this.musicInfo.tlrc, lxlrc: this.musicInfo.lxlrc })
this.setLyric()
})
},

View File

@ -579,16 +579,26 @@ export default {
overflow: hidden;
font-size: 16px;
cursor: grab;
color: @color-theme_2-font;
&.draging {
cursor: grabbing;
}
:global {
.lrc-content {
line-height: 1.2;
padding: 8px 0;
margin: 16px 0;
overflow-wrap: break-word;
.line {
transition-property: font-size, color !important;
background: none !important;
-webkit-text-fill-color: unset;
// -webkit-text-fill-color: none !important;
}
&.active {
.line {
color: @color-theme;
}
span {
// color: @color-theme;
font-size: 1.2em;
@ -597,7 +607,7 @@ export default {
span {
transition: @transition-theme !important;
transition-property: font-size;
transition-property: font-size !important;
font-size: 1em;
background-repeat: no-repeat;
background-color: rgba(77, 77, 77, 0.9);
@ -810,11 +820,18 @@ each(@themes, {
box-shadow: 0 0 4px ~'@{color-@{value}-theme-hover}';
// border-color: ~'@{color-@{value}-theme-hover}';
}
:global {
.lrc-content {
span {
// background-color: ~'@{color-@{value}-theme_2-font}';
background-image: -webkit-linear-gradient(top, ~'@{color-@{value}-theme}', ~'@{color-@{value}-theme}');
.lyric {
:global {
.lrc-content {
&.active {
.line {
color: ~'@{color-@{value}-theme}';
}
}
span {
// background-color: ~'@{color-@{value}-theme_2-font}';
background-image: -webkit-linear-gradient(top, ~'@{color-@{value}-theme}', ~'@{color-@{value}-theme}');
}
}
}
}

View File

@ -20,10 +20,11 @@ const createAnimation = (dom, duration) => new window.Animation(new window.Keyfr
// https://jsfiddle.net/ceqpnbky/1/
module.exports = class FontPlayer {
constructor({ lyric = '', className = '', shadowContent = false, shadowClassName = '' }) {
constructor({ lyric = '', className = '', lineModeClassName = '', shadowContent = false, shadowClassName = '' }) {
this.lyric = lyric
this.className = className
this.lineModeClassName = lineModeClassName
this.shadowContent = shadowContent
this.shadowClassName = shadowClassName
@ -100,6 +101,7 @@ module.exports = class FontPlayer {
this.isLineMode = true
const dom = document.createElement('span')
let shadowDom
dom.classList.add(this.lineModeClassName)
dom.textContent = this.lyric
if (this.shadowContent) {
shadowDom = document.createElement('span')

View File

@ -9,6 +9,7 @@ module.exports = class Lyric {
offset = 150,
className = '',
activeLineClassName = 'active',
lineModeClassName = 'line',
shadowClassName = '',
shadowContent = false,
onPlay = function() { },
@ -21,6 +22,7 @@ module.exports = class Lyric {
this.className = className
this.activeLineClassName = activeLineClassName
this.lineModeClassName = lineModeClassName
this.shadowClassName = shadowClassName
this.shadowContent = shadowContent
@ -98,6 +100,7 @@ module.exports = class Lyric {
const fontPlayer = new FontPlayer({
lyric: line.text,
className: this.className,
lineModeClassName: this.lineModeClassName,
shadowClassName: this.shadowClassName,
shadowContent: this.shadowContent,
})