You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, text = "FRIENDS", position = "bottom", fontSizeRatio = 0.15, addVintageFilter = 1) {
const canvas = document.createElement('canvas');
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Draw the original image
ctx.drawImage(originalImg, 0, 0, width, height);
// Apply a subtle warm, vintage 90s filter to enhance the "Friends" aesthetic
if (Number(addVintageFilter) === 1) {
// Warm overall tint
ctx.fillStyle = "rgba(255, 165, 0, 0.08)";
ctx.fillRect(0, 0, width, height);
// Increase contrast slightly using composite operations
ctx.globalCompositeOperation = 'overlay';
ctx.fillStyle = "rgba(128, 128, 128, 0.2)";
ctx.fillRect(0, 0, width, height);
ctx.globalCompositeOperation = 'source-over';
}
// Format text
const displayText = String(text).toUpperCase();
const fontSize = height * Number(fontSizeRatio);
ctx.font = `bold ${fontSize}px "Arial Black", Impact, sans-serif`;
ctx.textBaseline = "alphabetic";
// Classic Friends logo dot colors: Red, Blue, Yellow
const dotColors = ['#ff4238', '#42a2d6', '#ffce45'];
// Spacing and sizing for the dots between letters
const gap = fontSize * 0.45;
const dotRadius = fontSize * 0.08;
// Calculate total layout width for centering
let totalWidth = 0;
for (let i = 0; i < displayText.length; i++) {
totalWidth += ctx.measureText(displayText[i]).width;
if (i < displayText.length - 1) {
// Widen gap and skip dots for spaces
if (displayText[i] === ' ' || displayText[i+1] === ' ') {
totalWidth += gap * 1.5;
} else {
totalWidth += gap;
}
}
}
// Determine Y position
const padding = fontSize * 0.5;
let startY;
if (position === "top") {
startY = fontSize + padding;
} else if (position === "center") {
startY = (height + fontSize * 0.7) / 2;
} else { // "bottom" is the default
startY = height - padding;
}
let startX = (width - totalWidth) / 2;
// Setup text shadow to ensure visibility over any image background
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = fontSize * 0.08;
ctx.shadowOffsetX = fontSize * 0.02;
ctx.shadowOffsetY = fontSize * 0.02;
let currentX = startX;
let colorIndex = 0;
// Draw the letters and the colored dots
for (let i = 0; i < displayText.length; i++) {
const char = displayText[i];
const charWidth = ctx.measureText(char).width;
// Draw character
ctx.fillStyle = "white";
ctx.fillText(char, currentX, startY);
currentX += charWidth;
// Draw dot if it's not the last character
if (i < displayText.length - 1) {
const nextChar = displayText[i + 1];
// Adjust gap if there are spaces without drawing a dot
if (char === ' ' || nextChar === ' ') {
currentX += gap * 1.5;
} else {
currentX += gap / 2; // move to center of the gap
// Slightly softer shadow for the colored dots
ctx.shadowColor = 'rgba(0, 0, 0, 0.6)';
ctx.shadowBlur = fontSize * 0.05;
ctx.beginPath();
// Position dots slightly below the vertical middle of the text
ctx.arc(currentX, startY - (fontSize * 0.4), dotRadius, 0, Math.PI * 2);
ctx.fillStyle = dotColors[colorIndex % dotColors.length];
ctx.fill();
colorIndex++;
currentX += gap / 2; // move past the gap
// Restore primary text shadow for the next letter
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = fontSize * 0.08;
}
}
}
return canvas;
}
Apply Changes