#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() . Очень неэффективно.