You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, textTop = "MATER", textBottom = "MAJOR", rustLevel = "0.7") {
// 1. Setup Canvas
const canvas = document.createElement('canvas');
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// 2. Draw original image
ctx.drawImage(originalImg, 0, 0, width, height);
const intensity = Math.min(1, Math.max(0, parseFloat(rustLevel) || 0.7));
// 3. Apply Mater Rust/Brown Color Effect
ctx.globalCompositeOperation = 'multiply';
ctx.fillStyle = `rgba(180, 80, 30, ${intensity})`; // Rusty orange
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeOperation = 'overlay';
ctx.fillStyle = `rgba(139, 69, 19, ${intensity * 0.8})`; // Deep saddle brown
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeOperation = 'source-over';
// 4. Generate Procedural Rust/Grime Texture Layer
const noiseCanvas = document.createElement('canvas');
noiseCanvas.width = 100;
noiseCanvas.height = 100;
const nCtx = noiseCanvas.getContext('2d');
const nData = nCtx.createImageData(100, 100);
for (let i = 0; i < nData.data.length; i += 4) {
nData.data[i] = 139; // R
nData.data[i+1] = 69; // G
nData.data[i+2] = 19; // B
nData.data[i+3] = Math.random() * 150 * intensity; // Random alpha for gritty look
}
nCtx.putImageData(nData, 0, 0);
ctx.globalCompositeOperation = 'overlay';
const pattern = ctx.createPattern(noiseCanvas, 'repeat');
if (pattern) {
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, width, height);
}
ctx.globalCompositeOperation = 'source-over';
// Proportional scaling for drawn features
const scale = Math.min(width, height) / 500;
// 5. Draw Mater's Windshield & Eyes at the top
ctx.save();
ctx.translate(width * 0.5, 0);
ctx.scale(scale, scale);
// Windshield frame
ctx.fillStyle = '#6E3A07';
ctx.beginPath();
ctx.moveTo(-150, 0);
ctx.lineTo(150, 0);
ctx.lineTo(170, 120);
ctx.lineTo(-170, 120);
ctx.fill();
// Glass
ctx.fillStyle = '#87CEEB';
ctx.beginPath();
ctx.moveTo(-140, 0);
ctx.lineTo(-15, 0);
ctx.lineTo(-15, 95);
ctx.lineTo(-155, 95);
ctx.fill();
ctx.beginPath();
ctx.moveTo(15, 0);
ctx.lineTo(140, 0);
ctx.lineTo(155, 95);
ctx.lineTo(15, 95);
ctx.fill();
// Eyelids (sleepy/rusty look)
ctx.fillStyle = '#9b5b22';
ctx.beginPath();
ctx.moveTo(-140, 0);
ctx.lineTo(-15, 0);
ctx.lineTo(-15, 30);
ctx.lineTo(-150, 40);
ctx.fill();
ctx.beginPath();
ctx.moveTo(15, 0);
ctx.lineTo(140, 0);
ctx.lineTo(150, 40);
ctx.lineTo(15, 30);
ctx.fill();
// Eyes
function drawEye(x, y) {
// White part
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(x, y, 28, 0, Math.PI * 2);
ctx.fill();
// Green Iris
ctx.fillStyle = '#556B2F';
ctx.beginPath();
ctx.arc(x, y, 14, 0, Math.PI * 2);
ctx.fill();
// Pupil
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(x, y, 7, 0, Math.PI * 2);
ctx.fill();
}
drawEye(-60, 60);
drawEye(60, 60);
ctx.restore();
// 6. Draw Tow Hook hanging down from the left
ctx.save();
ctx.translate(width * 0.1, 0);
ctx.scale(scale, scale);
// Cable
ctx.strokeStyle = '#222';
ctx.lineWidth = 12;
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, 250);
ctx.stroke();
// Hook body
ctx.strokeStyle = '#333';
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.lineWidth = 18;
ctx.beginPath();
ctx.moveTo(0, 250);
ctx.lineTo(0, 290);
ctx.bezierCurveTo(50, 320, 80, 260, 40, 230);
ctx.stroke();
// Hook TIP
ctx.lineWidth = 8;
ctx.beginPath();
ctx.moveTo(40, 230);
ctx.lineTo(20, 248);
ctx.stroke();
ctx.restore();
// 7. Draw Buck Teeth at the bottom
ctx.save();
ctx.translate(width * 0.5, height);
ctx.scale(scale, scale);
ctx.fillStyle = '#e8e8d8'; // slightly yellowed white
ctx.strokeStyle = '#222';
ctx.lineWidth = 5;
// Left tooth
ctx.rotate(-0.06);
ctx.fillRect(-45, -100, 40, 100);
ctx.strokeRect(-45, -100, 40, 100);
ctx.rotate(0.06);
// Right tooth
ctx.rotate(0.1);
ctx.fillRect(10, -90, 35, 90);
ctx.strokeRect(10, -90, 35, 90);
ctx.restore();
// 8. Add Meme Overlay Text (Major)
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.font = `900 ${scale * 80}px Impact, sans-serif`;
ctx.lineWidth = scale * 8;
ctx.strokeStyle = 'black';
ctx.fillStyle = 'white';
if (textTop) {
ctx.strokeText(textTop, width / 2, scale * 170);
ctx.fillText(textTop, width / 2, scale * 170);
}
if (textBottom) {
// Draw slightly above the teeth
ctx.strokeText(textBottom, width / 2, height - (scale * 140));
ctx.fillText(textBottom, width / 2, height - (scale * 140));
}
return canvas;
}
Apply Changes