爱的力量 - Céline Dion_
<meta charset="utf-8"><style>
@import url("https://fonts.googleapis.com/css2?family=Ma+Shan+Zheng&display=swap");
#bj {
position: relative;
width: 1280px;
height: 710px;
margin: 0 -130px;
overflow: hidden;
z-index: 1;
background:#000 url(https://bbs.cnzv.cc/up/upload/pic/12/20260323-6098847ff487dceb9fdf17a1e85279aa.jpg) no-repeat center/cover;
border-radius: 2px;
box-shadow: 0px 0px 4px 0px #fff;
font-family: "Ma Shan Zheng","","SimHei", "Arial", "sans-serif"
}
.intro {margin: 0px0px;z-index:1;
width: 100%;
height:100%;
position: absolute;
background: url(https://bbs.cnzv.cc/up/upload/pic/12/20260323-6098847ff487dceb9fdf17a1e85279aa.jpg), linear-gradient(45deg, #e56420, #c555aa, #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);
}
}
.song-title {z-index: 15;
font-size: 40px;position: absolute;
right: 60px;
top: 120px;
font-weight: 300;
color: #fff000;text-align: center;
writing-mode: vertical-rl;
margin-bottom: 0px;
letter-spacing: 5px;
animation: hue-rotate 0.5s linear infinite;
}
#lrc {
position: absolute;
left:40%;
top: 40%;
transform: translate(-50%, -50%);
width: 900px;
height: 500px;
z-index: 8;
filter:drop-shadow(#fff 1px 0 0)drop-shadow(#fff 0 1px 0)drop-shadow(#fff -1px 0 0) drop-shadow(#fff 0 -1px0);
pointer-events: none;
}
.lrc-char {
position: absolute;
font-size: 3em;
color: #ff0000;
animation: hue-rotate 3s linear infinite;
white-space: nowrap;
left: 0;
top: 0;
transform: translate(-50%, -50%);
will-change: transform;
}
.lrc-char.spinning {
animation: spinColorContinuous 1s linear infinite;
}
.lrc-char.spinning.paused-animation {
animation-play-state: paused;
}
@keyframes spinColorContinuous {
0% {
transform: translate(-50%, -50%) rotate(0deg) scale(0.2);
filter: brightness(250%) hue-rotate(0deg);
}
50% {
transform: translate(-50%, -50%) rotate(180deg) scale(2);
filter: brightness(250%) contrast(250%)hue-rotate(180deg);
}
100% {
transform: translate(-50%, -50%) rotate(360deg) scale(1);
filter: brightness(250%) hue-rotate(360deg);
}
}
.lrc-space {
position: absolute;
color: transparent;
text-shadow: none;
left: 0;
top: 0;
transform: translate(-50%, -50%);
pointer-events: none;
}
#player {
position:absolute;top: 75%;z-index: 99;
left: 44%;transform: translate(-50%, -50%);
width: 150px;
height: 150px;
display: grid;text-align: center;
place-items: center;animation: rotateHalo 3s linear infinite,hue-rotate 1s linear infinite;
}
#rect {position: absolute;
display: grid;
place-items: center;
width:35%;
height: 35%;
clip-path: polygon(60% 0, 100% 0, 50% 50%, 40% 100%, 0 100%, 50% 50%);
}
#rect:nth-of-type(1) { background:#5500ff;transform: rotate(0deg);
}
#rect:nth-of-type(2) { background:#ff0000;transform: rotate(45deg);
}
#rect:nth-of-type(3) { background:#00aa00;transform: rotate(90deg);
}
#rect:nth-of-type(4) { background:#fff000;transform: rotate(135deg);
}
#player.paused{
animation-play-state: paused;
}
@keyframes rotateHalo {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.progress-container {
position: absolute;
bottom: 40px;
left: 50%;
transform: translateX(-50%);
width: 40%;
z-index: 20;
background:#bbb;
height: 6px;
border-radius: 2px;
cursor: pointer;
border: 0px solid rgba(255, 215, 0, 0.3);
}
.progress-bar {
height: 100%;
width: 0%;
background: #800;
border-radius: 2px;
transition: width 0.1s linear;
position: relative;
box-shadow: 0 0 0px rgba(255, 215, 0, 0.5);
}
.progress-bar::after {
display: none;
}
.time-display {
display: flex;
justify-content: space-between;
margin-top: -40px;
font-size: 20px;
color: #bbb;
}
.lyric-preview, canvas {
display: none;
}
</style>
<div id="bj">
<div class='intro'></div>
<div class="song-title"></div>
<div id="lrc"></div>
<div class="progress-container" id="progressContainer">
<div class="progress-bar" id="progressBar"></div>
<div class="time-display">
<span id="currentTime">00:00</span>
<span id="duration">00:00</span>
</div>
</div>
<div id="player" title="/">
<pid="rect"></p>
<pid="rect"></p>
<pid="rect"></p>
<pid="rect"></p>
</div>
<audio id="audio" loop></audio>
</div>
<script>
(function() {
// ===================== 歌曲数据 =====================
const songs = [
{
title: "爱的力量 - Celine Dion",
audioUrl: "https://upfile.mp3.wf/view.php/f70c945c047f5f91129210b8dfcf1c24.mp3",
lyrics: `
爱的力量 - Celine Dion
LRC编辑:醉美水芙蓉
The whispers in the morning
清晨里的喃喃细语
Of lovers sleeping tight
情侣们正在熟睡
Are rolling like thunder now
那轻语如雷般回荡
As I look in your eyes
当我看着你的眼睛
I hold on to your body
我紧紧拥抱着你的身体
And feel each move you make
感受你做的每一个动作
Your voice is warm and tender
你的声音温暖柔和
A love that I could not forsake
这是我不能舍弃的爱
'Coz I am your lady
因为我是你的女人
And you are my man
而你是我的男人
Whenever you reach for me
无论何时你来到我身边
I'll do all that I can
我将为你做我所能做的一切
Lost is how I'm feeling lying in your arms
躺在你的怀里我已迷失自我
When the world outside's too
外面的世界有太多诱惑
Much to take
That all ends when I'm with you
当我与你在一起的时候这些都不复存在了
Even though there may be times
即使有些时候
It seems I'm far away
似乎我在远离
Never wonder where I am
但是不要好奇我在哪里
'Coz I am always by your side
因为我一直站在你身后支持
'Coz I am your lady
因为我是你的女人
And you are my man
而你是我的男人
Whenever you reach for me
无论何时你来到我身边
I'll do all that I can
我将为你做我所能做的一切
We're heading for something
我们正在向目标前进
Somewhere I've never been
那是我从未实现的目标
Sometimes I am frightened
有时候我觉得很恐慌
But I'm ready to learn
但是我已经准备好去学习
Of the power of love
爱的力量
The sound of your heart beating
你心脏跳动的声音
Made it clear suddenly
突然变得清晰起来
The feeling that I can't go on
感觉我快要坚持不下去了
Is light years away
那感觉像是数光年外那般遥远
'Coz I am your lady
因为我是你的女人
And you are my man
而你是我的男人
Whenever you reach for me
无论何时你来到我身边
I'll do all that I can
我将为你做我所能做的一切
We're heading for something
我们正在向目标前进
Somewhere I've never been
那是我从未实现的目标
Sometimes I am frightened
有时候我觉得很恐慌
But I'm ready to learn
但是我已经准备好去学习
Of the power of love
爱的力量
The power of love
爱的力量
The power of love
爱的力量
Sometimes I am frightened
有时候我觉得很恐慌
But I'm ready to learn
但是我已经准备好去学习
The power of love
爱的力量
The power of love
爱的力量
谢谢欣赏!
`
}
];
function lrcTime(ar) {
let tmpAr = [];
for(let j = 0; j < ar.length - 1; j ++) {
if(j !== ar.length - 1)
tmpAr = parseFloat((ar - ar).toFixed(1));
}
let averAdd = 0;
let aver = parseInt(tmpAr.reduce((a,b) => a + b, 0) / (tmpAr.length - 1)) + averAdd;
tmpAr.push(aver);
tmpAr.forEach((item, key) => {
ar = item > aver ? aver : item;
});
return ar;
}
function getLrcAr(text) {
let lrcAr = [];
let calcRule = ;
let offset = 0;
for(let x of text.split('\n')) {
let ar = [];
let re = /\d+[\.:]\d+([\.:]\d+)?/g;
let geci = x.replace(re,'');
if(geci) {
geci = geci.replace(/[\[\]\'\"\t,\s]?/g,'');
let time = x.match(re);
if(time != null) {
for(let y of time) {
let tmp = y.match(/\d+/g);
let sec = 0;
for(let z in tmp)
sec += tmp * calcRule;
ar = ;
lrcAr.push(ar);
}
}
}
}
lrcAr.sort((a,b)=> a - b);
lrcAr = lrcAr.map(item => , item, 0]);
return lrcTime(lrcAr);
}
const currentSong = songs;
const lrcArray = getLrcAr(currentSong.lyrics);
const state = {
currentSongIndex: 0,
lyrics: lrcArray,
currentLyricIndex: 0,
isPlaying: false,
volume: 0.8,
isMuted: false,
videoMode: 3,
circularChars: [],
circularActiveIndex: -1,
currentLyricStart: 0,
currentLyricDuration: 5,
isDragging: false,
animationId: null,
};
const elements = {
audio: document.getElementById('audio'),
lrc: document.getElementById('lrc'),
progressContainer: document.getElementById('progressContainer'),
progressBar: document.getElementById('progressBar'),
currentTime: document.getElementById('currentTime'),
duration: document.getElementById('duration'),
player: document.getElementById('player'),
songTitle: document.querySelector('.song-title'),
};
const playerVideo = elements.player.querySelector('video');
function renderCircularLyric(text) {
if (!text) return;
elements.lrc.innerHTML = '';
const chars = text.split('');
const total = chars.length;
if (total === 0) return;
const centerX = 200;
const centerY = 270;
const radius = 140;
const step = total === 1 ? 0 : (2 * Math.PI) / total;
const newChars = [];
for (let i = 0; i < total; i++) {
const ch = chars;
const angle = i * step;
const x = centerX + radius * Math.cos(angle);
const y = centerY + radius * Math.sin(angle);
const span = document.createElement('span');
if (ch.trim() === '') {
span.className = 'lrc-space';
span.innerHTML = ' ';
} else {
span.className = 'lrc-char';
span.textContent = ch;
}
span.style.left = x + 'px';
span.style.top = y + 'px';
span.style.transform = 'translate(-50%, -50%)';
elements.lrc.appendChild(span);
newChars.push(span);
}
state.circularChars = newChars;
state.circularActiveIndex = -1;
}
function updateCircularActivation(now) {
const chars = state.circularChars;
if (!chars || chars.length === 0) return;
const start = state.currentLyricStart;
const duration = state.currentLyricDuration;
let progress = (now - start) / duration;
if (progress < 0) progress = 0;
if (progress > 1) progress = 1;
let targetIndex;
if (progress >= 1) {
targetIndex = chars.length - 1;
} else {
targetIndex = Math.floor(progress * chars.length);
}
if (targetIndex < 0) targetIndex = 0;
if (targetIndex >= chars.length) targetIndex = chars.length - 1;
if (targetIndex !== state.circularActiveIndex) {
if (state.circularActiveIndex !== -1) {
chars?.classList.remove('spinning', 'paused-animation');
}
chars?.classList.add('spinning');
if (!state.isPlaying) {
chars?.classList.add('paused-animation');
}
state.circularActiveIndex = targetIndex;
}
}
function animationLoop() {
if (!state.isPlaying) return;
const currentTime = elements.audio.currentTime;
const lyrics = state.lyrics;
for (let i = 0; i < lyrics.length; i++) {
const currentLyricTime = lyrics;
const nextLyricTime = i < lyrics.length - 1 ? lyrics : Infinity;
if (currentTime >= currentLyricTime && currentTime < nextLyricTime) {
if (state.currentLyricIndex !== i) {
state.currentLyricIndex = i;
const text = lyrics;
renderCircularLyric(text);
state.currentLyricStart = currentLyricTime;
state.currentLyricDuration = lyrics;
}
break;
}
}
updateCircularActivation(currentTime);
const duration = elements.audio.duration;
if (duration) {
const progressPercent = (currentTime / duration) * 100;
elements.progressBar.style.width = `${progressPercent}%`;
elements.currentTime.textContent = formatTime(currentTime);
elements.duration.textContent = formatTime(duration);
}
state.animationId = requestAnimationFrame(animationLoop);
}
function formatTime(seconds) {
const mins = Math.floor(seconds / 60);
const secs = Math.floor(seconds % 60);
return `${mins}:${secs < 10 ? '0' : ''}${secs}`;
}
function togglePlayback() {
if (elements.audio.paused) {
elements.audio.play().catch(e => console.log(e));
} else {
elements.audio.pause();
}
updatePlayerState();
}
function updatePlayerState() {
if (elements.audio.paused) {
state.isPlaying = false;
if (playerVideo) playerVideo.pause();
elements.player.classList.add('paused');
document.querySelectorAll('#lrc .lrc-char.spinning').forEach(char => {
char.classList.add('paused-animation');
});
if (state.animationId) {
cancelAnimationFrame(state.animationId);
state.animationId = null;
}
} else {
state.isPlaying = true;
if (playerVideo) playerVideo.play().catch(e => {});
elements.player.classList.remove('paused');
document.querySelectorAll('#lrc .lrc-char.spinning').forEach(char => {
char.classList.remove('paused-animation');
});
if (!state.animationId) {
state.animationId = requestAnimationFrame(animationLoop);
}
}
}
function bindEvents() {
elements.player.addEventListener('click', togglePlayback);
elements.progressContainer.addEventListener('click', (e) => {
const rect = elements.progressContainer.getBoundingClientRect();
const percent = (e.clientX - rect.left) / rect.width;
elements.audio.currentTime = percent * elements.audio.duration;
});
elements.progressContainer.addEventListener('mousedown', (e) => {
state.isDragging = true;
const rect = elements.progressContainer.getBoundingClientRect();
const percent = (e.clientX - rect.left) / rect.width;
elements.audio.currentTime = percent * elements.audio.duration;
});
document.addEventListener('mousemove', (e) => {
if (state.isDragging) {
const rect = elements.progressContainer.getBoundingClientRect();
const percent = Math.max(0, Math.min(1, (e.clientX - rect.left) / rect.width));
elements.audio.currentTime = percent * elements.audio.duration;
}
});
document.addEventListener('mouseup', () => { state.isDragging = false; });
elements.audio.addEventListener('play', updatePlayerState);
elements.audio.addEventListener('pause', updatePlayerState);
elements.audio.addEventListener('seeked', () => {
if (state.lyrics.length) {
const now = elements.audio.currentTime;
for (let i = 0; i < state.lyrics.length; i++) {
const currentTime = state.lyrics;
const nextTime = i < state.lyrics.length-1 ? state.lyrics : Infinity;
if (now >= currentTime && now < nextTime) {
state.currentLyricIndex = i;
renderCircularLyric(state.lyrics);
state.currentLyricStart = currentTime;
state.currentLyricDuration = state.lyrics;
updateCircularActivation(now);
break;
}
}
}
});
document.addEventListener('keydown', (e) => {
if (e.code === 'Space') { e.preventDefault(); togglePlayback(); }
else if (e.code === 'ArrowLeft') elements.audio.currentTime -= 5;
else if (e.code === 'ArrowRight') elements.audio.currentTime += 5;
});
}
functioninitVideos() {}
async function init() {
elements.audio.src = currentSong.audioUrl;
elements.audio.loop = true;
elements.songTitle.textContent = currentSong.title;
initVideos();
state.videoMode = 3;
if (state.lyrics.length > 0) {
renderCircularLyric(state.lyrics);
state.currentLyricStart = state.lyrics;
state.currentLyricDuration = state.lyrics;
}
bindEvents();
elements.audio.play().then(() => {
updatePlayerState();
}).catch(() => {
const hint = document.createElement('div');
hint.textContent = '点击任意位置开始播放';
hint.style.position = 'absolute';
hint.style.top = '50%';
hint.style.left = '50%';
hint.style.transform = 'translate(-50%, -50%)';
hint.style.background = 'rgba(139, 0, 0, 0.8)';
hint.style.color = '#ffd700';
hint.style.padding = '15px 30px';
hint.style.borderRadius = '10px';
hint.style.zIndex = '30';
hint.style.cursor = 'pointer';
hint.style.border = '1px solid #ffd700';
document.getElementById('bj').appendChild(hint);
hint.addEventListener('click', function start() {
elements.audio.play().then(() => {
updatePlayerState();
hint.remove();
});
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
const intro= document.querySelector('.intro');
let mState = () => audio.paused ? (intro.style.animationPlayState = 'paused') : (intro.style.animationPlayState = 'running');
audio.addEventListener('play', () => mState());
audio.addEventListener('pause', () => mState());
</script> 英文歌曲,别有味道呢 klxf 发表于 2026-3-24 17:32
英文歌曲,别有味道呢
谢谢友友欣赏! 谢谢楼主的辛苦分享 赞,顶帖思路非常新颖 不错哦喜欢 嘿嘿
页:
[1]