diff options
| author | julian laplace <julescarbon@gmail.com> | 2023-05-09 17:44:31 +0200 |
|---|---|---|
| committer | julian laplace <julescarbon@gmail.com> | 2023-05-09 17:44:31 +0200 |
| commit | 199f7c731886bd8e8ac0d28bd15ebec241255594 (patch) | |
| tree | 3122029522f44a105805bcb8f171f8b13fb956d8 /src/relabi/canvas.js | |
| parent | 0cac17666313c660b2fb6d18bea1aa844b060cbe (diff) | |
rendering dots
Diffstat (limited to 'src/relabi/canvas.js')
| -rw-r--r-- | src/relabi/canvas.js | 90 |
1 files changed, 79 insertions, 11 deletions
diff --git a/src/relabi/canvas.js b/src/relabi/canvas.js index dfbffa0..d2c55a2 100644 --- a/src/relabi/canvas.js +++ b/src/relabi/canvas.js @@ -17,14 +17,14 @@ export default class RelabiCanvas { // Speed of the wave in pixels per second this.speed = 1 / 5; - // Attach to the DOM - this.parent = parent = document.body; - this.canvas = document.createElement("canvas"); - this.ctx = this.canvas.getContext("2d"); - this.parent.appendChild(this.canvas); + // Position of current time on the screen, from the left + this.tZeroOffset = 20; + // Attach to the DOM + this.appendCanvas(parent); // Initialize array this.values = new Array(window.innerWidth).fill(0); + this.notes = []; this.append([]); // Clear the canvas @@ -35,6 +35,16 @@ export default class RelabiCanvas { } /** + * Append the canvas + */ + appendCanvas(parent) { + this.parent = parent || document.body; + this.canvas = this.canvas || document.createElement("canvas"); + this.ctx = this.ctx || this.canvas.getContext("2d"); + this.parent.appendChild(this.canvas); + } + + /** * Draw the next frame */ requestAnimationFrame(frame) { @@ -63,10 +73,20 @@ export default class RelabiCanvas { /** * Append values */ - append(time, values) { + append(time, values, notes) { this.lastAppendTime = time; this.lastAppendFrame = this.lastFrame; - this.values = this.values.concat(values).slice(-this.canvas.width); + this.values = this.values + .concat(values) + .slice(-this.canvas.width) + .sort((a, b) => a[0] - b[0]); + + if (notes?.length) { + this.notes = this.notes + .concat(notes) + .slice(-50) + .sort((a, b) => a[0] - b[0]); + } } /** @@ -76,6 +96,7 @@ export default class RelabiCanvas { this.clear(); this.drawRelabiWave(frame); this.drawBounds(); + this.drawNotes(frame); } /** @@ -90,12 +111,22 @@ export default class RelabiCanvas { const y = getWaveHeight(bound.level, height); ctx.beginPath(); - ctx.setLineDash([10, 5]); + ctx.setLineDash([4, 4]); + ctx.lineWidth = 1; ctx.strokeStyle = bound.color || "#888"; ctx.moveTo(0, y); ctx.lineTo(width, y); ctx.stroke(); } + + // Draw the zero position + ctx.beginPath(); + ctx.setLineDash([1, 1]); + ctx.lineWidth = 2; + ctx.strokeStyle = "#666"; + ctx.moveTo(width - this.tZeroOffset, 0); + ctx.lineTo(width - this.tZeroOffset, height); + ctx.stroke(); } /** @@ -110,7 +141,8 @@ export default class RelabiCanvas { // Start the path ctx.beginPath(); - ctx.strokeStyle = "white"; + ctx.strokeStyle = "#dff"; + ctx.lineWidth = 0.75; ctx.setLineDash([]); // This is the offset in seconds from the last frame we computed @@ -130,13 +162,13 @@ export default class RelabiCanvas { // Subtracting the frame offset pulls it negative. const timeOffset = this.lastAppendTime + frameOffset - time; - const x = width - timeOffset * this.speed * width - 10; + const x = width - timeOffset * this.speed * width - this.tZeroOffset; + const y = getWaveHeight(value, height); if (x < 0) { continue; } - const y = getWaveHeight(value, height); if (index === 0) { ctx.moveTo(x, y); } @@ -147,6 +179,42 @@ export default class RelabiCanvas { // Paint the line ctx.stroke(); } + + /** + * Draw the notes + */ + drawNotes(frame) { + const { canvas, ctx } = this; + const { width, height } = canvas; + + // This is the offset in seconds from the last frame we computed + const frameOffset = (frame - this.lastAppendFrame) / 1000; + + // Make a path connecting all values + for (const note of this.notes) { + const [time, value, direction] = note; + const timeOffset = this.lastAppendTime + frameOffset - time; + const x = width - timeOffset * this.speed * width - this.tZeroOffset; + const y = getWaveHeight(value, height); + + // Don't draw notes that haven't played yet + if (x > width - this.tZeroOffset) { + continue; + } + + // Draw notes as a dot that fades out + const opacity = 1 - (timeOffset * this.speed * width) / 1000; + if (opacity < 0.001) { + continue; + } + ctx.beginPath(); + ctx.arc(x - 2.5, y, 5, 0, 2 * Math.PI); + ctx.fillStyle = direction + ? `rgba(255,128,192,${opacity})` + : `rgba(192,255,128,${opacity})`; + ctx.fill(); + } + } } /** |
