Почему мой рисунок на правой стороне холста изменяет пиксели на левой стороне моего холста?

#javascript #html5-canvas

#javascript #html5-холст

Вопрос:

Я создаю графический эквалайзер формы волны для звука, используя canvas.

Я заметил, что на пиксели по всему холсту влияют штрихи, которые я делаю для определенных частей холста.

Если я вношу изменения в область холста, я ожидаю, что другие области холста не будут затронуты, но мои ожидания не оправдываются.

Почему?

Спасибо.

 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 amp;amp; 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>  

Комментарии:

1. Хотя это был приятный штрих… Вам не нужно было все повествование, чтобы объяснить вашу проблему

Ответ №1:

Вам не хватало только a beginPath , см. Код ниже

 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>  

Комментарии:

1. Чудесно. Это действительно было так просто. Спасибо. Итак, кажется, что canvas будет рисовать каждую из своих строк снова и снова, пока я не вызову beginPath() . Очень неэффективно.