Reputation: 43
I'm creating a waveform graphic equalizer for audio, using canvas.
I've noticed that pixels all over the canvas are being affected by strokes that I make to specific parts of the canvas.
If I make a change to a region of the canvas, I expect other regions of the canvas to be unaffected, but my expectation is not being met.
Why?
Thank you.
const c = document.getElementById('c');
const ctx = c.getContext('2d');
const [ r,g,b ] = [0,0,0];
const { height } = ctx.canvas;
const colorNode = document.getElementById('color');
const narrationNode = document.getElementById('narration');
var x = 0;
ctx.lineWidth = 1;
const interval = setInterval(() => {
x++;
if (x > 500) clearInterval(interval);
narrationNode.innerHTML = narration.map(
(narrative, i) => narrative && x >= i
? `<li>${narrative}</li>`
: ''
).join('');
const margin = x/5;
const gradient = ctx.createLinearGradient(
0, margin, 0, height-margin
);
gradient.addColorStop(0, `rgba(${r},${g},${b},0)`);
gradient.addColorStop(0.5, `rgba(${r},${g},${b},1)`);
gradient.addColorStop(1.0, `rgba(${r},${g},${b},0)`);
ctx.strokeStyle = gradient;
ctx.moveTo(x, margin);
ctx.lineTo(x, height-margin);
ctx.stroke();
var pixel = ctx.getImageData(25, 5, 1, 1).data;
var rgba = 'rgba(' + pixel[0] + ', ' + pixel[1] +
', ' + pixel[2] + ', ' + (pixel[3] / 255) + ')';
colorNode.innerHTML = rgba + ', ' + x;
},90)
var idx = 0;
const narration = [];
idx += 00; narration[idx] = 'We are monitoring alpha channel of a single pixel of this canvas at position 25x5.';
idx += 10; narration[idx] = 'It goes from 0 to 0.007 as the gradient sweeps across it.';
idx += 15; narration[idx] = 'See?';
idx += 40; narration[idx] = 'Naturally, the gradient stroke painted over this pixel, giving it a higher alpha value.';
idx += 40; narration[idx] = 'It is now reasonable to expect that this pixel will remain unchanged unless painted over again.';
idx += 40; narration[idx] = 'We will not paint over this pixel ever again, yet, you are going to see its alpha value change anyway!';
idx += 35; narration[idx] = 'Now, wait until the triangle tapers.';
idx += 20; narration[idx] = 'In a moment a second triangle will begin to form, and you will see.';
idx += 40; narration[idx] = '...'
idx += 20; narration[idx] = 'Now watch, as the second triangle begins to form.';
idx = 270; narration[idx] = 'The lines of the FIRST triangle begin to change, taking on sharp aliasing...';
idx = 330; narration[idx] = 'WTF?';
idx += 40; narration[idx] = 'Why?';
idx += 80; narration[idx] = 'Now watch the alpha channel value above... here it comes!';
idx = 460; narration[idx] = 'There!';
idx = 490; narration[idx] = 'Why is my drawing on the right side of the canvas changing the pixels at the left side of my canvas?';
#c {
background: #fff;
}
body {
background: #333;
color: #ccc;
}
<canvas id="c" height="100" width="500"></canvas>
<p>
Color at 5,5 = <span id="color">?</span>
</p>
<h1>Here's my question:</h1>
<ul id="narration"></ul>
Upvotes: 4
Views: 52
Reputation: 17594
You were missing just a beginPath
, see code below
const c = document.getElementById('c');
const ctx = c.getContext('2d');
const { height } = ctx.canvas;
var x = 0;
const interval = setInterval(() => {
x += 2;
if (x > 500) clearInterval(interval);
margin = x/5;
gradient = ctx.createLinearGradient(0, margin, 0, height-margin);
gradient.addColorStop(0, `rgba(0,0,0,0)`);
gradient.addColorStop(0.5, `rgba(0,0,0,1)`);
gradient.addColorStop(1.0, `rgba(0,0,0,0)`);
ctx.strokeStyle = gradient;
ctx.beginPath();
ctx.moveTo(x, margin);
ctx.lineTo(x, height-margin);
ctx.stroke();
},10)
<canvas id="c" height="100" width="500"></canvas>
Upvotes: 2