晚风-龙飘飘
本帖最后由 亚伦影音工作室 于 2025-10-18 12:23 编辑 <br /><br /><style>#bj {
position: relative;
width: 1286px;
height: 680px;
margin-left: -300px;
margin-top: 10px;
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) no-repeat center / cover,linear-gradient(145deg, #ff0000, #000078, #00aa00, #000090);
background-size: cover;
background-blend-mode: hard-light;
animation: hue-rotate 3s linear infinite;
}
@keyframes hue-rotate {50%{ transform:scale(1); opacity: 0.1;filter: hue-rotate(360deg)}}
.lrc {
position: absolute;
width: 500px;
height: 460px;
top: 45%;
left: 70%;
transform: translate(-50%, -50%); /* 容器整体居中 */
overflow: hidden;
text-align: center;
}
.lrc #ul {
width: 100%;
padding: 0;
list-style: none;
transition: 0.1s all ease;
margin: 0;
display: flex;
flex-direction: column;
align-items: center;
}
.lrc #ul li {filter:drop-shadow(#fff 1px 0px 1px);
color: #000;
font: 300 25px '华文新魏', sans-serif;
transition: 0.1s all ease;
list-style-type: none;
text-align: center;
padding: 0 0px;
height: 60px;
line-height:60px;
cursor: pointer;
white-space: nowrap; /* 防止歌词换行 */
}
.lrc #ul li span {
margin: 0 5px;
transform-origin: center center; /* x轴和y轴均以中心为原点 */
transition: all 0.1s cubic-bezier(0.34, 1.56, 0.64, 1); /* 缓动函数让动画更自然 */
display: inline-block; /* 确保transform-origin生效 */
}
.lrc #ul li span.active {
font: 200 28px '华文新魏', sans-serif;
color:#800000;
transform: scale(1.3)rotate(-720deg) translateY(-22%);/* 缩放效果 */
}
#bfq{
position:absolute;
width: 450px;
height:350px;overflow: hidden;
background:#0000;
transform:scale(.4);bottom: -100px;
left: -120px;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);}
#prog {position: absolute;z-index: 8;
width: 65%;
height: 2px;background:#fff;
cursor: pointer;
bottom: 46px;
left:12%;
border-radius: 1px;}
#prog-bar {
height: 100%;
background: #FF0000;
width: 0%;
}
#tmsg {position: absolute;z-index: 8;
font: 300 14px sans-serif;
color: #fff;
bottom: 42px;
right: 40px;}
#fpp{position: absolute; bottom: 42px; right: 140px;filter:invert(0%)hue-rotate(360deg);
width: 120px;cursor: pointer;background: url(https://pic1.imgdb.cn/item/68f315dcc5157e1a887fea24.png) no-repeat center / 120px 60px;
height: 60px;z-index: 8; }
#fpp img{width: 100%;
height: 100%;}
</style>
<div id="bj">
<div class='intro'></div>
<div class="lrc">
<ul id="ul"></ul>
</div>
<div id="bfq">
<div id="cz"class="pink"></div>
<div id="cp"><div class="inner"></div><div class="overlay"></div></div>
</div>
<div id="prog" title="播放进度条"><div id="prog-bar"></div></div>
<div id='fpp'><img id="testImg" src="https://pic1.imgdb.cn/item/68e8ed85c5157e1a886292b4.gif" ></div>
<div id="tmsg">00:00|00:00</div>
</div>
</div>
<audio id="audio" src="https://upfile.mp3.wf/view.php/e5aae9d425312b135aa2127d83e71a5e.mp3" loop autoplay></audio>
<script>
var lrc = `karaoke.add('00:01.430', '00:14.776', '晚风-龙飘飘', '1928,1928,1928,1928,1928,1928,1928,1280');
karaoke.add('00:15.430', '00:28.290', '词:西风', '3860,3860,3860,1280');
karaoke.add('00:30.878', '00:37.877', '夕阳下晚风凉', '1642,1306,931,869,971,1280');
karaoke.add('00:38.251', '00:43.465', '漫步走在山坡上', '761,490,405,470,860,948,1280');
karaoke.add('00:45.607', '00:49.527', '你也静静地', '1576,544,765,530,505');
karaoke.add('00:49.231', '00:52.618', '陪在我身旁', '906,315,462,424,1280');
karaoke.add('00:53.696', '00:58.207', '心底多舒畅', '561,785,889,996,1280');
karaoke.add('00:59.687', '01:07.392', '回想甜蜜的时光', '2314,466,885,905,1455,400,1280');
karaoke.add('01:07.677', '01:12.986', '我也不再黯然神伤', '750,485,435,430,486,857,586,1280');
karaoke.add('01:14.862', '01:21.813', '晚风歌出竹摇晃', '1616,803,900,881,969,965,817');
karaoke.add('01:21.522', '01:28.121', '把我吹进爱的梦乡', '768,494,1317,488,478,489,1285,1280');
karaoke.add('01:59.426', '02:06.582', '夕阳下晚风凉', '1855,1150,1046,827,998,1280');
karaoke.add('02:06.957', '02:12.120', '漫步走在山坡上', '699,454,480,450,918,882,1280');
karaoke.add('02:14.316', '02:18.115', '你也静静地', '1539,512,853,400,495');
karaoke.add('02:17.821', '02:21.338', '陪在我身旁', '965,574,508,190,1280');
karaoke.add('02:22.259', '02:26.905', '心底多舒畅', '522,939,925,980,1280');
karaoke.add('02:28.992', '02:36.035', '回想甜蜜的时光', '1658,472,934,874,1430,395,1280');
karaoke.add('02:36.335', '02:41.639', '我也不再黯然神伤', '745,471,414,819,301,735,539,1280');
karaoke.add('02:43.600', '02:50.517', '晚风歌出竹摇晃', '1720,495,955,1047,863,970,867');
karaoke.add('02:50.225', '02:55.859', '把我吹进爱的梦乡', '1234,1421,450,359,406,420,1144,200');
`;
let lrcArr = lrc.split('\n');
let result = [];
var audio = document.querySelector("#audio"),
ul = document.querySelector("#ul"),
container = document.querySelector(".lrc");
const lrcRegex = /karaoke\.add\('([\d:/.]+)',\s*'([\d:/.]+)',\s*'([^']*)'/;
for (let i = 0; i < lrcArr.length; i++) {
const line = lrcArr.trim();
if (!line) continue;
const match = line.match(lrcRegex);
if (!match) continue;
const startTimeStr = match;
const endTimeStr = match;
const lineText = match.trim();
if (!lineText) continue;
const startTime = parseTime(startTimeStr);
const endTime = parseTime(endTimeStr);
const lineDuration = endTime - startTime;
const words = lineText.split('');
const wordCount = words.length;
if (wordCount === 0) continue;
const wordDuration = lineDuration / wordCount;
const lineWords = [];
words.forEach((word, index) => {
lineWords.push({
time: startTime + index * wordDuration,
text: word
});
});
result.push(lineWords);
}
function parseTime(timeStr) {
const = timeStr.split(':');
return parseInt(minutes, 10) * 60 + parseFloat(seconds);
}
function getCurrentLineIndex() {
const currentTime = audio.currentTime;
for (let i = 0; i < result.length; i++) {
const line = result;
if (currentTime >= line.time &&
(i === result.length - 1 || currentTime < result.time)) {
return i;
}
}
return -1;
}
function createLyricElements() {
const frag = document.createDocumentFragment();
result.forEach((lineWords, lineIndex) => {
const li = document.createElement("li");
lineWords.forEach(wordObj => {
const span = document.createElement("span");
span.textContent = wordObj.text;
span.dataset.time = wordObj.time;
li.appendChild(span);
});
li.addEventListener('click', () => {
audio.currentTime = lineWords.time;
});
frag.appendChild(li);
});
ul.appendChild(frag);
}
createLyricElements();
const liHeight = 60;
const visibleLines = 1;
let prevLineIndex = -1;
function syncLyric() {
const currentLineIndex = getCurrentLineIndex();
if (currentLineIndex === -1) return;
const scrollOffset = currentLineIndex * liHeight;
ul.style.transform = `translateY(-${scrollOffset}px)`;
if (prevLineIndex!== -1 && prevLineIndex!== currentLineIndex) {
const prevLi = ul.children;
if (prevLi) {
prevLi.querySelectorAll('span.active').forEach(span => {
span.classList.remove('active');
});
}
}
const currentLi = ul.children;
const currentLine = result;
const currentTime = audio.currentTime;
currentLine.forEach((wordObj, wordIndex) => {
const span = currentLi.children;
const isActive = currentTime >= wordObj.time &&
(wordIndex === currentLine.length - 1 ||
currentTime < currentLine.time);
if (isActive) {
span.classList.add('active');
} else {
span.classList.remove('active');
}
});
prevLineIndex = currentLineIndex;
}
audio.addEventListener("timeupdate", syncLyric);
</script>
<script>
audio.addEventListener('timeupdate', () => {
tmsg.innerText = toMin(audio.currentTime) + ' | ' + toMin(audio.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;
}
prog.onclick = (e) => { audio.currentTime = audio.duration * e.offsetX / prog.offsetWidth; }
var progBar = document.getElementById('prog-bar');
audio.addEventListener('timeupdate', () => {
const percent = (audio.currentTime / audio.duration) * 100;
progBar.style.width = percent + '%';
});
fpp.onclick =cp.onclick = cz.onclick = () => audio.paused ? (audio.play(), cz.classList.remove('purple'),intro.style.animationPlayState = 'running',image.play()) : (audio.pause(), cz.classList.add('purple'),intro.style.animationPlayState = 'paused',image.stop());
cp.style.animationPlayState = audio.paused ? 'paused' : 'running';
audio.addEventListener('playing', () => cp.style.animationPlayState = 'running');
audio.addEventListener('pause', () => cp.style.animationPlayState = 'paused');
const intro= document.querySelector('.intro');
</script>
<script>
if ('getContext' in document.createElement('canvas')) {
HTMLImageElement.prototype.play = function() {
if (this.storeCanvas) {
// 移除存储的canvas
this.storeCanvas.parentElement.removeChild(this.storeCanvas);
this.storeCanvas = null;
// 透明度还原
image.style.opacity = '';
}
if (this.storeUrl) {
this.src = this.storeUrl;
}
};
HTMLImageElement.prototype.stop = function() {
var canvas = document.createElement('canvas');
// 尺寸
var width = this.width, height = this.height;
if (width && height) {
// 存储之前的地址
if (!this.storeUrl) {
this.storeUrl = this.src;
}
// canvas大小
canvas.width = width;
canvas.height = height;
// 绘制图片帧(第一帧)
canvas.getContext('2d').drawImage(this, 0, 0, width, height);
// 重置当前图片
try {
this.src = canvas.toDataURL("image/gif");
} catch(e) {
// 跨域
this.removeAttribute('src');
// 载入canvas元素
canvas.style.position = 'absolute';
// 前面插入图片
this.parentElement.insertBefore(canvas, this);
// 隐藏原图
this.style.opacity = '0';
// 存储canvas
this.storeCanvas = canvas;
}
}
};
}
var image = document.getElementById("testImg");
</script>
这个歌词同步设计得很妙,一个个蹦出来。真不错! {:4_199:} 真漂亮的制作。
欣赏亚伦老师好帖{:4_199:} 高级!
页:
[1]