diff --git a/lib/interfaces/oscilloscope.js b/lib/interfaces/oscilloscope.js index 4ee9f8a3..69103120 100644 --- a/lib/interfaces/oscilloscope.js +++ b/lib/interfaces/oscilloscope.js @@ -31,7 +31,8 @@ export default class Oscilloscope extends Interface { let options = []; let defaults = { - size: [300, 150] + size: [300, 150], + fps: undefined }; super(arguments, options, defaults); @@ -39,6 +40,9 @@ export default class Oscilloscope extends Interface { this.analyser = null; this.bufferLength = 0; this.dataArray = null; + + this.lastRefreshTimeMS = 0; + this.refreshRateMS = this.fps ? Math.round(1000/this.fps) : 0; this.active = false; @@ -62,53 +66,63 @@ export default class Oscilloscope extends Interface { this.canvas.element.style.backgroundColor = this.colors.fill; } - render() { + render(nowTime=performance.now()) { if (this.active) { requestAnimationFrame(this.render.bind(this)); + if (!this.refreshRateMS || ((nowTime - this.lastRefreshTimeMS) >= this.refreshRateMS)) { + this.lastRefreshTimeMS = nowTime; + } else { + return; //skip rendering until target framerate interval surpassed + } } if (this.analyser) { this.analyser.getByteTimeDomainData(this.dataArray); } - - this.canvas.context.fillStyle = this.colors.fill; - this.canvas.context.fillRect( + + //cache some vals to microoptimize + const width = this.canvas.element.width; + const height = this.canvas.element.height; + const canvasContext = this.canvas.context; + + canvasContext.fillStyle = this.colors.fill; + canvasContext.fillRect( 0, 0, - this.canvas.element.width, - this.canvas.element.height + width, + height ); - this.canvas.context.lineWidth = ~~(this.height / 100 + 2); - this.canvas.context.strokeStyle = this.colors.accent; + canvasContext.lineWidth = ~~(height / 100 + 2); + canvasContext.strokeStyle = this.colors.accent; - this.canvas.context.beginPath(); + canvasContext.beginPath(); if (this.source) { - var sliceWidth = (this.canvas.element.width * 1.0) / this.bufferLength; + var sliceWidth = width/this.bufferLength; var x = 0; for (var i = 0; i < this.bufferLength; i++) { var v = this.dataArray[i] / 128.0; - var y = (v * this.canvas.element.height) / 2; + var y = (v * height) / 2; if (i === 0) { - this.canvas.context.moveTo(x, y); + canvasContext.moveTo(x, y); } else { - this.canvas.context.lineTo(x, y); + canvasContext.lineTo(x, y); } x += sliceWidth; } } else { - this.canvas.context.moveTo(0, this.canvas.element.height / 2); - this.canvas.context.lineTo( - this.canvas.element.width, - this.canvas.element.height / 2 + canvasContext.moveTo(0, height / 2); + canvasContext.lineTo( + width, + height / 2 ); } - this.canvas.context.stroke(); + canvasContext.stroke(); } /** diff --git a/lib/util/dom.js b/lib/util/dom.js index 3f724d4a..c93ea677 100644 --- a/lib/util/dom.js +++ b/lib/util/dom.js @@ -37,11 +37,13 @@ exports.SmartCanvas = function(parent) { this.element = document.createElement('canvas'); this.context = this.element.getContext('2d'); + this.scale = window.devicePixelRatio || 1; + this.context.scale(this.scale, this.scale); parent.appendChild(this.element); this.resize = (w,h) => { - this.element.width = w*2; - this.element.height = h*2; + this.element.width = Math.floor(w * this.scale); + this.element.height = Math.floor(h * this.scale); this.element.style.width = w+'px'; this.element.style.height = h+'px'; };