У меня действительно странное поведение при выполнении функции.
Вот контекст: я пишу некий инструмент для рисования, основанный на манипуляциях с холстом. Мне нужно взять данные с основного холста и применить к нему процесс каждые N секунд (заменив цвет другим, и установите значение 0,0,0,0 для каждого второго пикселя). Затем обработанные данные помещаются в saveCanvas.
Функция:
function replaceColorByAnotherColor(data, oldRgbColor, newRgbColor, opacity) {
let i = 0;
let testTime = new Date();
let testPos = 0;
let testNeg = 0;
while (i < data.length) {
if (
data[i] >= oldRgbColor.r - 50 &&
data[i] <= oldRgbColor.r + 50 &&
data[i + 1] >= oldRgbColor.g - 50 &&
data[i + 1] <= oldRgbColor.g + 50 &&
data[i + 2] >= oldRgbColor.b - 50 &&
data[i + 2] <= oldRgbColor.b + 50
) {
testPos++;
data[i] = newRgbColor.r;
data[i + 1] = newRgbColor.g;
data[i + 2] = newRgbColor.b;
data[i + 3] = opacity;
} else {
testNeg++;
data[i] = 0;
data[i + 1] = 0;
data[i + 2] = 0;
data[i + 3] = 0;
}
i += 4;
}
console.log(data.length);
console.log(testPos);
console.log(testNeg);
console.log(new Date() - testTime + ' ms');
}
Вот JsFiddle , которая пытается воспроизвести ситуацию.
Итак, вот проблема, с которой я сталкиваюсь: иногда выполнение моей функции процесса занимает очень много времени (от ~ 80 мс до более чем 7 секунд!).
Когда я использую инструмент "производительность" в Chrome отладчик, вот что я нашел:
Когда после выполнения я не обновляю sh объект, читая картинку с основного холста (что я должен сделать для всего своего кода, чтобы работает правильно), моя функция выполняется нормально, например this JsFiddle :
Но если после выполнения я переосмыслил sh объект с getImageData()
на главном холсте выполнение моей функции - это своего рода фрагмент (и он намного длиннее), которого я никогда раньше не видел, как в this JsFiddle : Zoomed:
Я также указал, что в любом случае 3 или 4 в первый раз tions работает как заклинание, до того, как ошибка (или что-то еще) происходит.
Я не имею понятия о том, что происходит с этим исполнением.
Есть ли у вас какие-либо идеи? или вы когда-нибудь сталкивались с таким поведением раньше?
Спасибо!
РЕДАКТИРОВАТЬ 1:
Мне удалось вести себя так же без Реагируйте стеком в этот JsFiddle . Кстати, извините за отвратительную строку base64 в начале скрипки. Это мой первый раз с JsFiddle, я не знаю, как включить другие файлы, и я думаю, что моя проблема связана с размером изображения.
Как предложил @Bonatti, я включил основную функцию выше. И вот основной код:
<div>
<canvas style="width:200px" id="mainCanvas" width="3280" height="2464"></canvas>
<canvas style="width:200px" id="saveCanvas" width="3280" height="2464"></canvas>
</div>
var test = {
src:"data:image/png;base64,iVBOR....."
}
let imageData = null;
let mainTimeout = setTimeout(() => {processCanvas()},10000);
let mainCanvas = document.getElementById('mainCanvas');
let mainCtx = mainCanvas.getContext('2d');
let saveCanvas = document.getElementById('saveCanvas');
let saveCtx = saveCanvas.getContext('2d');
let image = new Image();
image.onload = () => {
mainCtx.drawImage(image,0,0);
imageData = mainCtx.getImageData(0,0,3280,2464);
}
image.src = test.src;
var refreshImageData = () => {
imageData = mainCtx.getImageData(0,0,3280,2464);
}
var processCanvas = () => {
console.log('====== PROCESS ======');
clearTimeout(mainTimeout);
refreshImageData();
replaceColorByAnotherColor(imageData.data, {r:255,g:0,b:0}, { r: 0, g: 255, b: 0 }, 255);
saveCtx.putImageData(imageData, 0, 0);
refreshImageData();
mainTimeout = setTimeout(() => {processCanvas()},10000);
}
Результат выполнения:
====== PROCESS ======
32327680
161417
7920503
63 ms
====== PROCESS ======
32327680
161417
7920503
225 ms
====== PROCESS ======
32327680
161417
7920503
2566 ms
И после этого он никогда не опускается ниже 2000 мс.
РЕДАКТИРОВАТЬ 2:
Похоже, проблема возникает, когда я читаю или пишу в массиве data
.
Это происходит, если я делаю:
while (i < data.length) {
if (data[i] === oldRgbColor.r) {
testPos++;
} else {
testNeg++;
}
i += 4;
}
Но нет, если я сделаю
while (i < data.length) {
if (i % 5) {
testPos++;
} else {
testNeg++;
}
i += 4;
}