You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, titleText = "КНИГА БУДУЩЕГО", themeColorRGB = "0, 255, 255", dataReadout = "STATUS: SYNCHRONIZED") {
// 1. Setup Canvas and Fonts
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1100;
canvas.height = 900;
// Load futuristic font
const fontName = 'Orbitron';
try {
const link = document.createElement("link");
link.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@400;700&display=swap`;
link.rel = "stylesheet";
document.head.appendChild(link);
await document.fonts.load(`16px "${fontName}"`);
await document.fonts.load(`bold 40px "${fontName}"`);
} catch (e) {
console.warn("Font loading skipped or failed. Using fallback.");
}
const fontFamily = `"${fontName}", sans-serif`;
// 2. Draw Futuristic Background
// Deep dark blue radial gradient
const bgGrad = ctx.createRadialGradient(canvas.width / 2, canvas.height / 2, 100, canvas.width / 2, canvas.height / 2, 800);
bgGrad.addColorStop(0, '#0a1128');
bgGrad.addColorStop(1, '#02050f');
ctx.fillStyle = bgGrad;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw perspective floor grid
const cx = canvas.width / 2;
const cy = canvas.height / 2 - 50;
ctx.strokeStyle = `rgba(${themeColorRGB}, 0.15)`;
ctx.lineWidth = 1;
// Floor mask: only draw grid on lower half
ctx.save();
ctx.beginPath();
ctx.rect(0, cy + 50, canvas.width, canvas.height);
ctx.clip();
ctx.beginPath();
// Radiant perspective lines
for (let x = -2000; x <= 3000; x += 150) {
ctx.moveTo(cx, cy);
ctx.lineTo(x, canvas.height);
}
// Horizontal perspective lines
for (let y = cy + 50; y <= canvas.height;) {
ctx.moveTo(0, y);
ctx.lineTo(canvas.width, y);
y += (y - cy) * 0.12; // exponential spacing for 3D effect
}
ctx.stroke();
ctx.restore();
// 3. Prepare the Holograph Book Texture (Offscreen Canvas)
const texCanvas = document.createElement('canvas');
const tCtx = texCanvas.getContext('2d');
const bookW = 800;
const bookH = 480;
texCanvas.width = bookW;
texCanvas.height = bookH;
// Cover scale original image into the book texture
const scale = Math.max(bookW / originalImg.width, bookH / originalImg.height);
const cw = originalImg.width * scale;
const ch = originalImg.height * scale;
const icx = (bookW - cw) / 2;
const icy = (bookH - ch) / 2;
tCtx.drawImage(originalImg, icx, icy, cw, ch);
// Filter to look like a hologram
tCtx.fillStyle = `rgba(${themeColorRGB}, 0.25)`;
tCtx.globalCompositeOperation = 'color';
tCtx.fillRect(0, 0, bookW, bookH);
tCtx.globalCompositeOperation = 'source-over';
// Add holographic scanlines to texture
tCtx.fillStyle = 'rgba(0, 0, 0, 0.4)';
for (let i = 0; i < bookH; i += 4) {
tCtx.fillRect(0, i, bookW, 1.5);
}
// Add UI/Tech elements directly onto the book texture
tCtx.strokeStyle = `rgba(${themeColorRGB}, 0.9)`;
tCtx.lineWidth = 2;
// Page Borders
tCtx.strokeRect(15, 15, bookW / 2 - 30, bookH - 30);
tCtx.strokeRect(bookW / 2 + 15, 15, bookW / 2 - 30, bookH - 30);
// Spine line
tCtx.beginPath();
tCtx.moveTo(bookW / 2, 0);
tCtx.lineTo(bookW / 2, bookH);
tCtx.stroke();
// Tech circle on left page
tCtx.beginPath();
tCtx.arc(bookW / 4, bookH / 2, 80, 0, Math.PI * 2);
tCtx.stroke();
tCtx.beginPath();
tCtx.arc(bookW / 4, bookH / 2, 60, 0, Math.PI * 2);
tCtx.setLineDash([10, 10]);
tCtx.stroke();
tCtx.setLineDash([]);
// Data bars on right page
tCtx.fillStyle = `rgba(255, 255, 255, 0.6)`;
for (let i = 0; i < 15; i++) {
let barW = Math.random() * 120 + 20;
tCtx.fillRect(bookW * 0.75 - 60, bookH / 2 - 90 + i * 12, barW, 4);
}
// 4. Draw Projector Base and Hologram Beam (Main Canvas)
const projectorY = 780;
// Base Rings
ctx.fillStyle = '#0f1426';
ctx.strokeStyle = `rgba(${themeColorRGB}, 0.8)`;
ctx.lineWidth = 4;
ctx.beginPath();
ctx.ellipse(cx, projectorY, 240, 35, 0, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.ellipse(cx, projectorY - 10, 200, 25, 0, 0, Math.PI * 2);
ctx.fillStyle = '#17203a';
ctx.fill();
ctx.stroke();
// Light emitting core
ctx.beginPath();
ctx.ellipse(cx, projectorY - 15, 120, 15, 0, 0, Math.PI * 2);
ctx.fillStyle = `rgba(${themeColorRGB}, 0.6)`;
ctx.fill();
ctx.shadowColor = `rgb(${themeColorRGB})`;
ctx.shadowBlur = 30;
ctx.fill();
ctx.shadowBlur = 0;
// Beam
const startX = (canvas.width - bookW) / 2;
const startY = 180;
ctx.globalCompositeOperation = 'screen';
const beamGrad = ctx.createLinearGradient(0, projectorY - 15, 0, startY + bookH - 50);
beamGrad.addColorStop(0, `rgba(${themeColorRGB}, 0.7)`);
beamGrad.addColorStop(1, `rgba(${themeColorRGB}, 0.0)`);
ctx.fillStyle = beamGrad;
ctx.beginPath();
ctx.moveTo(cx - 120, projectorY - 15);
ctx.lineTo(cx + 120, projectorY - 15);
ctx.lineTo(cx + bookW / 2 + 80, startY + bookH + 20);
ctx.lineTo(cx - bookW / 2 - 80, startY + bookH + 20);
ctx.fill();
ctx.globalCompositeOperation = 'source-over';
// 5. Render curved 3D Holographic Book
const bookCanvas = document.createElement('canvas');
bookCanvas.width = canvas.width;
bookCanvas.height = canvas.height;
const bCtx = bookCanvas.getContext('2d');
// Drawing multiple layers for 3D thickness effect
const layers = 15;
for (let thick = layers; thick >= 0; thick--) {
const isTopLayer = (thick === 0);
bCtx.globalAlpha = isTopLayer ? 1.0 : 0.06;
for (let x = 0; x < bookW; x++) { // 1px slices for curve
let t = (x < bookW / 2) ? (x / (bookW / 2)) : ((bookW - x) / (bookW / 2));
// Curve Math: Bulges up in the middle of pages, drops towards the spine
const bulge = 55;
const drop = 40;
const yOffset = -bulge * Math.sin(t * Math.PI) + drop * t;
bCtx.drawImage(
texCanvas,
x, 0, 1, bookH,
startX + x, startY + yOffset + thick * 1.5, 1, bookH
);
}
}
// Apply the curved 3D book onto the main canvas with localized glow
ctx.shadowColor = `rgb(${themeColorRGB})`;
ctx.shadowBlur = 40;
ctx.drawImage(bookCanvas, 0, 0);
ctx.shadowBlur = 0; // Reset
// 6. Floating Tech Particles
ctx.fillStyle = `rgb(${themeColorRGB})`;
for (let i = 0; i < 40; i++) {
const px = Math.random() * canvas.width;
const py = Math.random() * (canvas.height - 150);
const radius = Math.random() * 2 + 1;
ctx.globalAlpha = Math.random() * 0.8 + 0.2;
ctx.beginPath();
ctx.arc(px, py, radius, 0, Math.PI * 2);
ctx.fill();
}
ctx.globalAlpha = 1.0;
// 7. Add UI Overlays and Text
ctx.fillStyle = `rgb(${themeColorRGB})`;
ctx.font = `bold 42px ${fontFamily}`;
ctx.textAlign = 'center';
// Main Title Hologram above the book
ctx.shadowColor = `rgb(${themeColorRGB})`;
ctx.shadowBlur = 20;
ctx.fillText(titleText, cx, 90);
// Subtext stats
ctx.shadowBlur = 0;
ctx.font = `18px ${fontFamily}`;
ctx.textAlign = 'left';
ctx.fillText("HOLO-SYS // V.9.4.2", 40, 50);
ctx.fillText(dataReadout, 40, 80);
// Tech lines around top UI
ctx.strokeStyle = `rgba(${themeColorRGB}, 0.7)`;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(30, 20);
ctx.lineTo(150, 20);
ctx.lineTo(165, 35);
ctx.lineTo(280, 35);
ctx.stroke();
ctx.textAlign = 'right';
const hexHash = Math.random().toString(16).substring(2, 10).toUpperCase();
ctx.fillText(`ID: ${hexHash}`, canvas.width - 40, 50);
ctx.fillText("UPLINK: STABLE", canvas.width - 40, 80);
ctx.beginPath();
ctx.moveTo(canvas.width - 30, 20);
ctx.lineTo(canvas.width - 150, 20);
ctx.lineTo(canvas.width - 165, 35);
ctx.lineTo(canvas.width - 280, 35);
ctx.stroke();
// 8. Final Global Vintage/Tech Scanlines overlay
ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
for (let y = 0; y < canvas.height; y += 3) {
ctx.fillRect(0, y, canvas.width, 1);
}
return canvas;
}
Apply Changes