You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg,
mainFrameColor = '#00FFFF', // string: Color for the main frame elements (L-shapes)
secondaryFrameColor = '#FF00FF', // string: Color for secondary frame elements (parallel lines, mid-side markers)
mainGlowColor = '#00FFFF', // string: Glow color for main frame elements
secondaryGlowColor = '#FF00FF', // string: Glow color for secondary frame elements
mainGlowBlur = 10, // number: Blur radius for main glow effect
secondaryGlowBlur = 7, // number: Blur radius for secondary glow effect
mainLineWidth = 3, // number: Line width for main frame elements
secondaryLineWidth = 1, // number: Line width for secondary frame elements
framePadding = 60, // number: Total padding around the image to accommodate the frame and glow
cornerArmLength = 30, // number: Length of the arms of the L-shaped corner elements
frameImageOffset = 8, // number: Gap between the image edge and the vertex of the L-shapes
parallelLineGap = 4, // number: Clear space between main L-arms and secondary parallel lines
midSideMarkerLength = 15 // number: Length of the decorative markers on the middle of each side
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const imgW = originalImg.width;
const imgH = originalImg.height;
// Set canvas dimensions based on image size and padding
canvas.width = imgW + 2 * framePadding;
canvas.height = imgH + 2 * framePadding;
// Draw the original image centered on the canvas
const imgX = framePadding; // X-coordinate of top-left corner of the image
const imgY = framePadding; // Y-coordinate of top-left corner of the image
ctx.drawImage(originalImg, imgX, imgY, imgW, imgH);
// Calculate L-shape vertex points (where the two arms of an L meet)
// These points are 'frameImageOffset' distance away from the image corners
const TL_v = { x: imgX - frameImageOffset, y: imgY - frameImageOffset };
const TR_v = { x: imgX + imgW + frameImageOffset, y: imgY - frameImageOffset };
const BL_v = { x: imgX - frameImageOffset, y: imgY + imgH + frameImageOffset };
const BR_v = { x: imgX + imgW + frameImageOffset, y: imgY + imgH + frameImageOffset };
// --- Draw Main Frame Elements (L-shapes at corners) ---
ctx.strokeStyle = mainFrameColor;
ctx.lineWidth = mainLineWidth;
ctx.shadowColor = mainGlowColor;
ctx.shadowBlur = mainGlowBlur;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Top-Left L-shape
ctx.beginPath();
ctx.moveTo(TL_v.x - cornerArmLength, TL_v.y); // Outer end of horizontal arm
ctx.lineTo(TL_v.x, TL_v.y); // Vertex
ctx.lineTo(TL_v.x, TL_v.y - cornerArmLength); // Outer end of vertical arm
ctx.stroke();
// Top-Right L-shape
ctx.beginPath();
ctx.moveTo(TR_v.x + cornerArmLength, TR_v.y);
ctx.lineTo(TR_v.x, TR_v.y);
ctx.lineTo(TR_v.x, TR_v.y - cornerArmLength);
ctx.stroke();
// Bottom-Left L-shape
ctx.beginPath();
ctx.moveTo(BL_v.x - cornerArmLength, BL_v.y);
ctx.lineTo(BL_v.x, BL_v.y);
ctx.lineTo(BL_v.x, BL_v.y + cornerArmLength);
ctx.stroke();
// Bottom-Right L-shape
ctx.beginPath();
ctx.moveTo(BR_v.x + cornerArmLength, BR_v.y);
ctx.lineTo(BR_v.x, BR_v.y);
ctx.lineTo(BR_v.x, BR_v.y + cornerArmLength);
ctx.stroke();
// --- Draw Secondary Frame Elements (parallel lines to L-shapes) ---
ctx.strokeStyle = secondaryFrameColor;
ctx.lineWidth = secondaryLineWidth;
ctx.shadowColor = secondaryGlowColor;
ctx.shadowBlur = secondaryGlowBlur;
// Calculate offset for parallel lines:
// This is the distance from the centerline of the main L-arm to the centerline of the parallel secondary line.
const actualParallelOffset = (mainLineWidth / 2) + parallelLineGap + (secondaryLineWidth / 2);
// Top-Left parallel lines (outer)
ctx.beginPath(); // Parallel to horizontal arm
ctx.moveTo(TL_v.x - cornerArmLength, TL_v.y - actualParallelOffset);
ctx.lineTo(TL_v.x - (secondaryLineWidth/2) , TL_v.y - actualParallelOffset); // Adjusted to not overlap vertex visually with vertical parallel
ctx.stroke();
ctx.beginPath(); // Parallel to vertical arm
ctx.moveTo(TL_v.x - actualParallelOffset, TL_v.y - cornerArmLength);
ctx.lineTo(TL_v.x - actualParallelOffset, TL_v.y - (secondaryLineWidth/2)); // Adjusted
ctx.stroke();
// Top-Right parallel lines (outer)
ctx.beginPath(); // Parallel to horizontal arm
ctx.moveTo(TR_v.x + cornerArmLength, TR_v.y - actualParallelOffset);
ctx.lineTo(TR_v.x + (secondaryLineWidth/2), TR_v.y - actualParallelOffset); // Adjusted
ctx.stroke();
ctx.beginPath(); // Parallel to vertical arm
ctx.moveTo(TR_v.x + actualParallelOffset, TR_v.y - cornerArmLength);
ctx.lineTo(TR_v.x + actualParallelOffset, TR_v.y - (secondaryLineWidth/2)); // Adjusted
ctx.stroke();
// Bottom-Left parallel lines (outer)
ctx.beginPath(); // Parallel to horizontal arm
ctx.moveTo(BL_v.x - cornerArmLength, BL_v.y + actualParallelOffset);
ctx.lineTo(BL_v.x - (secondaryLineWidth/2), BL_v.y + actualParallelOffset); // Adjusted
ctx.stroke();
ctx.beginPath(); // Parallel to vertical arm
ctx.moveTo(BL_v.x - actualParallelOffset, BL_v.y + cornerArmLength);
ctx.lineTo(BL_v.x - actualParallelOffset, BL_v.y + (secondaryLineWidth/2)); // Adjusted
ctx.stroke();
// Bottom-Right parallel lines (outer)
ctx.beginPath(); // Parallel to horizontal arm
ctx.moveTo(BR_v.x + cornerArmLength, BR_v.y + actualParallelOffset);
ctx.lineTo(BR_v.x + (secondaryLineWidth/2), BR_v.y + actualParallelOffset); // Adjusted
ctx.stroke();
ctx.beginPath(); // Parallel to vertical arm
ctx.moveTo(BR_v.x + actualParallelOffset, BR_v.y + cornerArmLength);
ctx.lineTo(BR_v.x + actualParallelOffset, BR_v.y + (secondaryLineWidth/2)); // Adjusted
ctx.stroke();
// --- Draw Mid-Side Markers ---
// (Still using secondaryFrameColor, secondaryLineWidth, secondaryGlowColor, secondaryGlowBlur)
const markerGap = secondaryLineWidth * 2; // Gap between the two small lines of a marker
// Mid-Top Marker (two horizontal lines)
const MTP_y = imgY - frameImageOffset;
const MTP_x = imgX + imgW / 2;
ctx.beginPath();
ctx.moveTo(MTP_x - midSideMarkerLength / 2, MTP_y - markerGap / 2);
ctx.lineTo(MTP_x + midSideMarkerLength / 2, MTP_y - markerGap / 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(MTP_x - midSideMarkerLength / 2, MTP_y + markerGap / 2);
ctx.lineTo(MTP_x + midSideMarkerLength / 2, MTP_y + markerGap / 2);
ctx.stroke();
// Mid-Bottom Marker
const MBP_y = imgY + imgH + frameImageOffset;
const MBP_x = imgX + imgW / 2;
ctx.beginPath();
ctx.moveTo(MBP_x - midSideMarkerLength / 2, MBP_y - markerGap / 2);
ctx.lineTo(MBP_x + midSideMarkerLength / 2, MBP_y - markerGap / 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(MBP_x - midSideMarkerLength / 2, MBP_y + markerGap / 2);
ctx.lineTo(MBP_x + midSideMarkerLength / 2, MBP_y + markerGap / 2);
ctx.stroke();
// Mid-Left Marker (two vertical lines)
const MLP_x = imgX - frameImageOffset;
const MLP_y = imgY + imgH / 2;
ctx.beginPath();
ctx.moveTo(MLP_x - markerGap / 2, MLP_y - midSideMarkerLength / 2);
ctx.lineTo(MLP_x - markerGap / 2, MLP_y + midSideMarkerLength / 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(MLP_x + markerGap / 2, MLP_y - midSideMarkerLength / 2);
ctx.lineTo(MLP_x + markerGap / 2, MLP_y + midSideMarkerLength / 2);
ctx.stroke();
// Mid-Right Marker
const MRP_x = imgX + imgW + frameImageOffset;
const MRP_y = imgY + imgH / 2;
ctx.beginPath();
ctx.moveTo(MRP_x - markerGap / 2, MRP_y - midSideMarkerLength / 2);
ctx.lineTo(MRP_x - markerGap / 2, MRP_y + midSideMarkerLength / 2);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(MRP_x + markerGap / 2, MRP_y - midSideMarkerLength / 2);
ctx.lineTo(MRP_x + markerGap / 2, MRP_y + midSideMarkerLength / 2);
ctx.stroke();
// Reset shadow settings
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
return canvas;
}
Apply Changes