ksc歌词【人间疾苦】
本帖最后由 亚伦影音工作室 于 2025-8-10 08:44 编辑 <br /><br /><style >#bj {
position: relative;
width: 1286px;
height: 700px;
margin-left: -300px;
margin-top: 140px;
overflow: hidden;
background: url(https://pic1.imgdb.cn/item/689714a158cb8da5c814a178.jpg) no-repeat center / cover;
}
.intro {margin: 0px0px;
width: 100%;
height:100%;
position: absolute;
background: url(https://pic1.imgdb.cn/item/689714a158cb8da5c814a178.jpg), linear-gradient(145deg, #e56420, #c22525, #3d9c31, #37bbde);
background-size: cover;
background-blend-mode: hard-light;
animation: hue-rotate 3s linear infinite;
}
@keyframes hue-rotate {
from {
filter: hue-rotate(0);
}
to {
filter: hue-rotate(360deg);
}
}
.lyrics{margin: 0;z-index: 21;
top: 89%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px; /* 调整高度,只容纳当前歌词 */
text-align: center;
position: absolute;
}
.lyric-line{
width: 100%;
position: relative;
height: 60px;
overflow: visible;
font: 300 50px '华文隶书', sans-serif;
line-height: 60px;
text-align: left;
white-space: nowrap; /* 禁止换行 */
filter: drop-shadow(#fff 1px 0 0) drop-shadow(#fff 0 1px 0) drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px 0);
}
.lyric-mask {
position: absolute;
top: 0;
left: 0;
width: 0;
overflow: hidden;
color: #8B4513;
height: 100%;
white-space: nowrap;
}
.lyric-original {
color: #ag0000;
white-space: nowrap;
}
#sparkCanvas{ width: 1286px;
height: 700px;pointer-events: none;
position: absolute;overflow: hidden;
left:0;top: 0px;z-index:1;
}
#bfq{
position:absolute;
width: 450px;
height:350px;overflow: hidden;
background:#0000;
transform:scale(1);bottom: 38%;
left:55%;z-index: 20;}
#cp{
position:absolute;
width: 240px;border-radius: 50%;
height:240px;animation: rotating 6s infinite linear;
top:18%;background:repeating-radial-gradient(black, black 5px, #1C1C1C 6px, #1C1C1C 7px);
cursor: pointer;
left: 12%;z-index: 1;box-shadow:0px 0px 0px 1px #fff,0px 0px 0px 0px #880000;}
@keyframes rotating { to { transform: rotate(360deg); } }
.overlay {
content: '';
left: 50%;
top: 50%; transform: translate(-50%, -50%);
position: absolute;
width: 238px;
height: 238px;
background: linear-gradient(45deg, transparent, 40%, rgba(255,255,255,0.25), 60%, transparent);
border-radius: 50%;
}
.inner {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 100px;
height: 100px;
box-shadow:0px 0px 0px 1px #eee,0px 0px 0px 2px #444;
background:#880000 url('') no-repeat center / cover;
border-radius: 50%;
}
.inner::before {
content: '';
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 15px;
height: 15px;
background: #ccc;
border-radius: 50%;
}
#cz {position: absolute;
top:6%; left:45%;z-index: 2;
width: 150px;background: url('https://pic1.imgdb.cn/item/6688e0dad9c307b7e9a7a3e1.png')no-repeat center/85%;
height: 300px;
cursor: pointer;
}
.pink { transform:rotate(5deg);transform-origin: 100% 0%;}
.purple {transform-origin: 80% 0%;margin: -4px -18px;transform:rotate(-9deg);}
#fullscreen {border-radius: 4px;position: absolute;background:#0000 ;
color:#fff;box-shadow:0px 0px 0px 1px #fff;z-index: 20;
padding: 4px 10px;
font-size: 12px;
border: none;
cursor: pointer;margin: 8px 5px;left: 90%;top: 3%;
}
</style>
<divid="bj">
<div class='intro'></div>
<span id="fullscreen" title="屏展模式">全屏欣赏</span>
<div class="lyrics">
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
<div id="bfq">
<div id="cz"class="pink"></div>
<div id="cp"><div class="inner"></div><div class="overlay"></div></div>
</div>
<canvas id="sparkCanvas" > </canvas>
</div>
<audio id="audio" src="https://s2.ananas.chaoxing.com/sv-w7/audio/48/b7/73/8fab66981800475f5df16d8ed6da2dcf/audio.mp3" autoplay loop></audio>
<script>
// 鼠标跟随彩色火花效果
const canvas = document.getElementById('sparkCanvas');
const ctx = canvas.getContext('2d');
let mouseX = 0;
let mouseY = 0;
const sparks = [];
const particleTypes = [
{ color: 'rgba(255, 100, 100, 0.8)', sizeRange: }, // 红色系,尺寸范围增大
{ color: 'rgba(100, 255, 100, 0.8)', sizeRange: }, // 绿色系,尺寸范围增大
{ color: 'rgba(100, 100, 255, 0.8)', sizeRange: }, // 蓝色系,尺寸范围增大
{ color: 'rgba(255, 255, 100, 0.8)', sizeRange: }, // 黄色系,尺寸范围增大
{ color: 'rgba(255, 100, 255, 0.8)', sizeRange: }, // 粉色系,尺寸范围增大
{ color: 'rgba(100, 255, 255, 0.8)', sizeRange: }// 青色系,尺寸范围增大
];
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 粒子效果增强
document.addEventListener('mousemove', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
// 鼠标移动速度越快,产生的火花越多
const speed = calculateMouseSpeed(event);
// 根据移动速度创建不同数量的火花,数量增多
const sparkCount = Math.min(Math.floor(speed * 5), 5);
for (let i = 0; i < sparkCount; i++) {
createSpark();
}
});
// 鼠标点击时产生更多火花
document.addEventListener('click', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
for (let i = 0; i < 50; i++) {
createSpark(true);
}
});
// 计算鼠标移动速度
let lastX = 0, lastY = 0, lastTime = 0;
function calculateMouseSpeed(event) {
const now = Date.now();
const timeDiff = (now - lastTime) / 1000; // 转换为秒
lastTime = now;
if (timeDiff === 0) return 0;
const dx = event.clientX - lastX;
const dy = event.clientY - lastY;
const distance = Math.sqrt(dx * dx + dy * dy);
lastX = event.clientX;
lastY = event.clientY;
return distance / timeDiff;
}
// 创建火花函数
function createSpark(isClick = false) {
// 随机选择粒子类型
const type = particleTypes;
// 点击时产生的火花更大更亮
const sizeMultiplier = isClick ? 2 : 1.5;
const speedMultiplier = isClick ? 2 : 1.5;
const angle = Math.random() * Math.PI * 2;
const speed = (Math.random() * 4 + 4) * speedMultiplier; // 速度增大
const spark = {
x: mouseX,
y: mouseY,
radius: Math.random() * type.sizeRange + type.sizeRange * sizeMultiplier,
color: type.color,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: Math.random() * 60 + 40, // 火花生命周期延长
decay: Math.random() * 0.03 + 0.005, // 衰减率降低
gravity: isClick ? 0.08 : 0.04, // 重力增大
brightness: 2000 // 亮度
};
sparks.push(spark);
}
// 主更新函数
function update() {
// 只清除部分区域,保留火花尾迹,改为透明清除
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let i = sparks.length - 1; i >= 0; i--) {
const spark = sparks;
// 更新位置
spark.x += spark.vx;
spark.y += spark.vy;
// 应用重力
spark.vy += spark.gravity;
// 应用衰减
spark.vx *= 0.98;
spark.vy *= 0.98;
// 降低亮度
spark.brightness -= spark.decay;
spark.life--;
if (spark.life <= 0 || spark.brightness <= 0) {
sparks.splice(i, 1);
} else {
// 绘制火花
ctx.beginPath();
// 创建径向渐变增强真实感
const gradient = ctx.createRadialGradient(
spark.x, spark.y, 0,
spark.x, spark.y, spark.radius
);
// 提取RGBA值
const rgba = spark.color.match(/\d+/g);
const r = rgba;
const g = rgba;
const b = rgba;
const a = rgba || 1;
// 设置渐变颜色
gradient.addColorStop(0, `rgba(${r}, ${g}, ${b}, ${spark.brightness})`);
gradient.addColorStop(1, `rgba(${r}, ${g}, ${b}, 0)`);
ctx.fillStyle = gradient;
ctx.arc(spark.x, spark.y, spark.radius, 0, Math.PI * 2);
ctx.fill();
}
}
requestAnimationFrame(update);
}
update();
// 窗口大小调整时重设画布尺寸
window.addEventListener('resize', function() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
bgCanvas.width = window.innerWidth;
bgCanvas.height = window.innerHeight;
});
</script>
<script>
cp.onclick = cz.onclick = () => audio.paused ? (audio.play(), cz.classList.remove('purple'),intro.style.animationPlayState = 'running',cp.style.animationPlayState = 'running') : (audio.pause(), cz.classList.add('purple'),intro.style.animationPlayState = 'paused',cp.style.animationPlayState = 'paused');
const intro= document.querySelector('.intro');
let fs = true;
fullscreen.onclick = () => {
if (fs) {
fullscreen.innerText = '退出全屏';
bj.requestFullscreen();
} else {
fullscreen.innerText = '全屏欣赏';
document.exitFullscreen();
}
fs = !fs;
};
</script>
<script>
// 歌词解析ksc歌词或lrc歌词
const lrc = `karaoke.add('00:00.010', '00:02.508', '人间疾苦', '625,625,625,625');
karaoke.add('00:03.010', '00:05.276', '词曲:马健涛', '378,378,378,378,378,378');
karaoke.add('00:05.780', '00:07.436', '编曲:马健涛', '276,276,276,276,276,276');
karaoke.add('00:07.940', '00:09.638', '混音:马健涛', '283,283,283,283,283,283');
karaoke.add('00:10.140', '00:12.108', '母带:马健涛', '328,328,328,328,328,328');
karaoke.add('00:12.610', '00:15.640', '出品:亚伦影音工作室', '303,303,303,303,303,303,303,303,303,303');
karaoke.add('00:16.140', '00:18.505', '我尝尽了人间的折磨', '585,285,285,285,285,285,285,285,85');
karaoke.add('00:19.210', '00:22.222', '我受够了不停的奔波', '368,368,368,368,368,368,368,368,68');
karaoke.add('00:23.030', '00:25.808', '我迷茫在他乡的角落', '576,376,376,376,376,176,176,176,176');
karaoke.add('00:26.910', '00:30.803', '败给了这世界的浑浊', '477,477,477,477,477,477,477,477,77');
karaoke.add('00:31.710', '00:34.061', '流浪在地球的角落', '441,341,341,341,272,349,243,323');
karaoke.add('00:34.940', '00:38.036', '除了露宿就是漂泊', '387,387,387,387,387,387,387,387');
karaoke.add('00:38.540', '00:42.164', '微风它轻轻的吹过', '453,453,453,453,453,453,453,453');
karaoke.add('00:42.670', '00:46.374', '大雨作伴我的寂寞', '463,463,463,463,463,463,463,463');
karaoke.add('00:46.880', '00:49.664', '错怪了爱我的人啊', '348,348,348,348,348,348,348,348');
karaoke.add('00:50.170', '00:53.466', '我没资格让你留下', '412,412,412,412,412,412,412,412');
karaoke.add('00:53.970', '00:57.205', '柴米油盐酸甜苦辣', '671,523,510,436,205,248,56,168,418');
karaoke.add('00:57.640', '01:01.328', '也许我该认了命吧', '461,461,461,461,461,461,461,461');
karaoke.add('01:01.830', '01:04.158', '我落魄的不能再落魄', '292,292,292,292,292,292,292,192,92');
karaoke.add('01:04.960', '01:07.988', '我失落的不能再失落', '392,392,392,392,392,392,392,192,92');
karaoke.add('01:08.990', '01:12.087', '我的伤口愈合了又破', '418,784,470,757,392,67,44,75,90');
karaoke.add('01:12.590', '01:15.175', '我受够了憋屈的生活', '340,471,444,110,110,310,310,310,180');
karaoke.add('01:16.530', '01:19.048', '我尝尽了人间的折磨', '-444,888,784,104,523,444,18,118,83');
karaoke.add('01:20.150', '01:23.300', '我受够了不停的奔波', '999,827,157,372,189,184,162,188,72');
karaoke.add('01:24.000', '01:26.860', '我迷茫在他乡的角落', '378,26,810,496,-366,601,497,130,288');
karaoke.add('01:27.910', '01:31.550', '败给了这世界的浑浊', '680,580,340,340,340,340,340,340,340');
karaoke.add('02:02.970', '02:05.534', '错怪了爱我的人啊', '358,358,358,358,358,358,358,58');
karaoke.add('02:06.340', '02:09.200', '我没资格让你留下', '395,395,395,395,395,395,395,95');
karaoke.add('02:10.000', '02:12.072', '柴米油盐酸甜苦辣', '319,319,319,319,319,319,119,39');
karaoke.add('02:13.070', '02:16.624', '也许我该认了命吧', '921,921,821,321,221,221,21,121');
karaoke.add('02:17.730', '02:20.517', '我落魄的不能再落魄', '343,343,343,343,343,343,343,343,43');
karaoke.add('02:21.320', '02:24.170', '我失落的不能再失落', '350,350,350,350,350,350,350,350,50');
karaoke.add('02:24.970', '02:27.821', '我的伤口愈合了又破', '352,352,352,352,352,352,352,327,60');
karaoke.add('02:28.640', '02:32.366', '我受够了憋屈的生活', '414,414,414,414,414,414,414,414,414');
karaoke.add('02:32.870', '02:35.231', '我尝尽了人间的折磨', '292,292,292,292,292,292,292,192,125');
karaoke.add('02:36.40', '02:39.089', '我受够了不停的奔波', '401,401,401,401,401,401,401,201,41');
karaoke.add('02:40.110', '02:43.162', '我迷茫在他乡的角落', '386,386,386,386,386,386,386,302,48');
karaoke.add('02:44.090', '02:47.825', '败给了这世界的浑浊', '415,415,415,415,415,415,415,415,415');
karaoke.add('02:48.330', '02:50.299', '我落魄的不能再落魄', '241,241,241,241,241,241,241,241,41');
karaoke.add('02:51.70', '02:54.464', '我失落的不能再失落', '456,456,456,456,456,456,456,156,46');
karaoke.add('02:55.610', '02:58.280', '我的伤口愈合了又破', '330,330,330,330,330,330,330,330,30');
karaoke.add('02:59.080', '03:02.752', '我受够了憋屈的生活', '408,408,408,408,408,408,408,408,408');
karaoke.add('03:03.260', '03:06.320', '我尝尽了人间的折磨', '340,340,340,340,340,340,340,340,340');
karaoke.add('03:06.820', '03:09.805', '我受够了不停的奔波', '365,365,365,365,365,365,365,365,65');
karaoke.add('03:10.610', '03:13.640', '我迷茫在他乡的角落', '370,370,370,370,370,370,370,370,70');
karaoke.add('03:14.440', '03:18.786', '败给了这世界的浑浊', '1304,864,304,304,304,304,604,304,54');
`;
const audio = document.getElementById('audio');
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`;
}
// 监听更新歌词
audio.addEventListener('timeupdate', () => {
const currentTimeMs = audio.currentTime * 1000;
const index = getCurrentLyricIndex(lyrics, currentTimeMs);
if (index !== currentIndex) {
updateLyricDisplay(index);
}
updateLyricMask(currentTimeMs);
});
updateLyricDisplay(0);
</script>
这帖子很奇妙,鼠标只要移动就带来撒开的粒子效果,不管鼠标是否在帖子范围里。
这些鼠标移动的彩色粒子真漂亮,变色背景也很漂亮{:4_199:} ksc歌词真好,可以逐字对应呢。
欣赏亚伦老师好帖{:4_199:} 欣赏老师的新帖,精彩,点赞!
效果漂亮,有空学习下{:4_178:} 点赞、欣赏! ksc歌词太难找了,所以只能欣赏,学不了。
页:
[1]