全局控制
本帖最后由 亚伦影音工作室 于 2025-9-21 12:20 编辑 <br /><br /><style>.blackhole {margin: 10px-300px ;
position: relative;
width: 1286px;
height: 700px;
background:url(https://pic1.imgdb.cn/item/68be8b6558cb8da5c8883639.jpg) no-repeat center / cover;
overflow: hidden;--state: running;
}
#qmsvg{ position: absolute;z-index: 8;
left: 8%;cursor: pointer;
top: 10%;
animation: rot 10s linear infinite var(--state);
}
@keyframes rot {to { transform: rotate(-360deg);filter: hue-rotate(360deg); }}
#msvg{position: absolute; top: 14%;left: 6%;width:20%;height:20%;z-index: 2;animation: move 6s linear infinite var(--state);z-index: 8;cursor: pointer;}
@keyframes move {
to { transform: rotate(360deg);filter: hue-rotate(360deg); }
}
.lyrics{margin: 0;
top: 90%;
left: 50%;
transform: translate(-50%, -50%);
height: 100px; /* 调整高度,只容纳当前歌词 */
text-align: center;
position: absolute;z-index: 10;
}
.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;
}
#mypic {top:45%; left:70%;z-index: 6;
display: block;position: absolute;cursor: pointer;
width: 200px; height: 200px;
background: url(https://pic1.imgdb.cn/item/68bedc4158cb8da5c8893fd7.png)no-repeat 0 0/2600px 200px;
animation: heart-burst steps(13) 2s infinite var(--state);
}
@keyframes heart-burst {
0% {background-position: 0px 0;}
100% {background-position: -2600px 0;}
}
#mpic {top:35%; left:7%;z-index: 6;
display: block;position: absolute;cursor: pointer;
width: 260px; height: 360px;
background: url(https://pic1.imgdb.cn/item/68cea8b1c5157e1a88207bd8.png)no-repeat 0px 0/6240px 360px;
animation: burst steps(24) 2s infinite var(--state);
}
@keyframes burst {
0% {background-position: -10px 0;}
100% {background-position: -6240px 0;}
}
</style>
<div class="blackhole">
<svg id="msvg" width="400" height="400" viewBox="0 0 400 400"></svg>
<svgid="qmsvg"width="200" height="200">
<defs>
<path id="path" d="M0 100 A100 100 0 1 1 200 100 A100 100 0 1 1 0 100"/>
</defs>
<text dx="30" dy="30" font-size="30" fill="#ffff00"font-family="'楷体'">
<textPath href="#path" textLength="600">花潮论坛亚伦影音工作室</textPath>
</text>
</svg>
<div id="mypic" ></div>
<div id="mpic" ></div>
<div class="lyrics" >
<div class="lyric-line">
<div class="lyric-mask"></div>
<div class="lyric-original"></div>
</div>
</div>
</div>
<audio id="aud" src="https://www.dda5.com/plug/down.php?ac=mp3&id=1c245b97d3585e5438074b8ed6cbc3ec&.mp3" loop autoplay></audio>
<script type="module">
import Dr from 'https://638183.freep.cn/638183/svgdr/svgdr.mod.min.js';
var dr = Dr.dr(msvg);
var total = 7; // 绘制图案总数
var points = '200 200,160 65,200 10,240 65,200 200'; // 图案数据
// 绘制 total 个图案
Array.from({length: total}).forEach((_,k) => {
dr.polygon(points, 'none', 'teal', 3).transform(`rotate(${360 / total * k}, 200 200)`);
});
</script>
<script>
mpic .onclick =mypic .onclick = qmsvg.onclick =msvg.onclick = () => aud.paused ? aud.play() : aud.pause();
mState = () => blackhole.style.setProperty('--state',aud.paused ? 'paused' : 'running');
aud.onplaying = aud.onpause = () => mState();
const blackhole= document.querySelector('.blackhole');
</script>
<script>
// 歌词解析ksc歌词或lrc歌词
const lrc = `红尘梦里爱慕里再续柔情字句
落下雨点这瞬间希盼浪漫重聚
不必费解不说出不要落下情泪
若是擦肩可有对不对谁犹恨谁
>>>>
轻舟不觉已过千帆天青青
谁在泼墨藏了笔迹不作声
镜花水中不见寻觅故人天有命
无奈昨日情意沽清作一曲隽永
红尘梦里爱慕里再续柔情字句
落下雨点这瞬间希盼浪漫重聚
不必费解不说出不要落下情泪
若是擦肩可有对不对谁犹恨谁
浮云聚散已习惯放下前尘未晚
梦幻泡影交映出璀璨极乐无限
纷飞雨点不眷恋不顾落幕期限
度尽了今生你再不归还
尘俗终会散
一蓑烟雨离别哀愁更冷清
疑是昨夜凉意萧瑟催我醒
玉镂金簪钗髻来自你何须记认
遗憾已是难诉心声
绣花针印证
红尘梦里爱慕里再续柔情字句
落下雨点这瞬间希盼浪漫重聚
不必费解不说出不要落下情泪
若是擦肩可有对不对谁犹恨谁
浮云聚散已习惯放下前尘未晚
梦幻泡影交映出璀璨极乐无限
纷飞雨点不眷恋不顾落幕期限
度尽了今生你再不归还
尘俗终会散
看看夕照世俗无奈地叹
旧日往昔怎再返因有道别时限
风声雨声欢笑声一切渐渐回慢
但是我可否再回头望一眼
见惯聚散放下前尘未晚
梦幻泡影交映出璀璨极乐无限
纷飞雨点不眷恋不顾落幕期限
度尽了今生你再不归还
尘俗终会散
`;
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:} 原来这两张图图都是长图移动的蒙太奇动态效果呢,还以为是gif图能暂停在任意帧呢{:4_173:}
歌词同步也很漂亮,这个制作真棒{:4_199:} 欣赏佳作,问候亚伦。 制作非常漂亮!形成自己的独特风格! 漂亮!谢谢亚伦老师精彩分享{:4_191:} 刷新刷新看看,就看见二个动图,其他没有出来
https://i.postimg.cc/j5dLPtq7/QQ-1758374400245.jpg 现在播放器出来了,背景还是看不见,可能我的网速吧 音画唯美!
制作大气,太棒了!
谢谢亚伦影音工作室带来的精彩~!辛苦了! 老师制作的精彩,点赞!
页:
[1]