听心 (经典版) - 魏佳艺 TO:亚纶
<style>
#papa {margin: 120px -340px;
width: 1286px;
height: 720px;
border: 0px solid gray;
background:radial-gradient(ellipse farthest-corner at center center, transparent 38%,#999 90%),url(https://wj.zp68.com/lxx/yunhua/2025/10/06/04.jpg),linear-gradient(135deg, #e56420, #c22525, #3d9c31, #000078);
overflow: hidden;
position: relative;
--state: running;
}
.k-container-body {margin: 180px 390px;
position: absolute;transform:rotatey(0deg);
background: linear-gradient(45deg,
#000078, #000, #880000, #00aa00, #00aa7f, #111111, #00bb00, #ff0000);
border: 3px solid #d0d0d0;
border-radius: 20px;
width: 550px;
height: 320px;
perspective: 10000;
padding: 10px;overflow: hidden;
}
.k-container-body:before,
.k-container-body:after {
content: '';
position: absolute;
bottom: 20px;
height: 90px;
width: 35px;
border-radius: 10px;
z-index: -1;
}
.k-container-body:before {
border-left: 3px solid #d0d0d0;
left: -12px;
}
.k-container-body:after {
border-right: 3px solid #d0d0d0;
right: -12px;
}
.k-screw {
position: absolute;
display: inline-block;
border: 1px solid #d0d0d0;
border-radius: 50%;
width: 14px;
height: 14px;
}
.k-screw:before,
.k-screw:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transform-origin: center;
background-color: #d0d0d0;
height: 70%;
width: 2px;
}
.k-screw:before {
transform: translate(-50%, -50%) rotate(90deg);
}
.body .k-screw:after {
transform: translate(-50%, -50%) rotate(-90deg);
}
.k-screw.top-left {transform:rotateZ(12deg);
top: 7px;
left: 7px;
}
.k-screw.top-right {transform:rotateZ(-5deg);
top: 7px;
right: 7px;
}
.k-screw.bottom-left {transform:rotateZ(8deg);
bottom: 7px;
left: 7px;
}
.k-screw.bottom-right {transform:rotateZ(-10deg);
bottom: 7px;
right: 7px;
}
.k-centerreel {box-sizing: border-box;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 3px solid #d0d0d0;
border-radius: 45px;
width: 300px;
height: 90px;background: linear-gradient(45deg,
#000078, #000, #ff0000, #ffd700, #00aa7f, #111111, #999999, #000080);
padding: 10px;
}
.k-centerreel .reel {
position: relative;
display: inline-block;
border: 2px solid #d0d0d0;
width: 65px;
height: 100%;
border-radius: 50%;
}
.k-centerreel .reel:before {
content: '';
display: inline-block;
width: 82%;
height: 82%;
border: 6px dashed #d0d0d0;
border-radius: 50%;
transform-origin: center;
animation: spin 3s linear infinite var(--state);
}
.k-centerreel .reel.left {
float: left;
}
.k-centerreel .reel.right {
float: right;
}
.k-centerreel .center-tape {
border: 2px solid #d0d0d0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 70%;
width: 100px;
border-radius: 10px;
overflow: hidden;
}
.k-centerreel .center-tape:before {
content: '';
border: 3px solid #d0d0d0;
border-radius: 50%;
width: 80px;
height: 80px;
position: absolute;
top: 50%;
transform: translateY(-50%);
left: -50%;
animation: shiftLeft 1.3s ease-in-out alternate infinite var(--state);
}
.k-centerreel .center-tape:after {
content: '';
border: 3px solid #d0d0d0;
border-radius: 50%;
width: 100px;
height: 100px;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: -95%;
animation: shiftRight 1s ease-in-out alternate infinite var(--state);
}
.k-label {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #d0d0d0;
top: 25%;
max-width: 400px;
width: 100%;
padding: 0px 20px;
overflow: hidden;
}
.k-label:before {
content: '';
position: absolute;
bottom: 1.85ex;
left: 0;
right: 0;
height: 2.5ex;
border-top: 1px dashed #d0d0d0;
border-bottom: 3px dashed #d0d0d0;
z-index: -1;
}
.k-chin {
position: absolute;
left: 10%;
bottom: -6px;
transform:perspective(1em) rotateX(3deg);
transform-origin: bottom center;
max-width: 450px;
width: 100%;
height: 120px;background: linear-gradient(45deg,
#000078, #000, #ff0000, #ffd700, #00aa7f, #111111, #999999, #000080);
border-radius: 5px;
font-size: 60px;
border: 2px solid #d0d0d0;
}
.k-chin:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
top: 30%;
background: #eee;
width: 10px;
height: 10px;
border-radius: 20%;
}
.k-chin .holes {transform:rotateX(-65deg);
position: absolute;
display: inline-block;
border: 3px solid #d0d0d0;
border-radius: 20%;
}
.k-chin .holes:nth-child(1) {
width: 15px;
height: 20px;
bottom: 15px;
left: 40px;
}
.k-chin .holes:nth-child(2) {
width: 10px;
height: 20px;
bottom: 50px;
left: 80px;
}
.k-chin .holes:nth-child(3) {
width: 10px;
height: 20px;
bottom: 50px;
right: 80px;
}
.k-chin .holes:nth-child(4) {
width: 15px;
height: 20px;
bottom: 15px;
right: 40px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes shiftLeft {
0% {
left: -50%;
}
100% {
left: -53%;
}
}
@keyframes shiftRight {
0% {
right: -95%;
}
100% {
right: -93%;
}
}
.lyrics{margin: 0;
top: 22%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px; /**/
text-align: center;
position: absolute;z-index: 1;
}
.lyric-line{
width: 100%;
position: relative;
height: 60px;
overflow: visible;
font: 400 30px '仿宋', sans-serif;
line-height: 60px;
text-align: left;
white-space: nowrap; /**/
}
.lyric-mask {
position: absolute;
top: 0;
left: 0;
width: 0;
overflow: hidden;
color: #eee;
height: 100%;
white-space: nowrap;
}
.lyric-original {
color: #800000;
white-space: nowrap;
}
#player {
position: absolute;z-index: 40;
left:5%;
bottom: 260px;
width: 100px;
height: 40px;
opacity: 1;
transition: .4s;
display: grid;
place-items: center;
--sp1: 0; --sp2: 1;
}
#player::before, #player::after {
position: absolute;
content: '';
cursor: pointer;
transition: .4s;
}
#player::before {width: 100%;height: 100%;background:url(https://pic1.imgdb.cn/item/68ff14983203f7be00a5fd1b.png)no-repeat center/cover;
opacity: var(--sp1);}
#player::after {width: 100%;height: 100%;background:url(https://pic1.imgdb.cn/item/68ff14983203f7be00a5fd1c.png )no-repeat center/cover;
opacity: var(--sp2);}
#tmsg {position: absolute;z-index: 1;
font: normal 14px sans-serif;
color: #eee;
bottom: 35px;
left:250px;}
#prog {position: absolute;z-index: 8;filter:invert(0%) hue-rotate(0deg);
width: 444px;
height: 6px;
cursor: pointer;
bottom: 252px;
left:11%;}
</style>
<div id="papa">
<div class="k-container-body">
<span class="k-screw top-left"></span>
<span class="k-screw top-right"></span>
<span class="k-screw bottom-left"></span>
<span class="k-screw bottom-right"></span>
<div class="k-centerreel">
<div class="reel left"></div>
<div class="center-tape"></div>
<div class="reel right"></div>
</div>
<div class="k-label"></div>
<div class="k-chin">
<span class="holes"></span>
<span class="holes"></span>
<span class="holes"></span>
<span class="holes"></span>
</div>
<div class="lyrics" >
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
<div id="player" title="暂停/播放" ></div>
<div id="tmsg">00:00/00:00</div>
<progress id="prog"></progress>
</div>
</div>
<audio id="aud" src="https://aod.cos.tx.xmcdn.com/storages/5a0e-audiofreehighqps/99/12/GMCoOR4JYQAeACAAAAKSuus2.m4a" loop autoplay></audio>
<script>
const kcenterreel = document.querySelector('.k-centerreel');
const kcontainerbody= document.querySelector('.k-container-body');
player.onclick = () => aud.paused ? aud.play() : aud.pause();
mState = () => papa.style.setProperty('--state',aud.paused ? (player.style.setProperty('--sp1','1' ), player.style.setProperty('--sp2','0'),'paused') : (player.style.setProperty('--sp1','0'), player.style.setProperty('--sp2','1'),'running'));
aud.onplaying = aud.onpause = () => mState();
aud.ontimeupdate = () => prog.value=aud.currentTime/aud.duration;
prog.onclick = (e) => aud.currentTime=aud.duration*e.offsetX/prog.offsetWidth;
aud.addEventListener('timeupdate', () => {
tmsg.innerText = toMin(aud.currentTime) + '/' + toMin(aud.duration);
});
function toMin(val) {
if (!val) return '00:00';
val = Math.floor(val);
let min = parseInt(val / 60);
let sec = parseFloat(val % 60);
if (min < 10) min = '0' + min;
if (sec < 10) sec = '0' + sec;
return min + ':' + sec;
}
</script>
<script>
// ksclrc
const lrc = `听心 (经典版) - 魏佳艺
词:郭高见
曲:陈伟
编曲:李德奎
混音:潘君明
和声:夏初安
制作人:郜锦标
企划/统筹:吴聪聪
宣传推广:郜锦标/吴聪聪
艺人统筹:刘丹
OP:北京嘎嘎飙壹文化传媒有限公司
(此版本为正式授权翻唱作品)
闭上眼我想看见你
屏住了所有的呼吸
我怕你走错了轨迹
做了心跳的标记
在梦里总有个秘密
总是让我挥之不去
忍不住探索了心底
为何你摸索了离去
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近你一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
闭上眼我想看见你
屏住了所有的呼吸
我怕你走错了轨迹
做了心跳的标记
在梦里总有个秘密
总是让我挥之不去
忍不住探索了心底
为何你摸索了离去
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
就算我说我爱你
就算我说我想你
你也不能听到我的心
依然停留在这孤寂里
我想再靠近一点
我想再走近一点
让你能够听到我的心
什么时候也能把我想起
让你能够听到我的心
什么时候也能把我想起
`;
const lyrics = parseLyrics(lrc);
const lyricMask = document.querySelector('.lyric-mask');
const lyricOriginal = document.querySelector('.lyric-original');
let currentIndex = -1;
let currentLyric = null;
//
function parseLyrics(lrcText) {
const lyrics = [];
if (lrcText.includes('karaoke.add')) {
const lineRegex = /karaoke\.add\('([^']+)', '([^']+)', '([^']+)', '([^']+)'\);/g;
let match;
while ((match = lineRegex.exec(lrcText)) !== null) {
const startTime = timeToMs(match);
const endTime = timeToMs(match);
const text = match.replace(/\[|\]/g, '').trim();
const durations = match.split(',').map(Number);
if (text) {
lyrics.push({startTime, endTime, text, durations});
}
}
}
else if (lrcText.includes('[')) {
const lines = lrcText.split('\n').filter(line => line.trim());
lines.forEach((line, index) => {
const timeMatch = line.match(/\[(\d+:\d+\.\d+)\]/);
if (timeMatch) {
const timeStr = timeMatch;
const text = line.replace(/\[.*?\]/, '').trim();
if (text) {
const startTime = timeToMs(timeStr);
const nextLine = lines;
const nextTimeMatch = nextLine ? nextLine.match(/\[(\d+:\d+\.\d+)\]/) : null;
const endTime = nextTimeMatch ? timeToMs(nextTimeMatch) : startTime + 5000;
lyrics.push({
startTime,
endTime,
text,
durations: calculateCharDurations(text, startTime, endTime)
});
}
}
});
}
return lyrics;
}
function calculateCharDurations(text, startTime, endTime) {
const totalDuration = endTime - startTime;
const charCount = text.length;
const baseDur = Math.floor(totalDuration / charCount);
const durations = new Array(charCount).fill(baseDur);
const remainder = totalDuration % charCount;
for (let i = 0; i < remainder; i++) {
durations++;
}
return durations;
}
function timeToMs(timeStr) {
const parts = timeStr.split(':');
const minutes = parseInt(parts, 10);
const secondsAndMs = parts.split('.');
const seconds = parseInt(secondsAndMs, 10);
const ms = parseInt(secondsAndMs || 0, 10);
return minutes * 60 * 1000 + seconds * 1000 + ms;
}
function getCurrentLyricIndex(lyrics, currentTimeMs) {
for (let i = 0; i < lyrics.length; i++) {
if (currentTimeMs >= lyrics.startTime && currentTimeMs <= lyrics.endTime) {
return i;
}
}
return -1;
}
function updateLyricDisplay(index) {
if (index < 0 || index >= lyrics.length) return;
currentIndex = index;
currentLyric = lyrics;
lyricOriginal.textContent = currentLyric.text;
lyricMask.textContent = currentLyric.text;
lyricMask.style.width = '0%';
}
function updateLyricMask(currentTimeMs) {
if (!currentLyric) return;
const lyricStartTime = currentLyric.startTime;
const elapsed = currentTimeMs - lyricStartTime;
const totalDuration = currentLyric.durations.reduce((sum, d) => sum + d, 0);
let charIndex = 0;
let accumulatedTime = 0;
for (let i = 0; i < currentLyric.durations.length; i++) {
accumulatedTime += currentLyric.durations;
if (elapsed <= accumulatedTime) {
charIndex = i + 1;
break;
}
}
if (elapsed >= totalDuration) {
charIndex = currentLyric.text.length;
}
charIndex = Math.min(charIndex, currentLyric.text.length);
const tempSpan = document.createElement('span');
tempSpan.style.visibility = 'hidden';
tempSpan.style.position = 'absolute';
tempSpan.style.fontSize = '50px';
tempSpan.style.fontWeight = '800';
document.body.appendChild(tempSpan);
const visibleText = currentLyric.text.substring(0, charIndex);
tempSpan.textContent = visibleText;
const width = tempSpan.offsetWidth;
document.body.removeChild(tempSpan);
lyricMask.style.width = `${width}px`;
}
//
aud.addEventListener('timeupdate', () => {
const currentTimeMs = aud.currentTime * 1000;
const index = getCurrentLyricIndex(lyrics, currentTimeMs);
if (index !== currentIndex) {
updateLyricDisplay(index);
}
updateLyricMask(currentTimeMs);
});
updateLyricDisplay(0);
</script>
亚纶最近发现你制作了好几个纯代码的播放器,小辣椒套用玩一个 亲爱的也做了这个磁带的闭风器,真漂亮,还加入了花潮因素呢。
欣赏亲爱的好帖,亚伦老师收礼开心{:4_199:} 小辣椒 发表于 2025-10-27 23:03
亚纶最近发现你制作了好几个纯代码的播放器,小辣椒套用玩一个
真漂亮,真漂亮。 好看,点赞!{:4_187:} 这个磁带式的播放器
有点复古的感觉
一下子就回到了几十年前
那时候录音机刚兴起的时候
玩得不亦乐乎
还可以买空白磁带
转录歌曲玩
{:4_178:}
这首歌不陌生
抖音里常听到
很是温馨动人
{:4_204:} 好漂亮,小辣椒真棒!{:5_150:} 不错不错!!
页:
[1]