你的梦里没有我一席之地 - 赵洋【】火焰频谱
本帖最后由 亚伦影音工作室 于 2024-12-10 21:02 编辑 <br /><br /><style>#papa{width: 1164px; height: 620px; margin-top:120px; margin-left:-300px;box-shadow: 0px 0px 0px 2px #cccccc, 0px 0px 0px 8px #880000; overflow: hidden;transform:rotate(0deg);background:url(https://pic.imgdb.cn/item/6600f9079f345e8d03f51404.jpg)no-repeat center/cover,linear-gradient(50deg, #000080, #ff0000, #000000, #00f000); text-align: center;}
#aud {position:absolute;margin-top:0px; margin-left:0px;z-index: 60;
display: block;
width:102%;clip-path: inset(20% 1% 20% 1%);filter:invert(100%);margin: 580px -14px;
}
.lrc {position:absolute;width: 700px;margin-left:0px; z-index: 6;
height: 450px;
border: 0px solid white; text-align: center;
overflow: hidden;margin: 50px 0px;
}
.lrc #ul {overflow: hidden;
transition: all 0.6s;
text-align: center;
}
.lrc #ul li {font-size: 20px;overflow: hidden;
font-family:华文新魏;text-align: center;
color: #cccccc;
filter:drop-shadow(#000 1px 1px 1px)drop-shadow(#000 1px 1px 1px);
height: 40px; font-weight: normal;
line-height: 30px;
}
.lrc #ulli.active{ transform:translate(20px,0px)scale(1.3);
color: #ffFF00;
margin: 0px 0px;
}
</style>
<div id="papa">
<audio id="aud"src="https://s2.ananas.chaoxing.com/sv-w8/audio/76/ed/0e/913adbf00656d493283282ada91272c4/audio.mp3" autoplay loopcontrols crossOrigin="anonymous"></audio>
<div class="lrc">
<ul id="ul">
</ul>
</div>
<canvas id='canvas' width="2400" height="250"style="position: absolute; left:0px; bottom:20px;"></canvas>
</div>
<script>
var lrc = `你的梦里没有我一席之地(DJ 默涵版) - 赵洋
作词Lyricist: 关连宇
作曲Composer: 赵洋
那天在朋友的婚礼上偶遇
看到你们言谈举止很亲密
我没有勇气和你寒暄几句
只能躲在角落里偷偷哭泣
没能和你成个家真的可惜
是我命中注定没这个福气
如果早点说出那句对不起
也许我们就不是这样结局
你的梦里不再有我一席之地
我的位置已被别人代替
你带走我的心带不走回忆
无论何时都无法把你忘记
你的梦里已没有我一席之地
我的灵魂变得孤苦无依
没有你爱情还有什么意义
你就是我的空气我的呼吸
没能和你成个家真的可惜
是我命中注定没这个福气
如果早点说出那句对不起
也许我们就不是这样结局
你的梦里不再有我一席之地
我的位置已被别人代替
你带走我的心带不走回忆
无论何时都无法把你忘记
你的梦里已没有我一席之地
我的灵魂变得孤苦无依
没有你爱情还有什么意义
你就是我的空气我的呼吸
你就是我的空气我的呼吸
`;
// 最开始获取到的歌词列表是字符串类型(不好操作)
let lrcArr = lrc.split('\n');
// 接收修正后的歌词数组
let result = [];
// 获取所要用到的dom列表
doms = {
audio: document.querySelector("#aud"),
ul: document.querySelector("#ul"),
container: document.querySelector(".lrc")
}
// 将歌词数组转成由对象组成的数组,对象有time和word两个属性(为了方便操作)
for (let i = 0; i < lrcArr.length; i++) {
var lrcData = lrcArr.split(']');
var lrcTime = lrcData.substring(1);
var obj = {
time: parseTime(lrcTime),
word: lrcData
}
result.push(obj);
}
// 将tiem转换为秒的形式
function parseTime(lrcTime) {
lrcTimeArr = lrcTime.split(":")
return +lrcTimeArr * 60 + +lrcTimeArr;
}
// 获取当前播放到的歌词的下标
function getIndex() {
let Time = doms.audio.currentTime;
for (let i = 0; i < result.length; i++) {
if (result.time > Time) {
return i - 1;
}
}
}
// 创建歌词列表
function createElements() {
let frag = document.createDocumentFragment(); // 文档片段
for (let i = 0; i < result.length; i++) {
let li = document.createElement("li");
li.innerText = result.word;
frag.appendChild(li);
}
doms.ul.appendChild(frag);
}
createElements();
// 获取显示窗口的可视高度
let containerHeight = doms.container.clientHeight;
// 获取歌词列表的可视高度
let liHeight = doms.ul.children.clientHeight;
// 设置最大最小偏移量,防止显示效果不佳
let minOffset = 0;
let maxOffset = doms.ul.clientHeight - containerHeight;
// 控制歌词滚动移动的函数
function setOffset() {
let index = getIndex();
// 计算滚动距离
let offset = liHeight * index - containerHeight / 2 + liHeight / 2;
if (offset < minOffset) {
offset = minOffset;
};
if (offset > maxOffset) {
offset = maxOffset;
};
// 滚动
doms.ul.style.transform = `translateY(-${offset}px)`;
// 清除之前的active
let li = doms.ul.querySelector(".active")
if (li) {
li.classList.remove("active");
}
// 为当前所唱到的歌词添加active
li = doms.ul.children;
if (li) {
li.classList.add("active");
}
};
// 当audio的播放时间更新时,触发该事件
doms.audio.addEventListener("timeupdate", setOffset);
</script>
<script>
window.onload = function() {
var audio = document.getElementById('audio');
var ctx = new AudioContext();
var analyser = ctx.createAnalyser();
var audioSrc = ctx.createMediaElementSource(aud);
// we have to connect the MediaElementSource with the analyser
audioSrc.connect(analyser);
analyser.connect(ctx.destination);
// we could configure the analyser: e.g. analyser.fftSize (for further infos read the spec)
// analyser.fftSize = 164;
// frequencyBinCount tells you how many values you'll receive from the analyser
var frequencyData = new Uint8Array(analyser.frequencyBinCount);
// we're ready to receive some data!
var canvas = document.getElementById('canvas'),
cwidth = canvas.width,
cheight = canvas.height - 1,
meterWidth = 2, //width of the meters in the spectrum
gap = 2, //gap between meters
capHeight = 1,
capStyle = '#fff',
meterNum = 2400 / (2+ 1), //count of the meters
capYPositionArray = []; ////store the vertical position of hte caps for the preivous frame
ctx = canvas.getContext('2d'),
gradient = ctx.createLinearGradient(0, 20, 0, 300);
gradient.addColorStop(0.3, '#ffff00');
gradient.addColorStop(0.8, '#ff0000');
gradient.addColorStop(1, '#ffff00');
// loop
function renderFrame() {
var array = new Uint8Array(analyser.frequencyBinCount);
analyser.getByteFrequencyData(array);
var step = Math.round(array.length / meterNum); //sample limited data from the total array
ctx.clearRect(0, 0, cwidth, cheight);
for (var i = 0; i < meterNum; i++) {
var value = array;
if (capYPositionArray.length < Math.round(meterNum)) {
capYPositionArray.push(value);
};
ctx.fillStyle = capStyle;
//draw the cap, with transition effect
if (value < capYPositionArray) {
ctx.fillRect(i * 1.5, cheight - (--capYPositionArray), meterWidth, capHeight);
} else {
ctx.fillRect(i * 1, cheight - value, meterWidth, capHeight);
capYPositionArray = value;
};
ctx.fillStyle = gradient; //set the filllStyle to gradient for a better look
ctx.fillRect(i * 1.5 /*meterWidth+gap*/ , cheight - value + capHeight, meterWidth, cheight); //the meter
}
requestAnimationFrame(renderFrame);
}
renderFrame();
audio.play();
};
</script>
又一个带响应式频谱和长歌词的帖子。亚伦老师厉害了,一下子做了这么多,还都这么漂亮{:4_199:} 亚伦,我手机看不见你的按钮音乐,频谱都没有听到了以后电脑上去再欣赏了
页:
[1]