From 6f21871645f389d74cd81b281c624e6c680b0305 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:16:05 +0800 Subject: [PATCH 01/22] =?UTF-8?q?chore:=20=E5=BC=95=E5=85=A5=20@applemusic?= =?UTF-8?q?-like-lyrics=20=E4=B8=8E=E7=9B=B8=E5=85=B3=E4=BE=9D=E8=B5=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 9 ++ pnpm-lock.yaml | 326 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 335 insertions(+) diff --git a/package.json b/package.json index 4281078..99d8269 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,17 @@ "docs:preview": "vitepress preview docs" }, "dependencies": { + "@applemusic-like-lyrics/core": "^0.5.1", + "@applemusic-like-lyrics/lyric": "^1.0.1", "@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/utils": "^4.0.0", + "@pixi/app": "^7.4.3", + "@pixi/core": "^7.4.3", + "@pixi/display": "^7.4.3", + "@pixi/filter-blur": "^7.4.3", + "@pixi/filter-bulge-pinch": "^5.1.1", + "@pixi/filter-color-matrix": "^7.4.3", + "@pixi/sprite": "^7.4.3", "@hono/node-server": "^2.0.2", "@material/material-color-utilities": "^0.4.0", "@vueuse/core": "^14.2.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d6a0af1..a6283d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@applemusic-like-lyrics/core': + specifier: ^0.5.1 + version: 0.5.1(@pixi/app@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))(@pixi/filter-blur@7.4.3(@pixi/core@7.4.3))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.3))(@pixi/filter-color-matrix@7.4.3(@pixi/core@7.4.3))(@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))) + '@applemusic-like-lyrics/lyric': + specifier: ^1.0.1 + version: 1.0.1 '@electron-toolkit/preload': specifier: ^3.0.2 version: 3.0.2(electron@41.6.1) @@ -20,6 +26,27 @@ importers: '@material/material-color-utilities': specifier: ^0.4.0 version: 0.4.0 + '@pixi/app': + specifier: ^7.4.3 + version: 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)) + '@pixi/core': + specifier: ^7.4.3 + version: 7.4.3 + '@pixi/display': + specifier: ^7.4.3 + version: 7.4.3(@pixi/core@7.4.3) + '@pixi/filter-blur': + specifier: ^7.4.3 + version: 7.4.3(@pixi/core@7.4.3) + '@pixi/filter-bulge-pinch': + specifier: ^5.1.1 + version: 5.1.1(@pixi/core@7.4.3) + '@pixi/filter-color-matrix': + specifier: ^7.4.3 + version: 7.4.3(@pixi/core@7.4.3) + '@pixi/sprite': + specifier: ^7.4.3 + version: 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)) '@vueuse/core': specifier: ^14.2.1 version: 14.2.1(vue@3.5.32(typescript@5.9.3)) @@ -174,6 +201,23 @@ packages: '@antfu/install-pkg@1.1.0': resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==} + '@applemusic-like-lyrics/core@0.5.1': + resolution: {integrity: sha512-DAEHmAe2USj/9qH4GKRFr/TuIKCOsNlcjgB2J2Lh4Be65RLU/pWpgnRhpIbV9ppinJzs+dWEsueWZiFTgLvMYQ==} + peerDependencies: + '@pixi/app': '*' + '@pixi/core': '*' + '@pixi/display': '*' + '@pixi/filter-blur': '*' + '@pixi/filter-bulge-pinch': '*' + '@pixi/filter-color-matrix': '*' + '@pixi/sprite': '*' + + '@applemusic-like-lyrics/lyric@1.0.1': + resolution: {integrity: sha512-b4/9MUTdp9AuW59JTBpOxb8P+4SF8NjaoZYpLD/nkVHSM/4kfbnYpo9HldSMOjRLwlKVv8bTF6Vr9K3OLHL85Q==} + + '@applemusic-like-lyrics/ttml@1.0.1': + resolution: {integrity: sha512-xhLajMI9Jm+Etv99GbK5Fx8wqa5m9wnS3kCqOTBUy9imjsah2PrV1XyCc6LBssPhEFcQt2SrFNQlwT6GZwpY7A==} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1564,6 +1608,68 @@ packages: resolution: {integrity: sha512-ODOov0sGMJMf3jPonOkgGqPknTsu+DdQ7kD++gz8aI+aFMOMHFbWAA2taqXXVTdP+OTOQR/znGvSpmkeI0WTYQ==} engines: {node: '>=14.18.0'} + '@pixi/app@7.4.3': + resolution: {integrity: sha512-opyWMuO0Ir8pf1DYUR++wAA6ZfNU+nIX2z95R2OD172HbcdhB4/HD7leLIIAny/LciEdMqlWEBhXK7N93YWbdg==} + peerDependencies: + '@pixi/core': 7.4.3 + '@pixi/display': 7.4.3 + + '@pixi/color@7.4.3': + resolution: {integrity: sha512-a6R+bXKeXMDcRmjYQoBIK+v2EYqxSX49wcjAY579EYM/WrFKS98nSees6lqVUcLKrcQh2DT9srJHX7XMny3voQ==} + + '@pixi/colord@2.9.6': + resolution: {integrity: sha512-nezytU2pw587fQstUu1AsJZDVEynjskwOL+kibwcdxsMBFqPsFFNA7xl0ii/gXuDi6M0xj3mfRJj8pBSc2jCfA==} + + '@pixi/constants@7.4.3': + resolution: {integrity: sha512-QGmwJUNQy/vVEHzL6VGQvnwawLZ1wceZMI8HwJAT4/I2uAzbBeFDdmCS8WsTpSWLZjF/DszDc1D8BFp4pVJ5UQ==} + + '@pixi/core@7.4.3': + resolution: {integrity: sha512-5YDs11faWgVVTL8VZtLU05/Fl47vaP5Tnsbf+y/WRR0VSW3KhRRGTBU1J3Gdc2xEWbJhUK07KGP7eSZpvtPVgA==} + + '@pixi/display@7.4.3': + resolution: {integrity: sha512-b5m2dAaoNAVdxz1oDaxl3XZ059NEOcNtGkxTOZ4EYCw/jcp9sZXkgSROHRzsGn4k+NugH7+9MP4Id2Z0kkdUhw==} + peerDependencies: + '@pixi/core': 7.4.3 + + '@pixi/extensions@7.4.3': + resolution: {integrity: sha512-FhoiYkHQEDYHUE7wXhqfsTRz6KxLXjuMbSiAwnLb9uG1vAgp6q6qd6HEsf4X30YaZbLFY8a4KY6hFZWjF+4Fdw==} + + '@pixi/filter-blur@7.4.3': + resolution: {integrity: sha512-ZFzS9L/whdRbs5A/EUgF3yQaBcxNarmbuwaMgrfnpQ84mRczkGByqDLGToadiufyals07ufTrXBGRle9lbtEDA==} + peerDependencies: + '@pixi/core': 7.4.3 + + '@pixi/filter-bulge-pinch@5.1.1': + resolution: {integrity: sha512-80I3g813td7Fnzi7IJSiR3z8gZlKblk6WN+5z6WnscQROcNEpck6lgWS/Lf/IdeHB/FtUKJCbx7RzxkUhiRTvA==} + peerDependencies: + '@pixi/core': ^7.0.0-X + + '@pixi/filter-color-matrix@7.4.3': + resolution: {integrity: sha512-TNu0h20SrzjUWIb5v19dAp1vPpqtG0w2XF9kIHN91bMNaf3R1jzhpWG6TtaVO9eo1IolWcEJLw38jIohyC+KNw==} + peerDependencies: + '@pixi/core': 7.4.3 + + '@pixi/math@7.4.3': + resolution: {integrity: sha512-/uJOVhR2DOZ+zgdI6Bs/CwcXT4bNRKsS+TqX3ekRIxPCwaLra+Qdm7aDxT5cTToDzdxbKL5+rwiLu3Y1egILDw==} + + '@pixi/runner@7.4.3': + resolution: {integrity: sha512-TJyfp7y23u5vvRAyYhVSa7ytq0PdKSvPLXu4G3meoFh1oxTLHH6g/RIzLuxUAThPG2z7ftthuW3qWq6dRV+dhw==} + + '@pixi/settings@7.4.3': + resolution: {integrity: sha512-SmGK8smc0PxRB9nr0UJioEtE9hl4gvj9OedCvZx3bxBwA3omA5BmP3CyhQfN8XJ29+o2OUL01r3zAPVol4l4lA==} + + '@pixi/sprite@7.4.3': + resolution: {integrity: sha512-iNBrpOFF9nXDT6m2jcyYy6l/sRzklLDDck1eFHprHZwvNquY2nzRfh+RGBCecxhBcijiLJ3fsZN33fP0LDXkvw==} + peerDependencies: + '@pixi/core': 7.4.3 + '@pixi/display': 7.4.3 + + '@pixi/ticker@7.4.3': + resolution: {integrity: sha512-tHsAD0iOUb6QSGGw+c8cyRBvxsq/NlfzIFBZLEHhWZ+Bx4a0MmXup6I/yJDGmyPCYE+ctCcAfY13wKAzdiVFgQ==} + + '@pixi/utils@7.4.3': + resolution: {integrity: sha512-NO3Y9HAn2UKS1YdxffqsPp+kDpVm8XWvkZcS/E+rBzY9VTLnNOI7cawSRm+dacdET3a8Jad3aDKEDZ0HmAqAFA==} + '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} @@ -1763,9 +1869,15 @@ packages: '@types/cacheable-request@6.0.3': resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + '@types/css-font-loading-module@0.0.12': + resolution: {integrity: sha512-x2tZZYkSxXqWvTDgveSynfjq/T2HyiZHXb00j/+gy19yp70PHCizM48XFdjBCWH7eHBD0R5i/pw9yMBP/BH5uA==} + '@types/debug@4.1.13': resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/earcut@2.1.4': + resolution: {integrity: sha512-qp3m9PPz4gULB9MhjGID7wpo3gJ4bTGXm7ltNDsmOvsPduTeHp8wSW9YckBj3mljeOh4F0m2z/0JKAALRKbmLQ==} + '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} @@ -2198,6 +2310,9 @@ packages: resolution: {integrity: sha512-RxD2Vd96sQDjQr20kdP+F+dK/1OUNiVOl200vKBZY8u0vTwysfolF6Hq+3ZK2+h8My9YvZhHsF+RSGZW2VYrPQ==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + bezier-easing@3.0.0: + resolution: {integrity: sha512-lE85voPXiK99T8NHOfhaUqCZpJdP1gBbbTEvdBDdPB+phyvPZPNWalBe42eb6lKOYchP0qZrtBiRCARtT4edRQ==} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -2277,6 +2392,10 @@ packages: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -2443,6 +2562,9 @@ packages: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} + deep-freeze@0.0.1: + resolution: {integrity: sha512-Z+z8HiAvsGwmjqlphnHW5oz6yWlOwu6EQfFTjmeTWlDeda3FS2yv3jhq35TX/ewmsnqB+RX2IdsIOyjJCQN5tg==} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -2509,6 +2631,9 @@ packages: duplexer@0.1.2: resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + earcut@2.2.4: + resolution: {integrity: sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==} + ejs@3.1.10: resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} engines: {node: '>=0.10.0'} @@ -2704,6 +2829,9 @@ packages: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} @@ -2850,6 +2978,9 @@ packages: github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + gl-matrix@4.0.0-beta.2: + resolution: {integrity: sha512-OF6IkQpMkF8p2CZF9EtzYZPlPaW3M41KMsgZGlTKmMv/nWaP6GMJi9V5tI+oPn8FG0io85Q5ZtKpCXP4u6YmDA==} + glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} engines: {node: '>=10.13.0'} @@ -3024,6 +3155,9 @@ packages: resolution: {integrity: sha512-FFUtZMpoZ8RqHS3XeXEmHWLA4thH+ZxCv2lOiPIn1Xc7CxrqhWzNSDzD+/chS/zbYezmiwWLdQC09JdQKmthOw==} engines: {node: '>=20'} + ismobilejs@1.1.1: + resolution: {integrity: sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==} + jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -3308,6 +3442,10 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} @@ -3373,6 +3511,9 @@ packages: package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -3512,6 +3653,9 @@ packages: pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3528,6 +3672,10 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + engines: {node: '>=0.6'} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} @@ -3807,6 +3955,22 @@ packages: shiki@3.23.0: resolution: {integrity: sha512-55Dj73uq9ZXL5zyeRPzHQsK7Nbyt6Y10k5s7OjuFZGMhpp4r/rsLBH0o/0fstIzX1Lep9VxefWljK/SKCzygIA==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -4139,6 +4303,10 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -4381,6 +4549,27 @@ snapshots: package-manager-detector: 1.6.0 tinyexec: 1.1.1 + '@applemusic-like-lyrics/core@0.5.1(@pixi/app@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))(@pixi/filter-blur@7.4.3(@pixi/core@7.4.3))(@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.3))(@pixi/filter-color-matrix@7.4.3(@pixi/core@7.4.3))(@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))': + dependencies: + '@pixi/app': 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)) + '@pixi/core': 7.4.3 + '@pixi/display': 7.4.3(@pixi/core@7.4.3) + '@pixi/filter-blur': 7.4.3(@pixi/core@7.4.3) + '@pixi/filter-bulge-pinch': 5.1.1(@pixi/core@7.4.3) + '@pixi/filter-color-matrix': 7.4.3(@pixi/core@7.4.3) + '@pixi/sprite': 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)) + '@ungap/structured-clone': 1.3.1 + bezier-easing: 3.0.0 + deep-freeze: 0.0.1 + gl-matrix: 4.0.0-beta.2 + + '@applemusic-like-lyrics/lyric@1.0.1': + dependencies: + '@applemusic-like-lyrics/ttml': 1.0.1 + pako: 2.1.0 + + '@applemusic-like-lyrics/ttml@1.0.1': {} + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -5550,6 +5739,79 @@ snapshots: tslib: 2.8.1 webcrypto-core: 1.9.2 + '@pixi/app@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))': + dependencies: + '@pixi/core': 7.4.3 + '@pixi/display': 7.4.3(@pixi/core@7.4.3) + + '@pixi/color@7.4.3': + dependencies: + '@pixi/colord': 2.9.6 + + '@pixi/colord@2.9.6': {} + + '@pixi/constants@7.4.3': {} + + '@pixi/core@7.4.3': + dependencies: + '@pixi/color': 7.4.3 + '@pixi/constants': 7.4.3 + '@pixi/extensions': 7.4.3 + '@pixi/math': 7.4.3 + '@pixi/runner': 7.4.3 + '@pixi/settings': 7.4.3 + '@pixi/ticker': 7.4.3 + '@pixi/utils': 7.4.3 + + '@pixi/display@7.4.3(@pixi/core@7.4.3)': + dependencies: + '@pixi/core': 7.4.3 + + '@pixi/extensions@7.4.3': {} + + '@pixi/filter-blur@7.4.3(@pixi/core@7.4.3)': + dependencies: + '@pixi/core': 7.4.3 + + '@pixi/filter-bulge-pinch@5.1.1(@pixi/core@7.4.3)': + dependencies: + '@pixi/core': 7.4.3 + + '@pixi/filter-color-matrix@7.4.3(@pixi/core@7.4.3)': + dependencies: + '@pixi/core': 7.4.3 + + '@pixi/math@7.4.3': {} + + '@pixi/runner@7.4.3': {} + + '@pixi/settings@7.4.3': + dependencies: + '@pixi/constants': 7.4.3 + '@types/css-font-loading-module': 0.0.12 + ismobilejs: 1.1.1 + + '@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))': + dependencies: + '@pixi/core': 7.4.3 + '@pixi/display': 7.4.3(@pixi/core@7.4.3) + + '@pixi/ticker@7.4.3': + dependencies: + '@pixi/extensions': 7.4.3 + '@pixi/settings': 7.4.3 + '@pixi/utils': 7.4.3 + + '@pixi/utils@7.4.3': + dependencies: + '@pixi/color': 7.4.3 + '@pixi/constants': 7.4.3 + '@pixi/settings': 7.4.3 + '@types/earcut': 2.1.4 + earcut: 2.2.4 + eventemitter3: 4.0.7 + url: 0.11.4 + '@polka/url@1.0.0-next.29': {} '@quansync/fs@1.0.0': @@ -5704,10 +5966,14 @@ snapshots: '@types/node': 22.19.17 '@types/responselike': 1.0.3 + '@types/css-font-loading-module@0.0.12': {} + '@types/debug@4.1.13': dependencies: '@types/ms': 2.1.0 + '@types/earcut@2.1.4': {} + '@types/esrecurse@4.3.1': {} '@types/estree@1.0.8': {} @@ -6277,6 +6543,8 @@ snapshots: bindings: 1.5.0 prebuild-install: 7.1.3 + bezier-easing@3.0.0: {} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -6382,6 +6650,11 @@ snapshots: es-errors: 1.3.0 function-bind: 1.1.2 + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} camelcase@5.3.1: @@ -6512,6 +6785,8 @@ snapshots: deep-extend@0.6.0: {} + deep-freeze@0.0.1: {} + deep-is@0.1.4: {} defer-to-connect@2.0.1: {} @@ -6583,6 +6858,8 @@ snapshots: duplexer@0.1.2: {} + earcut@2.2.4: {} + ejs@3.1.10: dependencies: jake: 10.9.4 @@ -6881,6 +7158,8 @@ snapshots: esutils@2.0.3: {} + eventemitter3@4.0.7: {} + expand-template@2.0.3: {} exponential-backoff@3.1.3: {} @@ -7039,6 +7318,8 @@ snapshots: github-from-package@0.0.0: {} + gl-matrix@4.0.0-beta.2: {} + glob-parent@6.0.2: dependencies: is-glob: 4.0.3 @@ -7219,6 +7500,8 @@ snapshots: isexe@4.0.0: {} + ismobilejs@1.1.1: {} + jake@10.9.4: dependencies: async: 3.2.6 @@ -7487,6 +7770,8 @@ snapshots: dependencies: boolbase: 1.0.0 + object-inspect@1.13.4: {} + object-keys@1.1.1: optional: true @@ -7581,6 +7866,8 @@ snapshots: package-manager-detector@1.6.0: {} + pako@2.1.0: {} + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -7714,6 +8001,8 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode@1.4.1: {} + punycode@2.3.1: {} pvtsutils@1.3.6: @@ -7729,6 +8018,10 @@ snapshots: yargs: 15.4.1 optional: true + qs@6.15.2: + dependencies: + side-channel: 1.1.1 + quansync@0.2.11: {} quansync@1.0.0: {} @@ -8019,6 +8312,34 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -8391,6 +8712,11 @@ snapshots: dependencies: punycode: 2.3.1 + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.2 + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} From c84fc8d2cc27749e8ef1a10fc2fa2b11a65d3d4d Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:18:26 +0800 Subject: [PATCH 02/22] =?UTF-8?q?feat:=20=E5=AE=9E=E7=8E=B0=20cleanTTMLTra?= =?UTF-8?q?nslations=20=E7=94=A8=E4=BA=8E=20TTML=20=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E6=AD=8C=E8=AF=8D=E9=A2=84=E8=BF=87=E6=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/lyric/parseTTML.ts | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/src/utils/lyric/parseTTML.ts b/src/utils/lyric/parseTTML.ts index 2fd625f..99cbedd 100644 --- a/src/utils/lyric/parseTTML.ts +++ b/src/utils/lyric/parseTTML.ts @@ -424,3 +424,77 @@ export const parseTTML = (text: string, preferredLang = ""): LyricLine[] => { return lines; }; + +/** + * 清洗 TTML 中不需要的翻译,过滤非首选语言节点,避免上游解析器混淆 + * @param ttmlContent 原始 TTML 内容 + * @param preferredLang 偏好的语言(如 zh-CN) + * @returns 清洗后的 TTML 内容 + */ +export const cleanTTMLTranslations = (ttmlContent: string, preferredLang = ""): string => { + /** + * 统计 TTML 中的语言 + */ + const langCounter = (ttml_text: string) => { + const langRegex = /(?<=<(span|translation)[^<>]+)xml:lang="([^"]+)"/g; + const matches = ttml_text.matchAll(langRegex); + const langSet = new Set(); + for (const match of matches) { + if (match[2]) langSet.add(match[2]); + } + return Array.from(langSet); + }; + + /** + * 过滤语言并选择最佳匹配 + */ + const langFilter = (langs: string[]): string | null => { + if (langs.length <= 1) return null; + + const langMatcher = (target: string) => { + return langs.find((lang) => { + try { + return new Intl.Locale(lang).maximize().script === target; + } catch { + return false; + } + }); + }; + + // 优先匹配用户的偏好语言 + if (preferredLang) { + const preferred = preferredLang.toLowerCase().replace(/_/g, "-"); + const matched = langs.find((lang) => lang.toLowerCase().replace(/_/g, "-") === preferred); + if (matched) return matched; + + const prefBase = preferred.split("-")[0]; + const matchedBase = langs.find((lang) => lang.toLowerCase().replace(/_/g, "-").split("-")[0] === prefBase); + if (matchedBase) return matchedBase; + } + + // 备选的中文脚本匹配优先级 + const hans_matched = langMatcher("Hans"); + if (hans_matched) return hans_matched; + const hant_matched = langMatcher("Hant"); + if (hant_matched) return hant_matched; + const major = langs.find((key) => key.startsWith("zh")); + if (major) return major; + return langs[0]; + }; + + /** + * 替换清洗标签 + */ + const ttmlCleaner = (ttml_text: string, major_lang: string | null): string => { + if (major_lang === null) return ttml_text; + const replacer = (match: string, lang: string) => (lang === major_lang ? match : ""); + const translationRegex = /]+xml:lang="([^"]+)"[^>]*>[\s\S]*?<\/translation>/g; + const spanRegex = /]+xml:lang="([^" ]+)"[^>]*>[\s\S]*?<\/span>/g; + return ttml_text.replace(translationRegex, replacer).replace(spanRegex, replacer); + }; + + const context_lang = langCounter(ttmlContent); + const major = langFilter(context_lang); + const cleaned_ttml = ttmlCleaner(ttmlContent, major); + return cleaned_ttml.replace(/\n\s*/g, ""); +}; From d68fc4ab257c3d866a0e110cfdbfafa9445b6c13 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:20:02 +0800 Subject: [PATCH 03/22] =?UTF-8?q?refactor:=20=E5=9C=A8=20parseContent=20?= =?UTF-8?q?=E4=B8=AD=E9=9B=86=E6=88=90=20AMLL=20=E8=A7=A3=E6=9E=90?= =?UTF-8?q?=E5=99=A8=E9=80=82=E9=85=8D=20TTML=20=E4=B8=8E=20YRC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/lyric/parse.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/utils/lyric/parse.ts b/src/utils/lyric/parse.ts index 98d7b1b..5ce4f71 100644 --- a/src/utils/lyric/parse.ts +++ b/src/utils/lyric/parse.ts @@ -4,7 +4,8 @@ import { parseLRC } from "./parseLRC"; import { parseQRC } from "./parseQRC"; import { parseYRC } from "./parseYRC"; import { parseKRC } from "./parseKRC"; -import { parseTTML } from "./parseTTML"; +import { parseTTML, cleanTTMLTranslations } from "./parseTTML"; +import { parseTTML as parseAMLLTtml, parseYrc as parseAMLLYrc } from "@applemusic-like-lyrics/lyric"; import { parseLyS } from "./parseLyS"; import { parseSRT } from "./parseSRT"; import { parseASS } from "./parseASS"; @@ -70,14 +71,26 @@ export const detectFormat = (text: string): LyricFormat => { */ const parseContent = (text: string, format: LyricFormat, preferredLang = ""): LyricLine[] => { switch (format) { - case "ttml": - return parseTTML(text, preferredLang); + case "ttml": { + const cleaned = cleanTTMLTranslations(text, preferredLang); + try { + return parseAMLLTtml(cleaned).lines || []; + } catch (err) { + console.error("AMLL TTML parse failed, fallback to local parseTTML:", err); + return parseTTML(text, preferredLang); + } + } case "qrc": return parseQRC(text); case "krc": return parseKRC(text); case "yrc": - return parseYRC(text); + try { + return parseAMLLYrc(text) || []; + } catch (err) { + console.error("AMLL YRC parse failed, fallback to local parseYRC:", err); + return parseYRC(text); + } case "lrc": return parseLRC(text); case "lys": From 0b9d7ec351091084b61bb762626df48381a48eb9 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:21:23 +0800 Subject: [PATCH 04/22] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=9F=BA?= =?UTF-8?q?=E4=BA=8E=20PixiJS=20=E7=9A=84=E6=B5=81=E4=BD=93=E6=B8=90?= =?UTF-8?q?=E5=8F=98=E8=83=8C=E6=99=AF=E7=BB=84=E4=BB=B6=20BackgroundRende?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components.d.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/components.d.ts b/components.d.ts index 50895f2..067deac 100644 --- a/components.d.ts +++ b/components.d.ts @@ -17,6 +17,7 @@ declare module 'vue' { AppBackground: typeof import('./src/components/AppBackground.vue')['default'] AutoCloseDialog: typeof import('./src/components/modals/AutoCloseDialog.vue')['default'] BackgroundImagePicker: typeof import('./src/components/settings/custom/BackgroundImagePicker.vue')['default'] + BackgroundRender: typeof import('./src/components/player/FullPlayer/BackgroundRender.vue')['default'] BottomSpectrum: typeof import('./src/components/player/FullPlayer/BottomSpectrum.vue')['default'] ComboboxAnchor: typeof import('reka-ui')['ComboboxAnchor'] ComboboxContent: typeof import('reka-ui')['ComboboxContent'] From 050c04a15479db5bdae74aeb999763a2f22f40ba Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:22:51 +0800 Subject: [PATCH 05/22] =?UTF-8?q?feat:=20=E6=92=AD=E6=94=BE=E5=99=A8?= =?UTF-8?q?=E8=83=8C=E6=99=AF=20PlayerBackground=20=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=E6=B5=81=E4=BD=93=E5=8A=A8=E7=94=BB=E8=83=8C=E6=99=AF=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../player/FullPlayer/PlayerBackground.vue | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/components/player/FullPlayer/PlayerBackground.vue b/src/components/player/FullPlayer/PlayerBackground.vue index 5e1f832..0d06810 100644 --- a/src/components/player/FullPlayer/PlayerBackground.vue +++ b/src/components/player/FullPlayer/PlayerBackground.vue @@ -4,13 +4,14 @@ import { useThemeStore } from "@/stores/theme"; import { useMediaStore } from "@/stores/media"; import { useStatusStore } from "@/stores/status"; import DEFAULT_COVER from "@/assets/images/song.jpg"; +import BackgroundRender from "./BackgroundRender.vue"; const media = useMediaStore(); const settings = useSettingsStore(); const theme = useThemeStore(); const status = useStatusStore(); -const bgType = computed(() => settings.player.playerBgType); +const bgType = computed(() => settings.player.playerBgType as string); // 封面颜色(纯色模式) const coverColor = computed(() => { @@ -95,6 +96,14 @@ onBeforeUnmount(() => { /> + +
+ +
+
@@ -110,11 +119,13 @@ onBeforeUnmount(() => { diff --git a/src/components/player/Lyrics/AMLLLyrics.vue b/src/components/player/Lyrics/AMLLLyrics.vue new file mode 100644 index 0000000..6e4373b --- /dev/null +++ b/src/components/player/Lyrics/AMLLLyrics.vue @@ -0,0 +1,238 @@ + + + + + From 2bce8df05e0a36e3a33c0ee03388ef8d0ee7837c Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:32:22 +0800 Subject: [PATCH 07/22] =?UTF-8?q?feat:=20=E5=85=A8=E5=B1=8F=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E5=99=A8=20index.vue=20=E6=94=AF=E6=8C=81=E6=9D=A1?= =?UTF-8?q?=E4=BB=B6=E5=88=86=E6=B5=81=E6=B8=B2=E6=9F=93=E6=AD=8C=E8=AF=8D?= =?UTF-8?q?=E5=BC=95=E6=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/player/FullPlayer/index.vue | 33 +++++++++++++++++++-- src/components/player/Lyrics/AMLLLyrics.vue | 3 +- src/stores/settings.ts | 2 ++ src/types/settings.ts | 4 +++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/src/components/player/FullPlayer/index.vue b/src/components/player/FullPlayer/index.vue index 7c6222b..8591d9c 100644 --- a/src/components/player/FullPlayer/index.vue +++ b/src/components/player/FullPlayer/index.vue @@ -9,6 +9,7 @@ import { useFavorite } from "@/composables/useFavorite"; import { useDownload, buildDownloadQualityItems } from "@/composables/useDownload"; import { usePlaylistPicker } from "@/composables/usePlaylistPicker"; import Lyrics from "@/components/player/Lyrics/index.vue"; +import AMLLLyrics from "@/components/player/Lyrics/AMLLLyrics.vue"; import PlaylistPickerDialog from "@/components/modals/PlaylistPickerDialog.vue"; import { useWindowControls } from "@/composables/useWindowControls"; import * as player from "@/core/player"; @@ -39,7 +40,7 @@ const { } = storeToRefs(status); /** 歌词组件引用 */ -const lyricRef = ref>(); +const lyricRef = ref | InstanceType>(); /** 精确播放时间(毫秒);offset 直接读 status mirror(主进程权威源) */ const { start: startTick, stop: stopTick } = usePlaybackTime((currentMs) => { @@ -122,6 +123,20 @@ watch( }, ); +// 切换歌词引擎时,重新计算初始并推送时间 +watch( + () => settings.lyric.engine, + () => { + initialLyricTimeMs.value = getCurrentTime() + status.lyricOffsetMs; + nextTick(() => { + lyricRef.value?.setCurrentTime(getCurrentTime() + status.lyricOffsetMs); + if (isPlaying.value) { + lyricRef.value?.resume(); + } + }); + }, +); + /** 全屏 */ const { isFullscreen, toggleFullscreen } = useWindowControls(); @@ -357,8 +372,22 @@ const toggleLyric = (): void => { fontFamily: settings.lyric.fontFamily || undefined, }" > + { playerRef.value.setHidePassedLines(props.hidePassedLines); playerRef.value.setEnableBlur(props.enableBlur); - // 外部高级设置项读取与同步 - const useSpring = (settings.player as any).useAMSpring ?? true; + const useSpring = settings.lyric.useAMSpring; playerRef.value.setEnableSpring(useSpring); playerRef.value.setEnableScale(useSpring); } diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 93b01fb..ec6bcd7 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -88,6 +88,8 @@ export const useSettingsStore = defineStore( enableExcludeLyrics: true, excludeLyricsUserKeywords: [], excludeLyricsUserRegexes: [], + engine: "physics", + useAMSpring: true, }); /** 系统配置 - 传递主进程 */ diff --git a/src/types/settings.ts b/src/types/settings.ts index aedc492..3836026 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -109,6 +109,10 @@ export interface LyricSettings { excludeLyricsUserKeywords: string[]; /** 用户自定义正则 */ excludeLyricsUserRegexes: string[]; + /** 歌词引擎类型 */ + engine: "physics" | "amll"; + /** AM 歌词是否启用物理回弹与缩放 */ + useAMSpring: boolean; } /** 播放器设置 */ From 6d01f0d61bec1ca7fbe85e4b67c59e60225d054a Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:57:45 +0800 Subject: [PATCH 08/22] =?UTF-8?q?feat:=20=E6=89=A9=E5=B1=95=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=B1=BB=E5=9E=8B=E4=B8=8E=E6=8C=81=E4=B9=85=E5=8C=96?= =?UTF-8?q?=E6=AD=8C=E8=AF=8D=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E3=80=81?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E6=AD=8C=E8=AF=8D=E8=AE=BE=E7=BD=AE=EF=BC=8C?= =?UTF-8?q?=E5=B9=B6=E6=96=B0=E5=A2=9E=E5=85=A8=E5=B1=8F=E6=AD=8C=E8=AF=8D?= =?UTF-8?q?=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/i18n/locales/en-US.json | 14 +++ src/i18n/locales/zh-CN.json | 14 +++ src/settings/categories/lyric.ts | 166 ------------------------------- src/settings/schema.ts | 2 + src/types/settings.ts | 2 +- 5 files changed, 31 insertions(+), 167 deletions(-) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index fd5ecb2..8baf766 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -619,6 +619,7 @@ "general": "General", "player": "Player", "lyric": "Lyrics", + "fullScreenLyric": "Full-screen Lyrics", "externalLyric": "External Lyrics", "appearance": "Appearance", "hotkeys": "Hotkey Settings", @@ -639,6 +640,7 @@ "language": "Language", "playback": "Player", "playControl": "Playback Control", + "lyricEngine": "Lyric Engine", "lyricContent": "Lyric Content", "lyricTTML": "TTML Lyrics", "lyricExclude": "Metadata Stripping", @@ -837,6 +839,18 @@ "openSearch": "Open search" } }, + "engine": { + "label": "Lyric Engine", + "description": "Choose the engine type used for lyric rendering and scrolling" + }, + "lyricEngine": { + "physics": "Default", + "amll": "AMLL" + }, + "useAMSpring": { + "label": "Physics Spring & Scale", + "description": "Enable spring bounce and active line scaling effects for applemusic-like-lyrics" + }, "autoCenterCover": { "label": "Auto Center Cover", "description": "Center cover and hide lyric area when no lyrics available" diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 507addd..de6a915 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -607,6 +607,7 @@ "general": "常规设置", "player": "播放设置", "lyric": "歌词设置", + "fullScreenLyric": "全屏歌词", "externalLyric": "外部歌词", "appearance": "外观设置", "hotkeys": "快捷键配置", @@ -627,6 +628,7 @@ "language": "语言", "playback": "播放器", "playControl": "播放控制", + "lyricEngine": "歌词引擎", "lyricContent": "歌词内容", "lyricTTML": "TTML 歌词", "lyricExclude": "歌词排除", @@ -825,6 +827,18 @@ "openSearch": "打开搜索" } }, + "engine": { + "label": "歌词渲染引擎", + "description": "选择用于歌词渲染与滚动的动效引擎" + }, + "lyricEngine": { + "physics": "默认", + "amll": "AMLL" + }, + "useAMSpring": { + "label": "物理回弹与缩放", + "description": "为 Apple Music 风格歌词行启用物理弹性回弹与焦点行缩放效果" + }, "autoCenterCover": { "label": "自动居中封面", "description": "无歌词时自动居中封面并隐藏歌词区域" diff --git a/src/settings/categories/lyric.ts b/src/settings/categories/lyric.ts index 1148095..34dbaac 100644 --- a/src/settings/categories/lyric.ts +++ b/src/settings/categories/lyric.ts @@ -106,172 +106,6 @@ const lyricCategory: SettingCategory = { }, ], }, - { - id: "lyricGeneral", - items: [ - { - key: "adaptiveFontSize", - type: "switch", - binding: { store: "settings", path: "lyric.adaptiveFontSize" }, - defaultValue: true, - }, - { - key: "fontSize", - type: "slider", - binding: { store: "settings", path: "lyric.fontSize" }, - min: 30, - max: 64, - step: 1, - defaultValue: 48, - marks: { 30: "30", 48: "48", 64: "64" }, - }, - { - key: "fontWeight", - type: "slider", - binding: { store: "settings", path: "lyric.fontWeight" }, - min: 100, - max: 900, - step: 100, - defaultValue: 700, - marks: { 100: "100", 400: "400", 700: "700", 900: "900" }, - }, - { - key: "showTranslation", - type: "switch", - binding: { store: "settings", path: "lyric.showTranslation" }, - defaultValue: true, - }, - { - key: "showRomanization", - type: "switch", - binding: { store: "settings", path: "lyric.showRomanization" }, - defaultValue: true, - }, - ], - }, - { - id: "lyricDisplay", - items: [ - { - key: "enableWordHighlight", - type: "switch", - binding: { store: "settings", path: "lyric.enableWordHighlight" }, - defaultValue: true, - }, - { - key: "enableFloatAnimation", - type: "switch", - binding: { store: "settings", path: "lyric.enableFloatAnimation" }, - defaultValue: false, - }, - { - key: "enableEmphasizeEffect", - type: "switch", - binding: { store: "settings", path: "lyric.enableEmphasizeEffect" }, - defaultValue: false, - }, - { - key: "enableBlur", - type: "switch", - binding: { store: "settings", path: "lyric.enableBlur" }, - defaultValue: false, - }, - { - key: "hidePassedLines", - type: "switch", - binding: { store: "settings", path: "lyric.hidePassedLines" }, - defaultValue: false, - }, - ], - }, - { - id: "lyricSpring", - items: [ - { - key: "springPreset", - type: "select", - binding: { store: "settings", path: "lyric.springPreset" }, - options: [ - { value: "default", labelKey: "settings.springPreset.default" }, - { value: "smooth", labelKey: "settings.springPreset.smooth" }, - { value: "responsive", labelKey: "settings.springPreset.responsive" }, - { value: "jello", labelKey: "settings.springPreset.jello" }, - { value: "heavy", labelKey: "settings.springPreset.heavy" }, - { value: "noBounce", labelKey: "settings.springPreset.noBounce" }, - { value: "custom", labelKey: "settings.springPreset.custom" }, - ], - defaultValue: "default", - childrenCondition: () => useSettingsStore().lyric.springPreset === "custom", - children: [ - { - key: "springMass", - type: "slider", - binding: { store: "settings", path: "lyric.springMass" }, - min: 0.1, - max: 5, - step: 0.1, - defaultValue: 0.9, - marks: { 0.1: "0.1", 0.9: "0.9", 5: "5" }, - }, - { - key: "springDamping", - type: "slider", - binding: { store: "settings", path: "lyric.springDamping" }, - min: 1, - max: 50, - step: 0.5, - defaultValue: 15, - marks: { 1: "1", 15: "15", 50: "50" }, - }, - { - key: "springStiffness", - type: "slider", - binding: { store: "settings", path: "lyric.springStiffness" }, - min: 10, - max: 300, - step: 5, - defaultValue: 90, - marks: { 10: "10", 90: "90", 300: "300" }, - }, - ], - }, - ], - }, - { - id: "lyricLayout", - items: [ - { - key: "alignPosition", - type: "slider", - binding: { store: "settings", path: "lyric.alignPosition" }, - min: 0.1, - max: 0.9, - step: 0.05, - defaultValue: 0.35, - marks: { 0.1: "0.1", 0.35: "0.35", 0.9: "0.9" }, - }, - { - key: "wordFadeWidth", - type: "slider", - binding: { store: "settings", path: "lyric.wordFadeWidth" }, - min: 0.1, - max: 1, - step: 0.1, - defaultValue: 0.5, - marks: { 0.1: "0.1", 0.5: "0.5", 1: "1" }, - }, - { - key: "inactiveAlpha", - type: "slider", - binding: { store: "settings", path: "lyric.inactiveAlpha" }, - min: 0, - max: 1, - step: 0.05, - defaultValue: 0.2, - marks: { 0: "0", 0.2: "0.2", 1: "1" }, - }, - ], - }, ], }; diff --git a/src/settings/schema.ts b/src/settings/schema.ts index 5ba42e4..b4a416c 100644 --- a/src/settings/schema.ts +++ b/src/settings/schema.ts @@ -3,6 +3,7 @@ import generalCategory from "./categories/general"; import appearanceCategory from "./categories/appearance"; import playerCategory from "./categories/player"; import lyricCategory from "./categories/lyric"; +import fullScreenLyricCategory from "./categories/fullScreenLyric"; import externalLyricCategory from "./categories/externalLyric"; import hotkeysCategory from "./categories/hotkeys"; import servicesCategory from "./categories/services"; @@ -18,6 +19,7 @@ export const settingsSchema: SettingCategory[] = [ appearanceCategory, playerCategory, lyricCategory, + fullScreenLyricCategory, externalLyricCategory, hotkeysCategory, servicesCategory, diff --git a/src/types/settings.ts b/src/types/settings.ts index 3836026..e0d5eb5 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -5,7 +5,7 @@ import { ALL_PLATFORMS } from "@shared/types/platform"; import type { QualityLevel } from "@/utils/quality"; /** 播放器背景类型 */ -export type PlayerBgType = "blur" | "solid"; +export type PlayerBgType = "blur" | "solid" | "animation"; export type CoverLayout = "default" | "fullscreen"; /** From 29af4660e444ed04ebd5d2de86c4ae75f70922f1 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Thu, 18 Jun 2026 23:59:28 +0800 Subject: [PATCH 09/22] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E6=AD=8C?= =?UTF-8?q?=E8=AF=8D=E6=B8=B2=E6=9F=93=E5=BC=95=E6=93=8E=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/settings/categories/fullScreenLyric.ts | 209 +++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 src/settings/categories/fullScreenLyric.ts diff --git a/src/settings/categories/fullScreenLyric.ts b/src/settings/categories/fullScreenLyric.ts new file mode 100644 index 0000000..659ad3b --- /dev/null +++ b/src/settings/categories/fullScreenLyric.ts @@ -0,0 +1,209 @@ +import type { SettingCategory } from "@/types/settings-schema"; +import { useSettingsStore } from "@/stores/settings"; +import IconLucideTv from "~icons/lucide/tv"; + +const fullScreenLyricCategory: SettingCategory = { + id: "fullScreenLyric", + icon: IconLucideTv, + sections: [ + { + id: "lyricEngine", + items: [ + { + key: "engine", + type: "select", + binding: { store: "settings", path: "lyric.engine" }, + options: [ + { value: "physics", labelKey: "settings.lyricEngine.physics" }, + { value: "amll", labelKey: "settings.lyricEngine.amll" }, + ], + defaultValue: "physics", + childrenCondition: () => useSettingsStore().lyric.engine === "amll", + children: [ + { + key: "useAMSpring", + type: "switch", + binding: { store: "settings", path: "lyric.useAMSpring" }, + defaultValue: true, + }, + ], + }, + ], + }, + { + id: "lyricGeneral", + items: [ + { + key: "adaptiveFontSize", + type: "switch", + binding: { store: "settings", path: "lyric.adaptiveFontSize" }, + defaultValue: true, + }, + { + key: "fontSize", + type: "slider", + binding: { store: "settings", path: "lyric.fontSize" }, + min: 30, + max: 64, + step: 1, + defaultValue: 48, + marks: { 30: "30", 48: "48", 64: "64" }, + }, + { + key: "fontWeight", + type: "slider", + binding: { store: "settings", path: "lyric.fontWeight" }, + min: 100, + max: 900, + step: 100, + defaultValue: 700, + marks: { 100: "100", 400: "400", 700: "700", 900: "900" }, + }, + { + key: "showTranslation", + type: "switch", + binding: { store: "settings", path: "lyric.showTranslation" }, + defaultValue: true, + }, + { + key: "showRomanization", + type: "switch", + binding: { store: "settings", path: "lyric.showRomanization" }, + defaultValue: true, + }, + ], + }, + { + id: "lyricDisplay", + items: [ + { + key: "enableWordHighlight", + type: "switch", + binding: { store: "settings", path: "lyric.enableWordHighlight" }, + defaultValue: true, + disabled: () => useSettingsStore().lyric.engine === "amll", + }, + { + key: "enableFloatAnimation", + type: "switch", + binding: { store: "settings", path: "lyric.enableFloatAnimation" }, + defaultValue: false, + disabled: () => useSettingsStore().lyric.engine === "amll", + }, + { + key: "enableEmphasizeEffect", + type: "switch", + binding: { store: "settings", path: "lyric.enableEmphasizeEffect" }, + defaultValue: false, + disabled: () => useSettingsStore().lyric.engine === "amll", + }, + { + key: "enableBlur", + type: "switch", + binding: { store: "settings", path: "lyric.enableBlur" }, + defaultValue: false, + }, + { + key: "hidePassedLines", + type: "switch", + binding: { store: "settings", path: "lyric.hidePassedLines" }, + defaultValue: false, + }, + ], + }, + { + id: "lyricSpring", + items: [ + { + key: "springPreset", + type: "select", + binding: { store: "settings", path: "lyric.springPreset" }, + options: [ + { value: "default", labelKey: "settings.springPreset.default" }, + { value: "smooth", labelKey: "settings.springPreset.smooth" }, + { value: "responsive", labelKey: "settings.springPreset.responsive" }, + { value: "jello", labelKey: "settings.springPreset.jello" }, + { value: "heavy", labelKey: "settings.springPreset.heavy" }, + { value: "noBounce", labelKey: "settings.springPreset.noBounce" }, + { value: "custom", labelKey: "settings.springPreset.custom" }, + ], + defaultValue: "default", + disabled: () => useSettingsStore().lyric.engine === "amll", + childrenCondition: () => + useSettingsStore().lyric.engine !== "amll" && + useSettingsStore().lyric.springPreset === "custom", + children: [ + { + key: "springMass", + type: "slider", + binding: { store: "settings", path: "lyric.springMass" }, + min: 0.1, + max: 5, + step: 0.1, + defaultValue: 0.9, + marks: { 0.1: "0.1", 0.9: "0.9", 5: "5" }, + }, + { + key: "springDamping", + type: "slider", + binding: { store: "settings", path: "lyric.springDamping" }, + min: 1, + max: 50, + step: 0.5, + defaultValue: 15, + marks: { 1: "1", 15: "15", 50: "50" }, + }, + { + key: "springStiffness", + type: "slider", + binding: { store: "settings", path: "lyric.springStiffness" }, + min: 10, + max: 300, + step: 5, + defaultValue: 90, + marks: { 10: "10", 90: "90", 300: "300" }, + }, + ], + }, + ], + }, + { + id: "lyricLayout", + items: [ + { + key: "alignPosition", + type: "slider", + binding: { store: "settings", path: "lyric.alignPosition" }, + min: 0.1, + max: 0.9, + step: 0.05, + defaultValue: 0.35, + marks: { 0.1: "0.1", 0.35: "0.35", 0.9: "0.9" }, + }, + { + key: "wordFadeWidth", + type: "slider", + binding: { store: "settings", path: "lyric.wordFadeWidth" }, + min: 0.1, + max: 1, + step: 0.1, + defaultValue: 0.5, + marks: { 0.1: "0.1", 0.5: "0.5", 1: "1" }, + }, + { + key: "inactiveAlpha", + type: "slider", + binding: { store: "settings", path: "lyric.inactiveAlpha" }, + min: 0, + max: 1, + step: 0.05, + defaultValue: 0.2, + marks: { 0: "0", 0.2: "0.2", 1: "1" }, + disabled: () => useSettingsStore().lyric.engine === "amll", + }, + ], + }, + ], +}; + +export default fullScreenLyricCategory; From 78a2470b0dd25d87f5221d2aa138a8629aa7ff42 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:21:21 +0800 Subject: [PATCH 10/22] =?UTF-8?q?chore:=20=E6=89=A9=E5=B1=95=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E7=B1=BB=E5=9E=8B=E4=BB=A5=E6=94=AF=E6=8C=81=20AMLL?= =?UTF-8?q?=20=E4=B8=93=E5=B1=9E=E7=89=A9=E7=90=86=E5=9B=9E=E5=BC=B9?= =?UTF-8?q?=E4=B8=8E=E7=BC=A9=E6=94=BE=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/settings.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/types/settings.ts b/src/types/settings.ts index e0d5eb5..6391fdf 100644 --- a/src/types/settings.ts +++ b/src/types/settings.ts @@ -113,6 +113,16 @@ export interface LyricSettings { engine: "physics" | "amll"; /** AM 歌词是否启用物理回弹与缩放 */ useAMSpring: boolean; + /** AMLL 垂直位移弹簧参数 */ + amllVerticalSpringMass: number; + amllVerticalSpringDamping: number; + amllVerticalSpringStiffness: number; + amllVerticalSpringSoft: boolean; + /** AMLL 缩放弹簧参数 */ + amllScaleSpringMass: number; + amllScaleSpringDamping: number; + amllScaleSpringStiffness: number; + amllScaleSpringSoft: boolean; } /** 播放器设置 */ From e2e951f569e8ddafd91dd42e8e1a0d20aeded7d9 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:22:55 +0800 Subject: [PATCH 11/22] =?UTF-8?q?feat:=20=E5=9C=A8=20setting=20store=20?= =?UTF-8?q?=E4=B8=AD=E5=88=9D=E5=A7=8B=E5=8C=96=E5=B9=B6=E6=8C=81=E4=B9=85?= =?UTF-8?q?=E5=8C=96=20AMLL=20=E5=BC=B9=E7=B0=A7=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stores/settings.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/stores/settings.ts b/src/stores/settings.ts index ec6bcd7..1566ebd 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -90,6 +90,14 @@ export const useSettingsStore = defineStore( excludeLyricsUserRegexes: [], engine: "physics", useAMSpring: true, + amllVerticalSpringMass: 1, + amllVerticalSpringDamping: 15, + amllVerticalSpringStiffness: 100, + amllVerticalSpringSoft: false, + amllScaleSpringMass: 1, + amllScaleSpringDamping: 20, + amllScaleSpringStiffness: 100, + amllScaleSpringSoft: false, }); /** 系统配置 - 传递主进程 */ From 792b5f419e114c905dbecf766c11e231e80bfd9e Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:24:27 +0800 Subject: [PATCH 12/22] =?UTF-8?q?feat:=20=E8=AE=BE=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E6=94=AF=E6=8C=81=20visible=20=E6=9D=A1=E4=BB=B6=E6=B8=B2?= =?UTF-8?q?=E6=9F=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/settings/SettingsSearch.vue | 1 + src/components/settings/SettingsSection.vue | 2 +- src/types/settings-schema.ts | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/settings/SettingsSearch.vue b/src/components/settings/SettingsSearch.vue index c74ee00..d98a3e9 100644 --- a/src/components/settings/SettingsSearch.vue +++ b/src/components/settings/SettingsSearch.vue @@ -29,6 +29,7 @@ const results = computed(() => { for (const cat of settingsSchema) { for (const sec of cat.sections ?? []) { for (const item of sec.items) { + if (item.visible && !item.visible()) continue; const label = t(`settings.${item.key}.label`); const desc = item.hideDescription ? "" : t(`settings.${item.key}.description`); const kw = item.keywords?.map((k) => t(k)).join(" ") ?? ""; diff --git a/src/components/settings/SettingsSection.vue b/src/components/settings/SettingsSection.vue index 916ff4c..36b1afd 100644 --- a/src/components/settings/SettingsSection.vue +++ b/src/components/settings/SettingsSection.vue @@ -13,7 +13,7 @@ const props = withDefaults( const { t } = useI18n(); -const visibleItems = computed(() => props.section.items); +const visibleItems = computed(() => props.section.items.filter((item) => !item.visible || item.visible())); const itemStyle = (i: number) => { const d = props.highlightKey ? "0s" : `${Math.min(props.startIndex + i, 15) * 0.03}s`; diff --git a/src/types/settings-schema.ts b/src/types/settings-schema.ts index 1099e77..9cd565c 100644 --- a/src/types/settings-schema.ts +++ b/src/types/settings-schema.ts @@ -51,6 +51,8 @@ export interface SettingItem { hideDescription?: boolean; /** 条件禁用 */ disabled?: () => boolean; + /** 条件隐藏 */ + visible?: () => boolean; /** button 类型的点击回调 */ action?: () => void; /** custom 类型的组件 */ From 8de0fbf9fbeb2ae9ebd0bea1675369beda3a8347 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:25:09 +0800 Subject: [PATCH 13/22] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=E5=85=A8?= =?UTF-8?q?=E5=B1=8F=E6=AD=8C=E8=AF=8D=E8=AE=BE=E7=BD=AE=20Schema=20?= =?UTF-8?q?=E4=BD=BF=E4=B8=93=E5=B1=9E=E9=80=89=E9=A1=B9=E6=8C=89=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E6=98=BE=E9=9A=90=E4=B8=94=E6=94=AF=E6=8C=81=E5=B5=8C?= =?UTF-8?q?=E5=A5=97=E5=B1=95=E5=BC=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/settings/categories/fullScreenLyric.ts | 87 ++++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/src/settings/categories/fullScreenLyric.ts b/src/settings/categories/fullScreenLyric.ts index 659ad3b..c80bffe 100644 --- a/src/settings/categories/fullScreenLyric.ts +++ b/src/settings/categories/fullScreenLyric.ts @@ -18,6 +18,7 @@ const fullScreenLyricCategory: SettingCategory = { { value: "amll", labelKey: "settings.lyricEngine.amll" }, ], defaultValue: "physics", + hideChildren: true, childrenCondition: () => useSettingsStore().lyric.engine === "amll", children: [ { @@ -25,6 +26,82 @@ const fullScreenLyricCategory: SettingCategory = { type: "switch", binding: { store: "settings", path: "lyric.useAMSpring" }, defaultValue: true, + hideChildren: true, + childrenCondition: () => useSettingsStore().lyric.useAMSpring, + children: [ + { + key: "amllVerticalSpringMass", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringMass" }, + min: 0.1, + max: 5, + step: 0.1, + defaultValue: 1, + marks: { 0.1: "0.1", 1: "1", 5: "5" }, + }, + { + key: "amllVerticalSpringDamping", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringDamping" }, + min: 0, + max: 40, + step: 0.5, + defaultValue: 15, + marks: { 0: "0", 15: "15", 40: "40" }, + }, + { + key: "amllVerticalSpringStiffness", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringStiffness" }, + min: 1, + max: 300, + step: 1, + defaultValue: 100, + marks: { 1: "1", 100: "100", 300: "300" }, + }, + { + key: "amllVerticalSpringSoft", + type: "switch", + binding: { store: "settings", path: "lyric.amllVerticalSpringSoft" }, + defaultValue: false, + }, + { + key: "amllScaleSpringMass", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringMass" }, + min: 0.1, + max: 5, + step: 0.1, + defaultValue: 1, + marks: { 0.1: "0.1", 1: "1", 5: "5" }, + }, + { + key: "amllScaleSpringDamping", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringDamping" }, + min: 0, + max: 40, + step: 0.5, + defaultValue: 20, + marks: { 0: "0", 20: "20", 40: "40" }, + }, + { + key: "amllScaleSpringStiffness", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringStiffness" }, + min: 1, + max: 300, + step: 1, + defaultValue: 100, + marks: { 1: "1", 100: "100", 300: "300" }, + }, + { + key: "amllScaleSpringSoft", + type: "switch", + binding: { store: "settings", path: "lyric.amllScaleSpringSoft" }, + defaultValue: false, + }, + ], }, ], }, @@ -81,21 +158,21 @@ const fullScreenLyricCategory: SettingCategory = { type: "switch", binding: { store: "settings", path: "lyric.enableWordHighlight" }, defaultValue: true, - disabled: () => useSettingsStore().lyric.engine === "amll", + visible: () => useSettingsStore().lyric.engine === "physics", }, { key: "enableFloatAnimation", type: "switch", binding: { store: "settings", path: "lyric.enableFloatAnimation" }, defaultValue: false, - disabled: () => useSettingsStore().lyric.engine === "amll", + visible: () => useSettingsStore().lyric.engine === "physics", }, { key: "enableEmphasizeEffect", type: "switch", binding: { store: "settings", path: "lyric.enableEmphasizeEffect" }, defaultValue: false, - disabled: () => useSettingsStore().lyric.engine === "amll", + visible: () => useSettingsStore().lyric.engine === "physics", }, { key: "enableBlur", @@ -128,7 +205,7 @@ const fullScreenLyricCategory: SettingCategory = { { value: "custom", labelKey: "settings.springPreset.custom" }, ], defaultValue: "default", - disabled: () => useSettingsStore().lyric.engine === "amll", + visible: () => useSettingsStore().lyric.engine === "physics", childrenCondition: () => useSettingsStore().lyric.engine !== "amll" && useSettingsStore().lyric.springPreset === "custom", @@ -199,7 +276,7 @@ const fullScreenLyricCategory: SettingCategory = { step: 0.05, defaultValue: 0.2, marks: { 0: "0", 0.2: "0.2", 1: "1" }, - disabled: () => useSettingsStore().lyric.engine === "amll", + visible: () => useSettingsStore().lyric.engine === "physics", }, ], }, From f2b73cf54ac845e6c6ac0d6ed0fafc914138941a Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:27:26 +0800 Subject: [PATCH 14/22] =?UTF-8?q?feat:=20AMLL=20=E9=80=82=E9=85=8D?= =?UTF-8?q?=E8=87=AA=E9=80=82=E5=BA=94=E5=AD=97=E5=8F=B7=EF=BC=8C=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E7=89=A9=E7=90=86=E5=BC=B9=E7=B0=A7=E5=BE=AE=E8=B0=83?= =?UTF-8?q?=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/player/Lyrics/AMLLLyrics.vue | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/components/player/Lyrics/AMLLLyrics.vue b/src/components/player/Lyrics/AMLLLyrics.vue index 834d570..65fea26 100644 --- a/src/components/player/Lyrics/AMLLLyrics.vue +++ b/src/components/player/Lyrics/AMLLLyrics.vue @@ -159,6 +159,19 @@ watchEffect(() => { const useSpring = settings.lyric.useAMSpring; playerRef.value.setEnableSpring(useSpring); playerRef.value.setEnableScale(useSpring); + + playerRef.value.setLinePosYSpringParams({ + mass: settings.lyric.amllVerticalSpringMass, + damping: settings.lyric.amllVerticalSpringDamping, + stiffness: settings.lyric.amllVerticalSpringStiffness, + soft: settings.lyric.amllVerticalSpringSoft, + }); + playerRef.value.setLineScaleSpringParams({ + mass: settings.lyric.amllScaleSpringMass, + damping: settings.lyric.amllScaleSpringDamping, + stiffness: settings.lyric.amllScaleSpringStiffness, + soft: settings.lyric.amllScaleSpringSoft, + }); } }); @@ -221,6 +234,7 @@ defineExpose({ } :deep(.amll-lyric-player) { + --amll-lp-font-size: 1em; width: 100%; height: 100%; padding-left: 10%; From be1884a81b4af30bae5c8aa699be9850fe0832c7 Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:33:46 +0800 Subject: [PATCH 15/22] =?UTF-8?q?chore:=20=E8=A1=A5=E5=85=A8=20AMLL=20?= =?UTF-8?q?=E4=B8=93=E5=B1=9E=E5=BC=B9=E7=B0=A7=E5=BE=AE=E8=B0=83=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E9=A1=B9=E7=9A=84=E4=B8=AD=E8=8B=B1=E6=96=87=E5=A4=9A?= =?UTF-8?q?=E8=AF=AD=E8=A8=80=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/i18n/locales/en-US.json | 32 ++++++++++++++++++++++++++++++++ src/i18n/locales/zh-CN.json | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 8baf766..58c3a69 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -851,6 +851,38 @@ "label": "Physics Spring & Scale", "description": "Enable spring bounce and active line scaling effects for applemusic-like-lyrics" }, + "amllVerticalSpringMass": { + "label": "Vertical Spring Mass", + "description": "Mass of the vertical scrolling physics spring. Larger mass increases spring inertia." + }, + "amllVerticalSpringDamping": { + "label": "Vertical Spring Damping", + "description": "Damping of the vertical scrolling physics spring. Larger damping reduces oscillation and settles faster." + }, + "amllVerticalSpringStiffness": { + "label": "Vertical Spring Stiffness", + "description": "Stiffness of the vertical scrolling physics spring. Larger stiffness pulls harder and bounces quicker." + }, + "amllVerticalSpringSoft": { + "label": "Vertical Soft Spring", + "description": "Forces the vertical scrolling to use a softer spring profile." + }, + "amllScaleSpringMass": { + "label": "Scale Spring Mass", + "description": "Mass of the active line scale animation. Larger mass increases scale bounce inertia." + }, + "amllScaleSpringDamping": { + "label": "Scale Spring Damping", + "description": "Damping of the active line scale animation. Larger damping reduces scale jitter and settles faster." + }, + "amllScaleSpringStiffness": { + "label": "Scale Spring Stiffness", + "description": "Stiffness of the active line scale animation. Larger stiffness responds and scales quicker." + }, + "amllScaleSpringSoft": { + "label": "Scale Soft Spring", + "description": "Forces the active line scale animation to use a softer spring profile." + }, "autoCenterCover": { "label": "Auto Center Cover", "description": "Center cover and hide lyric area when no lyrics available" diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index de6a915..9d60405 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -839,6 +839,38 @@ "label": "物理回弹与缩放", "description": "为 Apple Music 风格歌词行启用物理弹性回弹与焦点行缩放效果" }, + "amllVerticalSpringMass": { + "label": "垂直回弹质量", + "description": "垂直弹性滚动的惯性质量。质量越大,回弹惯性越大" + }, + "amllVerticalSpringDamping": { + "label": "垂直回弹阻尼", + "description": "垂直弹性滚动的阻尼阻力。阻力越大,回弹振幅越小且越快静止" + }, + "amllVerticalSpringStiffness": { + "label": "垂直回弹刚度", + "description": "垂直弹性滚动的弹簧刚度。刚度越大,拉力越强,回弹速度越快" + }, + "amllVerticalSpringSoft": { + "label": "垂直强制软弹簧", + "description": "启用后将强制使用较软的垂直滚动弹簧动效" + }, + "amllScaleSpringMass": { + "label": "缩放回弹质量", + "description": "焦点行缩放动画的质量。值越大,缩放回弹的惯性越大" + }, + "amllScaleSpringDamping": { + "label": "缩放回弹阻尼", + "description": "焦点行缩放动画的阻尼阻力。值越大,缩放震荡越少且越快静止" + }, + "amllScaleSpringStiffness": { + "label": "缩放回弹刚度", + "description": "焦点行缩放动画的弹簧刚度。值越大,缩放回弹越迅速" + }, + "amllScaleSpringSoft": { + "label": "缩放强制软弹簧", + "description": "启用后将强制使用较软的焦点行缩放弹簧动效" + }, "autoCenterCover": { "label": "自动居中封面", "description": "无歌词时自动居中封面并隐藏歌词区域" From 6191bf59076805d67dd6d4bc10fc5ccf4ab6448b Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 00:54:17 +0800 Subject: [PATCH 16/22] =?UTF-8?q?refactor:=20=E8=A1=A5=E5=85=A8=E6=89=81?= =?UTF-8?q?=E5=B9=B3=E5=8C=96=20AMLL=20=E5=BC=B9=E7=B0=A7=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E5=88=86=E5=8C=BA=E5=B9=B6=E8=A1=A5=E9=BD=90=E7=BF=BB?= =?UTF-8?q?=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/settings/SettingsItem.vue | 14 +- src/i18n/locales/en-US.json | 9 +- src/i18n/locales/zh-CN.json | 11 +- src/settings/categories/fullScreenLyric.ts | 187 +++++++++++---------- src/types/settings-schema.ts | 5 +- 5 files changed, 135 insertions(+), 91 deletions(-) diff --git a/src/components/settings/SettingsItem.vue b/src/components/settings/SettingsItem.vue index 09b80c2..fe718d7 100644 --- a/src/components/settings/SettingsItem.vue +++ b/src/components/settings/SettingsItem.vue @@ -19,6 +19,7 @@ const selectOptions = computed(() => ); const isChildrenActive = computed(() => { + if (props.item.type === "title") return true; if (props.item.childrenCondition) return props.item.childrenCondition(); return model.value === true; }); @@ -39,6 +40,14 @@ const descriptionText = computed(() => class="transition-all duration-300" :class="highlighted ? 'animate-highlight-pulse' : ''" /> + +
+ + {{ t(`settings.${item.key}.label`) }} +
diff --git a/src/i18n/locales/en-US.json b/src/i18n/locales/en-US.json index 58c3a69..5e9e1be 100644 --- a/src/i18n/locales/en-US.json +++ b/src/i18n/locales/en-US.json @@ -648,6 +648,7 @@ "lyricDisplay": "Display Effects", "lyricSpring": "Spring Animation", "lyricLayout": "Layout & Opacity", + "amllLyricSpring": "Physics Spring & Scale", "desktopLyric": "Desktop Lyric", "dynamicIsland": "Dynamic Island Lyric", "taskbarLyric": "Taskbar Lyric", @@ -848,9 +849,15 @@ "amll": "AMLL" }, "useAMSpring": { - "label": "Physics Spring & Scale", + "label": "Spring Animation Debug Switch", "description": "Enable spring bounce and active line scaling effects for applemusic-like-lyrics" }, + "amllVerticalSpringHeader": { + "label": "Vertical Translation Spring Parameters" + }, + "amllScaleSpringHeader": { + "label": "Scale Spring Parameters" + }, "amllVerticalSpringMass": { "label": "Vertical Spring Mass", "description": "Mass of the vertical scrolling physics spring. Larger mass increases spring inertia." diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 9d60405..aa3795a 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -636,6 +636,7 @@ "lyricDisplay": "显示效果", "lyricSpring": "弹簧动画", "lyricLayout": "布局与透明度", + "amllLyricSpring": "物理回弹与缩放", "desktopLyric": "桌面歌词", "dynamicIsland": "灵动岛歌词", "taskbarLyric": "任务栏歌词", @@ -836,8 +837,14 @@ "amll": "AMLL" }, "useAMSpring": { - "label": "物理回弹与缩放", - "description": "为 Apple Music 风格歌词行启用物理弹性回弹与焦点行缩放效果" + "label": "弹簧动画调试开关", + "description": "为 applemusic-like-lyrics 启用物理弹性回弹与焦点行缩放效果" + }, + "amllVerticalSpringHeader": { + "label": "垂直位移弹簧参数" + }, + "amllScaleSpringHeader": { + "label": "缩放弹簧参数" }, "amllVerticalSpringMass": { "label": "垂直回弹质量", diff --git a/src/settings/categories/fullScreenLyric.ts b/src/settings/categories/fullScreenLyric.ts index c80bffe..6018303 100644 --- a/src/settings/categories/fullScreenLyric.ts +++ b/src/settings/categories/fullScreenLyric.ts @@ -18,92 +18,6 @@ const fullScreenLyricCategory: SettingCategory = { { value: "amll", labelKey: "settings.lyricEngine.amll" }, ], defaultValue: "physics", - hideChildren: true, - childrenCondition: () => useSettingsStore().lyric.engine === "amll", - children: [ - { - key: "useAMSpring", - type: "switch", - binding: { store: "settings", path: "lyric.useAMSpring" }, - defaultValue: true, - hideChildren: true, - childrenCondition: () => useSettingsStore().lyric.useAMSpring, - children: [ - { - key: "amllVerticalSpringMass", - type: "slider", - binding: { store: "settings", path: "lyric.amllVerticalSpringMass" }, - min: 0.1, - max: 5, - step: 0.1, - defaultValue: 1, - marks: { 0.1: "0.1", 1: "1", 5: "5" }, - }, - { - key: "amllVerticalSpringDamping", - type: "slider", - binding: { store: "settings", path: "lyric.amllVerticalSpringDamping" }, - min: 0, - max: 40, - step: 0.5, - defaultValue: 15, - marks: { 0: "0", 15: "15", 40: "40" }, - }, - { - key: "amllVerticalSpringStiffness", - type: "slider", - binding: { store: "settings", path: "lyric.amllVerticalSpringStiffness" }, - min: 1, - max: 300, - step: 1, - defaultValue: 100, - marks: { 1: "1", 100: "100", 300: "300" }, - }, - { - key: "amllVerticalSpringSoft", - type: "switch", - binding: { store: "settings", path: "lyric.amllVerticalSpringSoft" }, - defaultValue: false, - }, - { - key: "amllScaleSpringMass", - type: "slider", - binding: { store: "settings", path: "lyric.amllScaleSpringMass" }, - min: 0.1, - max: 5, - step: 0.1, - defaultValue: 1, - marks: { 0.1: "0.1", 1: "1", 5: "5" }, - }, - { - key: "amllScaleSpringDamping", - type: "slider", - binding: { store: "settings", path: "lyric.amllScaleSpringDamping" }, - min: 0, - max: 40, - step: 0.5, - defaultValue: 20, - marks: { 0: "0", 20: "20", 40: "40" }, - }, - { - key: "amllScaleSpringStiffness", - type: "slider", - binding: { store: "settings", path: "lyric.amllScaleSpringStiffness" }, - min: 1, - max: 300, - step: 1, - defaultValue: 100, - marks: { 1: "1", 100: "100", 300: "300" }, - }, - { - key: "amllScaleSpringSoft", - type: "switch", - binding: { store: "settings", path: "lyric.amllScaleSpringSoft" }, - defaultValue: false, - }, - ], - }, - ], }, ], }, @@ -206,6 +120,7 @@ const fullScreenLyricCategory: SettingCategory = { ], defaultValue: "default", visible: () => useSettingsStore().lyric.engine === "physics", + indentChildren: false, childrenCondition: () => useSettingsStore().lyric.engine !== "amll" && useSettingsStore().lyric.springPreset === "custom", @@ -280,6 +195,106 @@ const fullScreenLyricCategory: SettingCategory = { }, ], }, + { + id: "amllLyricSpring", + items: [ + { + key: "useAMSpring", + type: "switch", + binding: { store: "settings", path: "lyric.useAMSpring" }, + defaultValue: true, + visible: () => useSettingsStore().lyric.engine === "amll", + hideChildren: true, + childrenCondition: () => useSettingsStore().lyric.useAMSpring, + children: [ + { + key: "amllVerticalSpringHeader", + type: "title", + children: [ + { + key: "amllVerticalSpringMass", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringMass" }, + min: 0.1, + max: 5, + step: 0.1, + defaultValue: 1, + marks: { 0.1: "0.1", 1: "1", 5: "5" }, + }, + { + key: "amllVerticalSpringDamping", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringDamping" }, + min: 0, + max: 40, + step: 0.5, + defaultValue: 15, + marks: { 0: "0", 15: "15", 40: "40" }, + }, + { + key: "amllVerticalSpringStiffness", + type: "slider", + binding: { store: "settings", path: "lyric.amllVerticalSpringStiffness" }, + min: 1, + max: 300, + step: 1, + defaultValue: 100, + marks: { 1: "1", 100: "100", 300: "300" }, + }, + { + key: "amllVerticalSpringSoft", + type: "switch", + binding: { store: "settings", path: "lyric.amllVerticalSpringSoft" }, + defaultValue: false, + }, + ], + }, + { + key: "amllScaleSpringHeader", + type: "title", + children: [ + { + key: "amllScaleSpringMass", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringMass" }, + min: 0.1, + max: 5, + step: 0.1, + defaultValue: 1, + marks: { 0.1: "0.1", 1: "1", 5: "5" }, + }, + { + key: "amllScaleSpringDamping", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringDamping" }, + min: 0, + max: 40, + step: 0.5, + defaultValue: 20, + marks: { 0: "0", 20: "20", 40: "40" }, + }, + { + key: "amllScaleSpringStiffness", + type: "slider", + binding: { store: "settings", path: "lyric.amllScaleSpringStiffness" }, + min: 1, + max: 300, + step: 1, + defaultValue: 100, + marks: { 1: "1", 100: "100", 300: "300" }, + }, + { + key: "amllScaleSpringSoft", + type: "switch", + binding: { store: "settings", path: "lyric.amllScaleSpringSoft" }, + defaultValue: false, + }, + ], + }, + ], + }, + ], + }, ], }; diff --git a/src/types/settings-schema.ts b/src/types/settings-schema.ts index 9cd565c..c3d3f57 100644 --- a/src/types/settings-schema.ts +++ b/src/types/settings-schema.ts @@ -8,7 +8,8 @@ export type SettingWidgetType = | "color" | "button" | "custom" - | "number"; + | "number" + | "title"; /** 选择项 */ export interface SettingOption { @@ -67,6 +68,8 @@ export interface SettingItem { childrenCondition?: () => boolean; /** 是否完全隐藏子项 */ hideChildren?: boolean; + /** 是否对子项进行左侧边线和缩进(默认 true) */ + indentChildren?: boolean; /** 标题旁的徽标 */ tag?: SettingTag; } From d044e61f02f0ae79cfab624d289754475e01d6fd Mon Sep 17 00:00:00 2001 From: ITManCHINA <1678812512@qq.com> Date: Fri, 19 Jun 2026 01:04:37 +0800 Subject: [PATCH 17/22] =?UTF-8?q?refactor:=20=E4=BC=98=E5=8C=96=E7=BC=A9?= =?UTF-8?q?=E8=BF=9B=E4=B8=8E=E6=A0=BC=E5=BC=8F=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/player/FullPlayer/BackgroundRender.vue | 8 ++------ src/components/player/FullPlayer/PlayerBackground.vue | 5 ++++- src/components/player/Lyrics/AMLLLyrics.vue | 4 ++-- src/components/settings/SettingsItem.vue | 4 +++- src/components/settings/SettingsSection.vue | 4 +++- src/utils/lyric/parse.ts | 5 ++++- src/utils/lyric/parseTTML.ts | 4 +++- 7 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/components/player/FullPlayer/BackgroundRender.vue b/src/components/player/FullPlayer/BackgroundRender.vue index 665271c..c56d00e 100644 --- a/src/components/player/FullPlayer/BackgroundRender.vue +++ b/src/components/player/FullPlayer/BackgroundRender.vue @@ -118,7 +118,7 @@ onMounted(() => { if (wrapperRef.value) { // 初始化 AMLL 底层渲染器 bgRenderRef.value = CoreBackgroundRender.new(props.renderer); - + // 设置 Canvas 自适应容器并附着 DOM const el = bgRenderRef.value.getElement(); el.style.width = "100%"; @@ -212,11 +212,7 @@ defineExpose({ diff --git a/src/components/player/Lyrics/renderer.css b/src/components/player/Lyrics/renderer.css index 81538fd..f3219c7 100644 --- a/src/components/player/Lyrics/renderer.css +++ b/src/components/player/Lyrics/renderer.css @@ -120,6 +120,22 @@ .lp-credit { opacity: var(--lp-credit-opacity, 0.3); + pointer-events: auto !important; /* 启用交互并阻止点击穿透到下方的普通歌词行上 */ + z-index: 10 !important; /* 提升层级,防止被普通歌词行(尤其是最后一行)遮挡和阻断点击 */ + background: none !important; + background-color: transparent !important; + box-shadow: none !important; + border: none !important; + outline: none !important; +} + +.lp-credit:hover, +.lp-credit:active { + background: none !important; + background-color: transparent !important; + box-shadow: none !important; + border: none !important; + outline: none !important; } .lp-credit:empty {