Files
2025-03-26 21:57:50 +01:00

142 lines
4.4 KiB
JavaScript

const maxStep = 50;
const minStep = 20;
const stepDelta = 10;
const randomCount = 5;
const randomTimeout = 300;
const stepTimeoutPixelate = 300;
const stepTimeoutDepixelate = 100;
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
var isPixeling = false;
var isDepixeling = false;
function pixelate(destination) {
source = destination.cloneNode(true);
increment(source, destination, minStep);
}
function pixelateRandom(source, destination, mlt = 1) {
if (isDepixeling) return;
// pixelateImageRandom(source, destination, maxStep);
pixelateImage(source, destination, maxStep + (1 * mlt));
setTimeout(() => {
pixelateRandom(source, destination, mlt * -1);
}, randomTimeout);
}
function depixelate(source, destination) {
decrement(source, destination, maxStep);
}
function increment(source, destination, step) {
isPixeling = true;
pixelateImage(source, destination, step);
setTimeout(() => {
if (step < maxStep) {
increment(source, destination, step + stepDelta);
}
else {
isPixeling = false;
// todo fix the animation: desired: pixeling random
pixelateRandom(source, destination, randomCount);
}
}, stepTimeoutPixelate);
}
function decrement(source, destination, step) {
isDepixeling = true
pixelateImage(source, destination, step);
setTimeout(() => {
if (step > minStep) {
decrement(source, destination, step - stepDelta);
} else if (step > 1 && step <= minStep) {
isDepixeling = false
destination.src = source.src;
}
}, stepTimeoutDepixelate);
}
function pixelateImage(source, destination, pixelationFactor) {
const originalWidth = source.width;
const originalHeight = source.height;
const canvasWidth = originalWidth;
const canvasHeight = originalHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context.drawImage(source, 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);
}
}
}
destination.src = canvas.toDataURL();
}
function pixelateImageRandom(source, destination, pixelationFactor) {
const originalWidth = source.width;
const originalHeight = source.height;
const canvasWidth = originalWidth;
const canvasHeight = originalHeight;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
context.drawImage(source, 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 + Math.floor(Math.random() * 3)]},
${originalImageData[pixelIndexPosition + Math.floor(Math.random() * 3)]},
${originalImageData[pixelIndexPosition + Math.floor(Math.random() * 3)]},
${originalImageData[pixelIndexPosition + 3]}
)`;
context.fillRect(x, y, pixelationFactor, pixelationFactor);
}
}
}
destination.src = canvas.toDataURL();
}
window.pixelate = pixelate;
window.depixelate = depixelate;