I am writing a "waterfall" diagram for an SDR receiver which is displayed in a canvas on a web page.
The canvas has a size of w=1000 h=800 pixels. The top line is delivered every 50ms from a server. The browser (using javascript) must move all lines down one line and then insert the new line at the top. This gives the look of a waterfall where all pixels are moving from top to bottom.
It is working fine, but the CPU load for the pixel moving is very high, too high for i.e. a raspberry.
What I am doing is:
var imagedata = context.getImageData(0,0,pixwidth,height-1);
var dataCopy = new Uint8ClampedArray(imagedata.data);
for(i=(dataCopy.length - (2*pixwidth*4)); i>= 0; i--) {
dataCopy[i+ pixwidth*4] = dataCopy[i];
}
imagedata.data.set(dataCopy);
// insert new top line
// ....
context.putImageData(imagedata, 0, 0);
I also tried to directly copy the pixel data in imagedata[some index], which gives almost the same bad performance.
In another C-Program I did the same thing with a simple memcpy operation which is very fast. But what to do in Javascript ? There are 800.000 pixels, which are 3.200.000 bytes. How can I copy or move them with the best possible performance in Javascript ?
var cv = document.getElementById('cv');
var ctx = cv.getContext('2d');
function draw() {
ctx.fillStyle = `hsla(${360 * Math.random()}, 100%, 50%, 1)`;
ctx.fillRect(0, 0, cv.width, 10);
ctx.drawImage(cv, 0, 10);
}
setInterval(function() { draw() }, 200)
<canvas id="cv" width="800" height="400"></canvas>
After drawing a line, take a snapshot of the entire canvas and redraw it with an offset of 10 px on the y scale. Repeat the process and you will get an waterfall like effect.