【发布时间】:2014-08-16 21:32:10
【问题描述】:
我创建了一个小页面,您可以在其中拖放音频文件,然后将其上传。然后创建一个波形并计算音频 ar 的 bpm(每分钟节拍数)。到这里:没问题。
然后我创建了一个(某种)水平时间线,其中显示了一部分波形,如果您播放音频,它将滚动。在波形上绘制“节拍标记”。它们表示每个“节拍”。我想你知道我的意思。然后在节拍标记上有一个“网格”,它允许在每个节拍中绘制多达四个“音符” - 最多三个音符“一个在另一个之上”。有点音乐性:如果节拍是 1/4 音符,则每个绘制的音符都是 1/16 音符。如果您现在有点困惑,只需观看下面的短片,我很确定您所有的歧义都会消失。 所以就是这个概念... 这是一个小演示视频: http://www.youtube.com/watch?v=DkT4LcSAcvo
现在我创建网格的实现:
<script type="text/javascript">
function createBeatBoxes() {
var duration = audio.duration;
var measures = Math.floor((duration/(60/bpm))/beatPerMeasure); //calculate the amount of measures for the complete song - beatsPerMeasure defines time signature (eg. 4/4 or 3/4)
var gapPixel = gap*secondWidth; //secondWidth defines how wide will be one second on the timeline (eg. "secondWidth=20" would mean the timeline of a song which is 10 seconds long would be 20*10 = 200 pixels wide)
var measurePixel = secondWidth*(60/bpm)*beatPerMeasure; /defines the width of of one measure
var beatPixel = measurePixel/beatPerMeasure; /defines the width of one beat
var notePixel = beatPixel/notesPerBeat; /defines the width of one note - notesPerBeat defines the amount of notes in one beat
for (i=1;i <= measures;i++) {
var measureBox = document.createElement("div");
measureBox.setAttribute('class', 'measureBox');
if (i == 1) {
measureBox.setAttribute('style', 'left:'+gapPixel+'px;width:'+measurePixel+'px');
}
else {
measureBox.setAttribute('style', 'left:'+(((i-1)*measurePixel)+gapPixel)+'px;width:'+measurePixel+'px');
}
for (j=1;j <= beatPerMeasure;j++) {
var beatBox = document.createElement("div");
beatBox.setAttribute('class', 'beatBox');
beatBox.setAttribute('style', 'left:'+((j-1)*beatPixel)+'px;width:'+beatPixel+'px');
for (k=1;k <= notesPerBeat;k++) {
var noteBarBox = document.createElement("div");
noteBarBox.setAttribute('class', 'noteBarBox');
noteBarBox.setAttribute('style', 'left:-'+(0.5*notePixel)+'px;width:'+notePixel+'px');
var noteBox = document.createElement("div");
noteBox.setAttribute('class', 'noteBox rednoteBox');
noteBox.setAttribute('onClick', 'toogleNote(this,"red")');
noteBarBox.appendChild(noteBox);
var noteBox = document.createElement("div");
noteBox.setAttribute('class', 'noteBox greennoteBox');
noteBox.setAttribute('onClick', 'toogleNote(this,"green")');
noteBarBox.appendChild(noteBox);
var noteBox = document.createElement("div");
noteBox.setAttribute('class', 'noteBox bluenoteBox');
noteBox.setAttribute('onClick', 'toogleNote(this,"blue")');
noteBarBox.appendChild(noteBox);
beatBox.appendChild(noteBarBox);
}
measureBox.appendChild(beatBox);
}
document.querySelector('#timeline').appendChild(measureBox);
}
}
</script>
这个实现的问题是时间线本身是一个非常宽的 div(例如 950000px),其中包含一个带有绘制波形的 img。在那个 div 中有许多度量 div,其中包含 (4) 个节拍 div,它们又包含 (4) 个带有 3 个不同音符子 div 的音符 div。这里有一点摘录:
<div class="measureBox" style="left:1.746031745px;width:975.609756097561px">
<div class="beatBox" style="left:0px;width:242.65243902439025px">
<div class="noteBarBox" style="left:-29.964304878048782px;width:59.928609756097565px">
<div class="noteBox rednoteBox" onclick="toogleNote(this,"red")"></div>
<div class="noteBox greennoteBox" onclick="toogleNote(this,"green")"></div>
<div class="noteBox bluenoteBox" onclick="toogleNote(this,"blue")"></div>
...
</div>
...
</div>
...
</div>
这是css:
.measureBox {
height:400px;
float:left;
border-right: 5px solid rgba(255,255,255,0.5);
position:absolute;
box-sizing:border-box;
top:0;
}
.beatBox {
height:400px;
float:left;
border-right: 3px solid rgba(255,255,255,0.5);
box-sizing:border-box;
}
.noteBarBox {
position: relative;
height:400px;
float:left;
box-sizing:border-box;
}
.noteBox {
float:left;
height:133.33px;
width:inherit;
box-sizing:border-box;
border-radius: 66.66px;
}
.redNoteBox {
top:0;
}
.greenNoteBox {
top:133.33px;
}
.blueNoteBox {
top:266.66px;
}
总结所有 div,它们的长度超过 300.000 个字符,当然不能平滑滚动了,cpu 完全不堪重负。
是否有任何其他方法可以创建这些“节拍标记”以及在不需要太多处理器负载的特定间隙/距离的网格上“绘制”音符的可能性?
我希望你能想出一些好主意,甚至是一些代码。那太棒了,因为我完全停留在这一点上。
【问题讨论】:
标签: javascript jquery html css timeline