From 0987a67382eb4729dacf235b5bad8b248a2ac37c Mon Sep 17 00:00:00 2001 From: "J.W. Jagersma" Date: Sun, 13 Sep 2020 06:47:05 +0200 Subject: [PATCH] split waterfall over multiple canvas elements to increase maximum fft resolution --- htdocs/css/openwebrx.css | 9 ++++++- htdocs/openwebrx.js | 52 ++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/htdocs/css/openwebrx.css b/htdocs/css/openwebrx.css index 441d4e1..d460bab 100644 --- a/htdocs/css/openwebrx.css +++ b/htdocs/css/openwebrx.css @@ -294,14 +294,21 @@ input[type=range]:disabled { flex-grow: 1; } +#webrx-canvas-container div +{ + position: relative; + overflow: visible; + width: 100%; +} + #webrx-canvas-container canvas { position: absolute; border-style: none; image-rendering: crisp-edges; image-rendering: -webkit-optimize-contrast; - width: 100%; height: 200px; + pointer-events: none; } #openwebrx-log-scroll diff --git a/htdocs/openwebrx.js b/htdocs/openwebrx.js index de65e70..9ce6c02 100644 --- a/htdocs/openwebrx.js +++ b/htdocs/openwebrx.js @@ -1226,22 +1226,30 @@ function color_between(first, second, percent) { } -var canvas_context; +var canvas_max_width = 8192; +var canvas_subcontainer; var canvases = []; var canvas_default_height = 200; var canvas_container; var canvas_actual_line; function add_canvas() { - var new_canvas = document.createElement("canvas"); - new_canvas.width = fft_size; - new_canvas.height = canvas_default_height; - canvas_actual_line = canvas_default_height - 1; - new_canvas.openwebrx_top = (-canvas_default_height + 1); - new_canvas.style.top = new_canvas.openwebrx_top.toString() + "px"; - canvas_context = new_canvas.getContext("2d"); - canvas_container.appendChild(new_canvas); - canvases.push(new_canvas); + canvas_subcontainer = document.createElement("div"); + var n = fft_size / canvas_max_width; + var w = 100 / n; + for (var i = 0; i < n; ++i) { + var new_canvas = document.createElement("canvas"); + new_canvas.width = Math.min(fft_size, canvas_max_width); + new_canvas.height = canvas_default_height; + new_canvas.style.width = w + '%'; + new_canvas.style.marginLeft = (w * i) + '%'; + canvas_actual_line = canvas_default_height - 1; + canvas_subcontainer.appendChild(new_canvas); + } + canvas_subcontainer.openwebrx_top = (-canvas_default_height + 1); + canvas_subcontainer.style.top = canvas_subcontainer.openwebrx_top.toString() + "px"; + canvas_container.appendChild(canvas_subcontainer); + canvases.push(canvas_subcontainer); while (canvas_container && canvas_container.clientHeight + canvas_default_height * 2 < canvases.length * canvas_default_height) { var c = canvases.shift(); if (!c) break; @@ -1291,7 +1299,6 @@ function waterfall_init() { function waterfall_add(data) { if (!waterfall_setup_done) return; - var w = fft_size; if (waterfall_measure_minmax_now) { var levels = waterfall_measure_minmax_do(data); @@ -1305,16 +1312,21 @@ function waterfall_add(data) { waterfallColorsContinuous(level); } - //Add line to waterfall image - var oneline_image = canvas_context.createImageData(w, 1); - for (var x = 0; x < w; x++) { - var color = waterfall_mkcolor(data[x]); - for (i = 0; i < 3; i++) oneline_image.data[x * 4 + i] = color[i]; - oneline_image.data[x * 4 + 3] = 255; - } + //Add line to waterfall + var w = Math.min(fft_size, canvas_max_width); + for (var j = 0; j < fft_size / canvas_max_width; ++j) { + var canvas_context = canvas_subcontainer.childNodes[j].getContext("2d"); + var oneline_image = canvas_context.createImageData(w, 1); + for (var x = 0; x < w; x++) { + var color = waterfall_mkcolor(data[x + canvas_max_width * j]); + for (i = 0; i < 3; i++) oneline_image.data[x * 4 + i] = color[i]; + oneline_image.data[x * 4 + 3] = 255; + } - //Draw image - canvas_context.putImageData(oneline_image, 0, canvas_actual_line--); + //Draw image + canvas_context.putImageData(oneline_image, 0, canvas_actual_line); + } + --canvas_actual_line; shift_canvases(); if (canvas_actual_line < 0) add_canvas(); }