Falc410
Vice Admiral
- Registriert
- Juni 2006
- Beiträge
- 6.723
Ich habe ein HTML Canvas Element welches mir die Waveform eines Audiosamples anzeigt (wurde vom Benutzer aufgenommen und in Javascript gespeichert).
Der Canvas wird so erzeugt:
und anschliessend "bemalt", dafür habe ich eine etwas komplizierte Funktion gefunden die das perfekt übernimmt:
Resultat sieht dann so aus:

Nun möchte ich, das ein Cursor über die Waveform fährt während das WAV File abgespielt wird. Den Cursor konnte ich erzeugen und der fährt auch von Links nach Rechts (die Geschwindigkeit muss ich noch an die Länge des WAV Files anpassen). Das Problem ist allerdings dass nun nur noch der Cursor angezeigt wird und die ursprüngliche Waveform verschwindet.
Kann ich das clearen des Canvas irgendwie verhindern? Wenn ich das context.clearRect rausnehme dann wird die Waveform übermalt von meinem Cursor. Ich hatte erwartet das wirklich nur das Rect bewegt wird, aber das hinterlässt dann eben eine Spur. Durch das context.clearRect wird wohl alles gelöscht und der Canvas zum Zeitpunkt x komplett neu gezeichnet. Dann müsste ich aber in jedem Frame das Waveform neu malen - was relativ aufwendig ist. Gibt es da eine andere Möglichkeit?
Hier sieht man den Cursor (bewegt sich nach rechts):

und noch einmal wenn ich das context.clearRect auskommentiere:

Hier der Code für die Animation:
Ausgelöst wird er beim Click auf den Play Knopf:
Der Canvas wird so erzeugt:
Code:
<canvas id="wavedisplay" width="1024" height="200" style="display: inline-block;
width: 95%; height: 45%; box-shadow: 0px 0px 10px blue;"></canvas>
Code:
function drawBuffer( width, height, context, data ) {
var step = Math.ceil( data.length / width );
var amp = height / 2;
context.fillStyle = "black";
context.clearRect(0,0,width,height);
for(var i=0; i < width; i++){
var min = 1.0;
var max = -1.0;
for (var j=0; j<step; j++) {
var datum = data[(i*step)+j];
if (datum < min)
min = datum;
if (datum > max)
max = datum;
}
context.fillRect(i,(1+min)*amp,1,Math.max(1,(max-min)*amp));
}
}

Nun möchte ich, das ein Cursor über die Waveform fährt während das WAV File abgespielt wird. Den Cursor konnte ich erzeugen und der fährt auch von Links nach Rechts (die Geschwindigkeit muss ich noch an die Länge des WAV Files anpassen). Das Problem ist allerdings dass nun nur noch der Cursor angezeigt wird und die ursprüngliche Waveform verschwindet.
Kann ich das clearen des Canvas irgendwie verhindern? Wenn ich das context.clearRect rausnehme dann wird die Waveform übermalt von meinem Cursor. Ich hatte erwartet das wirklich nur das Rect bewegt wird, aber das hinterlässt dann eben eine Spur. Durch das context.clearRect wird wohl alles gelöscht und der Canvas zum Zeitpunkt x komplett neu gezeichnet. Dann müsste ich aber in jedem Frame das Waveform neu malen - was relativ aufwendig ist. Gibt es da eine andere Möglichkeit?
Hier sieht man den Cursor (bewegt sich nach rechts):

und noch einmal wenn ich das context.clearRect auskommentiere:

Hier der Code für die Animation:
Code:
function animate(myRectangle, canvas, context, startTime) {
// update
var time = (new Date()).getTime() - startTime;
var linearSpeed = 100;
// pixels / second
var newX = linearSpeed * time / 1000;
if(newX < canvas.width - myRectangle.width - myRectangle.borderWidth / 2) {
myRectangle.x = newX;
}
// clear
context.clearRect(0, 0, canvas.width, canvas.height);
drawRectangle(myRectangle, context);
// request new frame
requestAnimFrame(function() {
animate(myRectangle, canvas, context, startTime);
});
}
var canvas = document.getElementById('wavedisplay');
var context = canvas.getContext('2d');
var myRectangle = {
x: 0,
y: 0,
width: 10,
height: canvas.height,
borderWidth: 1
};
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function drawRectangle(myRectangle, context) {
context.beginPath();
context.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height);
context.fillStyle = '#8ED6FF';
context.fill();
context.lineWidth = myRectangle.borderWidth;
context.strokeStyle = 'black';
context.stroke();
}
Ausgelöst wird er beim Click auf den Play Knopf:
Code:
$('#playPauseButton').on('click', function() {
$('#recording')[0].play();
var startTime = (new Date()).getTime();
animate(myRectangle, canvas, context, startTime);
});
Zuletzt bearbeitet: