ɐʞoʎǝH
ɐʞoʎǝH

Reputation: 43

Why is my drawing on the right side of the canvas changing the pixels at the left side of my canvas?

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

Answers (1)

Helder Sepulveda
Helder Sepulveda

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

Related Questions