You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, title = "ЗОЛОТАЯ КАРТА", subtitle = "VIP MEMBER", rating = "99") {
// Canvas setup
const canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 850;
const ctx = canvas.getContext('2d');
// Helper functions
function drawRoundRect(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
function createGoldGradient(x1, y1, x2, y2) {
let g = ctx.createLinearGradient(x1, y1, x2, y2);
g.addColorStop(0, '#BF953F');
g.addColorStop(0.25, '#FCF6BA');
g.addColorStop(0.5, '#B38728');
g.addColorStop(0.75, '#FBF5B7');
g.addColorStop(1, '#AA771C');
return g;
}
// Clip entire canvas to rounded corners
drawRoundRect(0, 0, canvas.width, canvas.height, 25);
ctx.clip();
// 1. Base Gold Gradient
const bgGrad = createGoldGradient(0, 0, canvas.width, canvas.height);
ctx.fillStyle = bgGrad;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. Vignette (Dark borders for depth)
const vignette = ctx.createRadialGradient(
canvas.width / 2, canvas.height / 2, 100,
canvas.width / 2, canvas.height / 2, 700
);
vignette.addColorStop(0, 'rgba(0,0,0,0)');
vignette.addColorStop(1, 'rgba(60,40,0,0.6)');
ctx.fillStyle = vignette;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 3. Background Sunburst/Rays
ctx.save();
ctx.translate(canvas.width / 2, 340);
ctx.fillStyle = 'rgba(255, 255, 255, 0.12)';
for (let i = 0; i < 36; i++) {
ctx.rotate(Math.PI / 18);
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(800, -12);
ctx.lineTo(800, 12);
ctx.fill();
}
ctx.restore();
// 4. Main Image Frame and Drawing
const imgW = 440;
const imgH = 440;
const imgX = 80;
const imgY = 110;
// Save state, clip area for image
ctx.save();
drawRoundRect(imgX, imgY, imgW, imgH, 20);
ctx.clip();
// Draw object-fit: cover image
const scale = Math.max(imgW / originalImg.width, imgH / originalImg.height);
const w = originalImg.width * scale;
const h = originalImg.height * scale;
const dx = imgX + (imgW - w) / 2;
const dy = imgY + (imgH - h) / 2;
ctx.drawImage(originalImg, dx, dy, w, h);
ctx.restore();
// Draw image border
drawRoundRect(imgX, imgY, imgW, imgH, 20);
ctx.lineWidth = 6;
ctx.strokeStyle = createGoldGradient(imgX, imgY, imgX + imgW, imgY + imgH);
ctx.stroke();
// 5. Title text
ctx.font = 'bold 38px Georgia, serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#ffffff';
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = 8;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.fillText(title, canvas.width / 2, 60, canvas.width - 100);
ctx.shadowColor = 'transparent'; // Reset shadow
// 6. Rating Shield (Top-Left intersecting Image)
const sx = 40, sy = 90, sw = 100, sh = 120;
ctx.beginPath();
ctx.moveTo(sx + sw / 2, sy);
ctx.lineTo(sx + sw, sy);
ctx.lineTo(sx + sw, sy + sh * 0.5);
ctx.bezierCurveTo(sx + sw, sy + sh * 0.8, sx + sw / 2, sy + sh, sx + sw / 2, sy + sh);
ctx.bezierCurveTo(sx + sw / 2, sy + sh, sx, sy + sh * 0.8, sx, sy + sh * 0.5);
ctx.lineTo(sx, sy);
ctx.closePath();
ctx.fillStyle = '#1A1A1A';
ctx.fill();
ctx.lineWidth = 4;
ctx.strokeStyle = createGoldGradient(sx, sy, sx + sw, sy + sh);
ctx.stroke();
// Rating Text inside Shield
ctx.fillStyle = createGoldGradient(sx, sy + 20, sx, sy + 80);
ctx.font = 'bold 45px Georgia, serif';
ctx.fillText(rating, sx + sw / 2, sy + 50, sw - 10);
ctx.font = 'bold 13px Georgia, serif';
ctx.fillStyle = '#FFF';
ctx.fillText("RATING", sx + sw / 2, sy + 90);
// 7. Subtitle Banner below the image
const by = 575;
const bh = 55;
const bannerGrad = ctx.createLinearGradient(imgX, by, imgX + imgW, by);
bannerGrad.addColorStop(0, '#111');
bannerGrad.addColorStop(0.5, '#333');
bannerGrad.addColorStop(1, '#111');
ctx.fillStyle = bannerGrad;
drawRoundRect(imgX, by, imgW, bh, 10);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = createGoldGradient(imgX, by, imgX + imgW, by + bh);
ctx.stroke();
ctx.fillStyle = ctx.strokeStyle; // use gold gradient for text
ctx.font = 'bold 26px Georgia, serif';
ctx.fillText(subtitle, canvas.width / 2, by + bh / 2 + 2, imgW - 40);
// 8. 5 Stars Decoration
function drawStar(cx, cy, spikes, outerRadius, innerRadius) {
let rot = Math.PI / 2 * 3;
let x = cx, y = cy;
let step = Math.PI / spikes;
ctx.beginPath();
ctx.moveTo(cx, cy - outerRadius);
for (let i = 0; i < spikes; i++) {
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
ctx.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
ctx.lineTo(x, y);
rot += step;
}
ctx.lineTo(cx, cy - outerRadius);
ctx.closePath();
ctx.fill();
}
ctx.fillStyle = bgGrad;
const starY = 660;
for (let i = -2; i <= 2; i++) {
drawStar(canvas.width / 2 + (i * 40), starY, 5, 12, 5);
}
// 9. Card Stats / Labels
ctx.fillStyle = '#1A1A1A';
ctx.font = 'bold 22px Georgia, serif';
// Line 1
ctx.textAlign = 'left';
ctx.fillText("STATUS:", 150, 725);
ctx.textAlign = 'right';
ctx.fillText("ACTIVATED", 450, 725);
// Divider
ctx.beginPath();
ctx.moveTo(140, 745);
ctx.lineTo(460, 745);
ctx.strokeStyle = 'rgba(0,0,0,0.2)';
ctx.lineWidth = 1;
ctx.stroke();
// Line 2
ctx.textAlign = 'left';
ctx.fillText("VALIDITY:", 150, 775);
ctx.textAlign = 'right';
ctx.fillText("LIFETIME", 450, 775);
// 10. Outer and inner border lines over everything
ctx.lineWidth = 16;
ctx.strokeStyle = createGoldGradient(0, 0, canvas.width, 0);
drawRoundRect(8, 8, canvas.width - 16, canvas.height - 16, 20);
ctx.stroke();
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(255,255,255,0.7)';
drawRoundRect(24, 24, canvas.width - 48, canvas.height - 48, 12);
ctx.stroke();
return canvas;
}
Apply Changes