You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, trackName = 'Awesome Song', artistName = 'Great Artist', trackTime = 180, playedTime = 60, barColor = '#FFFFFF', fontColor = '#FFFFFF', backgroundColor = 'rgba(0, 0, 0, 0.5)') {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
// 1. Draw the original image as the background
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 2. Draw a semi-transparent overlay
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// --- Helper Functions ---
/**
* Formats seconds into a mm:ss string.
* @param {number} totalSeconds - The total seconds to format.
* @returns {string} The formatted time string.
*/
const formatTime = (totalSeconds) => {
const minutes = Math.floor(totalSeconds / 60);
const seconds = Math.floor(totalSeconds % 60);
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
};
/**
* Draws a play button (triangle pointing right).
* @param {CanvasRenderingContext2D} ctx - The canvas context.
* @param {number} x - The center x-coordinate.
* @param {number} y - The center y-coordinate.
* @param {number} size - The height of the triangle.
*/
const drawPlay = (ctx, x, y, size) => {
const width = size * 0.866; // approx Math.sqrt(3)/2 for equilateral look
ctx.beginPath();
ctx.moveTo(x - width / 2, y - size / 2);
ctx.lineTo(x + width / 2, y);
ctx.lineTo(x - width / 2, y + size / 2);
ctx.closePath();
ctx.fill();
};
/**
* Draws a "next track" icon.
* @param {CanvasRenderingContext2D} ctx - The canvas context.
* @param {number} x - The center x-coordinate.
* @param {number} y - The center y-coordinate.
* @param {number} size - The width and height of the icon.
*/
const drawNext = (ctx, x, y, size) => {
const barWidth = size * 0.15;
const spacing = size * 0.05;
const triangleWidth = size * 0.5;
// Bar on the right
ctx.fillRect(x + size / 2 - barWidth, y - size / 2, barWidth, size);
// Triangle on the left
const triX1 = x - size / 2 + spacing;
const triX2 = triX1 + triangleWidth;
ctx.beginPath();
ctx.moveTo(triX1, y - size / 2);
ctx.lineTo(triX2, y);
ctx.lineTo(triX1, y + size / 2);
ctx.closePath();
ctx.fill();
};
/**
* Draws a "previous track" icon.
* @param {CanvasRenderingContext2D} ctx - The canvas context.
* @param {number} x - The center x-coordinate.
* @param {number} y - The center y-coordinate.
* @param {number} size - The width and height of the icon.
*/
const drawPrevious = (ctx, x, y, size) => {
const barWidth = size * 0.15;
const spacing = size * 0.05;
const triangleWidth = size * 0.5;
// Bar on the left
ctx.fillRect(x - size / 2, y - size / 2, barWidth, size);
// Triangle on the right
const triX2 = x + size / 2 - spacing;
const triX1 = triX2 - triangleWidth;
ctx.beginPath();
ctx.moveTo(triX2, y - size / 2);
ctx.lineTo(triX1, y);
ctx.lineTo(triX2, y + size / 2);
ctx.closePath();
ctx.fill();
};
// --- Layout and Sizing Calculations ---
const w = canvas.width;
const h = canvas.height;
const baseSize = Math.min(w, h); // Use the smaller dimension for relative sizing
const sideMargin = w * 0.1;
// Vertical positions from bottom up
const y_controls = h * 0.9;
const y_progressBar = h * 0.82;
const y_artistName = h * 0.75;
const y_trackName = h * 0.68;
// --- Draw UI Elements ---
ctx.fillStyle = fontColor;
ctx.strokeStyle = fontColor;
// 3. Draw Track and Artist Names
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
const trackFontSize = baseSize * 0.07;
ctx.font = `bold ${trackFontSize}px system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif`;
ctx.fillText(trackName, w / 2, y_trackName);
const artistFontSize = baseSize * 0.05;
ctx.font = `${artistFontSize}px system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif`;
ctx.fillText(artistName, w / 2, y_artistName);
// 4. Draw Progress Bar and Timestamps
const barX = sideMargin;
const barWidth = w - 2 * sideMargin;
const barHeight = Math.max(2, baseSize * 0.008);
const progress = Math.max(0, Math.min(1, playedTime / trackTime));
// Bar background
ctx.globalAlpha = 0.4;
ctx.fillStyle = barColor;
ctx.fillRect(barX, y_progressBar - barHeight / 2, barWidth, barHeight);
ctx.globalAlpha = 1.0;
// Bar progress
ctx.fillRect(barX, y_progressBar - barHeight / 2, barWidth * progress, barHeight);
// Progress handle (circle)
const handleRadius = barHeight * 1.5;
ctx.beginPath();
ctx.arc(barX + barWidth * progress, y_progressBar, handleRadius, 0, 2 * Math.PI);
ctx.fill();
// Timestamps
const timeFontSize = baseSize * 0.035;
ctx.font = `${timeFontSize}px system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif`;
const timeY = y_progressBar + barHeight + timeFontSize * 0.8;
ctx.textAlign = 'left';
ctx.fillText(formatTime(playedTime), barX, timeY);
ctx.textAlign = 'right';
ctx.fillText(formatTime(trackTime), barX + barWidth, timeY);
// 5. Draw Player Controls
const controlSize = baseSize * 0.06;
const playControlSize = controlSize * 1.3;
const controlSpacing = baseSize * 0.15;
drawPrevious(ctx, w / 2 - controlSpacing, y_controls, controlSize);
drawPlay(ctx, w / 2, y_controls, playControlSize);
drawNext(ctx, w / 2 + controlSpacing, y_controls, controlSize);
return canvas;
}
Apply Changes