@alOstrovsqkii

Как оптимизировать код js?

Есть функция анимации на js. Внутри интервал вызывающий функцию пикселизации изображения. Она занимает много времени и стопорит остальной код для прокрутки страницы. Как правильно переписать код?
function animatePixel(pixelatedImage, index) {
		let start = Date.now();
		let timer = setInterval(() => {
			let timePassed = Date.now() - start;

			if (timePassed >= 1500) {
				clearInterval(timer);
				resolve(1)
			}

			isVisible[index] = false;
			pixelateImage(originalImage[index], Math.floor((1500 - timePassed) / 100), pixelatedImage);
		}, 100)

	}


function pixelateImage(originalImage, pixelationFactor, pixelatedImage) {
		const canvas = document.createElement("canvas");
		const context = canvas.getContext("2d");
		const originalWidth = originalImage.width;
		const originalHeight = originalImage.height;
		const canvasWidth = originalWidth;
		const canvasHeight = originalHeight;
		canvas.width = canvasWidth;
		canvas.height = canvasHeight;
		context.drawImage(originalImage, 0, 0, originalWidth, originalHeight);
		const originalImageData = context.getImageData(
			0,
			0,
			originalWidth,
			originalHeight
		).data;
		if (pixelationFactor !== 0) {
			for (let y = 0; y < originalHeight; y += pixelationFactor) {
				for (let x = 0; x < originalWidth; x += pixelationFactor) {
					// extracting the position of the sample pixel
					const pixelIndexPosition = (x + y * originalWidth) * 4;
					// drawing a square replacing the current pixels
					context.fillStyle = `rgba(
						${originalImageData[pixelIndexPosition]},
						${originalImageData[pixelIndexPosition + 1]},
						${originalImageData[pixelIndexPosition + 2]},
						${originalImageData[pixelIndexPosition + 3]}
					)`;
					context.fillRect(x, y, pixelationFactor, pixelationFactor);
				}
			}
		}
		pixelatedImage.src = canvas.toDataURL();
	}
  • Вопрос задан
  • 452 просмотра
Пригласить эксперта
Ответы на вопрос 1
Alexandroppolus
@Alexandroppolus
кодир
У тебя дохрена всего лишнего. Как минимум, pixelatedImage.src = canvas.toDataURL(); в каждой итерации - это прямо вишенка на торте.

показывай анимацию на канве, а не в элементе img

Однократно:
1) создать канву нужных размеров, кинуть на неё картинку
2) забрать originalImageData = context.getImageData(...)
3) создать новый targerImageData = context.createImageData(width, height)

На каждой итерации (на каждом срабатывании таймера):
1) Обойдя пиксели originalImageData, заполнить соответствующие квадраты в targerImageData
2) Вызвать context.putImageData(targerImageData, 0, 0)

Если у тебя большая картинка и это всё равно будет подтормажвиать, то стоит попробовать вынести работу с originalImageData и targerImageData в отдельный поток. При этом targerImageData нужно правильно перекидывать между потоками.

Как вариант, можно попробовать раскурить webgl, тут подсказать не могу, не пробовал.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы