You can edit the below JavaScript code to customize the image tool.
function processImage(
originalImg,
fontSize = 16,
fontColor = "lime",
trailColor = "rgba(0, 0, 0, 0.05)",
characterType = "katakana_numbers", // Options: "katakana_numbers", "alphanumeric", "binary", "numbers", "katakana"
fallSpeed = 1,
resetProbability = 0.02
) {
// Ensure numeric parameters are numbers and have valid ranges/defaults
fontSize = Number(fontSize);
if (isNaN(fontSize) || fontSize <= 0) {
fontSize = 16;
}
fallSpeed = Number(fallSpeed);
if (isNaN(fallSpeed) || fallSpeed <= 0) {
fallSpeed = 1;
}
resetProbability = Number(resetProbability);
if (isNaN(resetProbability) || resetProbability < 0 || resetProbability > 1) {
resetProbability = isNaN(resetProbability) ? 0.02 : Math.max(0, Math.min(1, resetProbability));
}
characterType = String(characterType); // Ensure characterType is a string for the switch
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d', { alpha: false }); // alpha: false assuming trailColor effectively makes it opaque
// Use naturalWidth/Height if available for the image, fallback to width/height
canvas.width = originalImg.naturalWidth || originalImg.width;
canvas.height = originalImg.naturalHeight || originalImg.height;
// Handle cases where image dimensions might be problematic
if (canvas.width === 0 || canvas.height === 0) {
canvas.width = canvas.width || 100; // Ensure some dimension if original was 0
canvas.height = canvas.height || 100;
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Attempt to draw an error message on the placeholder canvas
if (typeof ctx.fillText === 'function') {
ctx.fillStyle = "red";
ctx.font = "12px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Error: Image zero size", canvas.width / 2, canvas.height / 2);
}
return canvas;
}
// Draw the original image ONCE as the initial background.
try {
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
} catch (e) {
// Fallback: fill canvas with black if image drawing fails (e.g. tainted canvas)
ctx.fillStyle = "black";
ctx.fillRect(0, 0, canvas.width, canvas.height);
if (typeof ctx.fillText === 'function') {
ctx.fillStyle = "red";
ctx.font = "12px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Error: Couldn't draw image", canvas.width/2, canvas.height/2);
}
return canvas; // Early exit if image can't be drawn
}
// Define character sets
const KATAKANA_SET = "アァカサタナハマヤャラワガザダバパイィキシチニヒミリヰギジヂビピウゥクスツヌフムユュルグズブヅプエェケセテネヘメレヱゲゼデベペオォコソトノホモヨョロヲゴゾドボポヴッン";
const NUMBERS_SET = "0123456789";
const ALPHANUMERIC_SET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" + NUMBERS_SET;
const BINARY_SET = "01";
let charSet = "";
switch (characterType.toLowerCase()) {
case "katakana_numbers":
charSet = KATAKANA_SET + NUMBERS_SET;
break;
case "alphanumeric":
charSet = ALPHANUMERIC_SET;
break;
case "binary":
charSet = BINARY_SET;
break;
case "numbers":
charSet = NUMBERS_SET;
break;
case "katakana":
charSet = KATAKANA_SET;
break;
default:
charSet = KATAKANA_SET + NUMBERS_SET; // Default if unknown type
}
// Ensure charSet is not empty
if (charSet.length === 0) {
charSet = NUMBERS_SET;
}
const numColumns = Math.floor(canvas.width / fontSize);
// If canvas is too narrow for any columns, apply trail and return
if (numColumns <= 0) {
ctx.fillStyle = trailColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
return canvas;
}
// Initialize drops: y-coordinate (in fontSize blocks) for the leading char of each column
const drops = [];
for (let i = 0; i < numColumns; i++) {
// Start drops at random negative y-positions (staggered above the canvas)
// Stagger depth is somewhat proportional to the number of columns.
drops[i] = -(Math.random() * numColumns * 0.8);
}
function drawMatrix() {
// Apply trailColor: fills the canvas, creating a fading effect for previous characters
// and continuously fading the original background image.
ctx.fillStyle = trailColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = fontColor;
ctx.font = `${fontSize}px monospace`; // Monospace for grid-like character alignment
for (let i = 0; i < numColumns; i++) {
const charIndex = Math.floor(Math.random() * charSet.length);
const text = charSet[charIndex];
const xPos = i * fontSize;
const yPos = drops[i] * fontSize;
ctx.fillText(text, xPos, yPos);
// Check if the drop's y-position is past the canvas height
if (yPos > canvas.height) {
// If so, and a random chance is met (based on resetProbability), reset the drop.
if (Math.random() < resetProbability) {
// Reset to a staggered position slightly above the canvas.
drops[i] = -(Math.random() * numColumns * 0.2);
}
// If resetProbability is 0, or the random chance isn't met, the drop continues
// falling further down. It will only reset if resetProbability > 0 and the chance occurs.
}
drops[i] += fallSpeed; // Move the drop down for the next frame
}
requestAnimationFrame(drawMatrix); // Continue the animation loop
}
drawMatrix(); // Start the animation
return canvas; // Return the canvas, on which the animation is continuously drawing
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Matrix Code Rain Filter Effect Tool allows users to apply a dynamic visual effect reminiscent of the iconic ‘Matrix’ code rain to their images. This tool transforms the original image into a flowing backdrop of falling characters, which can be customized with varying font sizes, colors, speed, and character sets. Use cases include enhancing digital artwork, creating background visuals for videos, or simply adding a creative overlay to images for social media posts. The tool’s settings allow for various styles from alphanumeric characters to katakana and binary representations, making it versatile for different artistic preferences.