我的祝福你聽見了嗎
<style>#bj {
position: relative;
width: 1280px;
height: 720px;
margin-left: -300px;
margin-top: 10px;
overflow: hidden;z-index:12345;
background: ;
}
.intro {margin: 0px0px;z-index:2;
width: 100%;
height:100%;
position: absolute;
background:url('https://picasa.eu.org/i/2026/06/05/md468y.jpg'),repeating-linear-gradient(57deg, rgba(250, 4, 10, 0.55) 0%,rgba(73, 185, 41, 0.45) 28%,rgba(4, 38, 245, 0.34) 50%,rgba(73, 185, 41, 0.45) 72%,rgba(250, 4, 10, 0.55) 100%);
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);
}
}
#balloonCanvas{ z-index:3;
pointer-events: none;
position: absolute;overflow: hidden;
left:0;top: 0px;
}
.lyrics{margin: 0;z-index: 20;
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;
}
</style>
<divid="bj">
<div class='intro'></div>
<canvas id="balloonCanvas" ></canvas>
<div class="lyrics" >
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
</div>
<audio id="audio" src="https://pan.suyanw.cn/view.php/7d56d6e2077e9f4c51f663d5fa1db65a.mp3" autoplay loop></audio>
<script>
const balloonCanvas = document.getElementById('balloonCanvas');
const balloonCtx = balloonCanvas.getContext('2d');
balloonCtx.imageSmoothingEnabled = true;
let mouseX = 0;
let mouseY = 0;
let isMouseMoving = false;
const balloons = [];
const balloonColors = [
'red', 'blue', 'green', 'yellow', 'purple', 'orange', 'pink'
];
const balloonSizeRange = ;
balloonCanvas.width = window.innerWidth;
balloonCanvas.height = window.innerHeight;
document.addEventListener('mousemove', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
isMouseMoving = true;
const speed = calculateMouseSpeed(event);
const balloonCount = Math.min(Math.floor(speed * 1), 2);
for (let i = 0; i < balloonCount; i++) {
createBalloon();
}
setTimeout(() => {
isMouseMoving = false;
}, 200);
});
document.addEventListener('click', function(event) {
mouseX = event.clientX;
mouseY = event.clientY;
for (let i = 0; i < 3; i++) {
createBalloon(true);
}
});
const images = document.getElementsByTagName('img');
for (let i = 0; i < images.length; i++) {
images.addEventListener('click', function() {
balloons.forEach(balloon => {
const angle = Math.random() * Math.PI * 2;
const speed = (Math.random() * 5 + 3);
balloon.vx = Math.cos(angle) * speed;
balloon.vy = Math.sin(angle) * speed;
});
});
}
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 createBalloon(isClick = false) {
const color = balloonColors;
const sizeMultiplier = isClick ? 1.2 : 1;
const speedMultiplier = isClick ? 1.2 : 1;
const angle = Math.random() * Math.PI * 2;
const speed = (Math.random() * 2 + 1) * speedMultiplier;
const balloon = {
x: mouseX,
y: mouseY,
radiusX: Math.random() * balloonSizeRange + balloonSizeRange * sizeMultiplier,
radiusY: (Math.random() * 0.5 + 1) * (Math.random() * balloonSizeRange + balloonSizeRange * sizeMultiplier), // 闀垮渾褰㈢姸
color: color,
vx: Math.cos(angle) * speed,
vy: Math.sin(angle) * speed,
life: Math.random() * 80 + 50, decay: Math.random() * 0.02 + 0.01,
brightness: 500
};
balloons.push(balloon);
}
function createFallingBalloon() {
const color = balloonColors;
const radiusX = Math.random() * balloonSizeRange + balloonSizeRange;
const radiusY = (Math.random() * 0.5 + 1) * (Math.random() * balloonSizeRange + balloonSizeRange); // 闀垮渾褰㈢姸
const balloon = {
x: Math.random() * balloonCanvas.width,
y: 0,
radiusX: radiusX,
radiusY: radiusY,
color: color,
vx: (Math.random() - 0.5) * 2,
vy: Math.random() * 2 + 1,
life: Math.random() * 80 + 50,
decay: Math.random() * 0.02 + 0.01,
brightness: 1
};
balloons.push(balloon);
}
for (let i = 0; i < 3; i++) {
createFallingBalloon();
}
function update() {
balloonCtx.clearRect(0, 0, balloonCanvas.width, balloonCanvas.height);
if (!isMouseMoving) {
balloons.forEach(balloon => {
const randomFactor = Math.random() * 0.1 + 1;
balloon.vx *= 1.05 * randomFactor;
balloon.vy *= 1.05 * randomFactor;
});
}
for (let i = balloons.length - 1; i >= 0; i--) {
const balloon = balloons;
balloon.x += balloon.vx;
balloon.y += balloon.vy;
balloon.vx *= 0.98;
balloon.vy *= 0.98;
balloon.brightness -= balloon.decay;
balloon.life--;
if (balloon.x - balloon.radiusX < 0) {
balloon.x = balloon.radiusX;
balloon.vx = -balloon.vx * 0.8;
}
if (balloon.x + balloon.radiusX > balloonCanvas.width) {
balloon.x = balloonCanvas.width - balloon.radiusX;
balloon.vx = -balloon.vx * 0.8;
}
if (balloon.y - balloon.radiusY < 0) {
balloon.y = balloon.radiusY;
balloon.vy = -balloon.vy * 0.8;
}
if (balloon.y + balloon.radiusY > balloonCanvas.height) {
balloon.y = balloonCanvas.height - balloon.radiusY;
balloon.vy = -balloon.vy * 0.8;
}
if (balloon.life <= 0 || balloon.brightness <= 0) {
balloons.splice(i, 1);
} else {
drawBalloon(balloon);
}
}
requestAnimationFrame(update);
}
function drawBalloon(balloon) {
balloonCtx.shadowColor = 'rgba(0, 0, 0, 0.3)';
balloonCtx.shadowBlur = 5;
balloonCtx.shadowOffsetX = 2;
balloonCtx.shadowOffsetY = 2;
const gradient = balloonCtx.createRadialGradient(
balloon.x, balloon.y, 0,
balloon.x, balloon.y, Math.max(balloon.radiusX, balloon.radiusY)
);
gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
gradient.addColorStop(0.2, 'rgba(0, 0, 0, 0)');
gradient.addColorStop(1, balloon.color);
balloonCtx.beginPath();
balloonCtx.ellipse(balloon.x, balloon.y, balloon.radiusX, balloon.radiusY, 0, 0, Math.PI * 2);
balloonCtx.fillStyle = gradient;
balloonCtx.fill();
balloonCtx.beginPath();
balloonCtx.ellipse(balloon.x, balloon.y, balloon.radiusX, balloon.radiusY, 0, 0, Math.PI * 2);
balloonCtx.strokeStyle = 'rgba(255, 255, 255, 0.4)';
balloonCtx.lineWidth = 1;
balloonCtx.stroke();
balloonCtx.shadowColor = 'rgba(0, 0, 0, 0)';
}
update();
window.addEventListener('resize', function() {
balloonCanvas.width = window.innerWidth;
balloonCanvas.height = window.innerHeight;
});
</script>
<script>
// 歌词解析ksc歌词或lrc歌词
const lrc = `
作詞 : 郝立軒
作曲 : 王立冬
我的祝福你聽見了嗎
我的祝福你聽見了嗎
祝福你聽見了嗎
我的思念你感覺到了嗎
思念你感覺到了嗎
有一種情緣不用來訴說
提起來總是難以放下
有一種牽掛
不用你來叮嚀
說起來總是讓人淌淚花
想起你的祝福
就像彩信捎來的情話
想起你的問候
就像彩鈐深情的表達
你的身體還好嗎
像你說的那樣嗎
你的生活幸福嗎
像我想的那樣嗎
也許你現在過得不錯
我對你還是放心不下
有一種愛戀
不用你來報答
守望著这一生
青絲變白發
我的思念
思念你感覺到了嗎
我的祝福
祝福你聽見了嗎
我的思念
思念你感覺到了嗎
我的祝福
祝福你聽見了嗎
祝福你聽見了嗎
`;
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>
<script>
bj.onclick = () => audio.paused ? (audio.play(), intro.style.animationPlayState = 'running') : (audio.pause(),intro.style.animationPlayState = 'paused');
const intro= document.querySelector('.intro');
</script>
页:
[1]