You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, boardWidth = 220, boardLength = 850, orientation = "vertical") {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d", { alpha: true });
// Determine dimensions based on orientation
const isHorizontal = orientation.toLowerCase().startsWith('h');
const boardW = isHorizontal ? boardLength : boardWidth;
const boardH = isHorizontal ? boardWidth : boardLength;
// Padding for drop shadow
const ox = 80;
const oy = 80;
canvas.width = boardW + ox * 2;
canvas.height = boardH + oy * 2;
// Helper function to draw the longboard shape (Cruiser/Pintail hybrid styling)
function drawBoardPath() {
ctx.beginPath();
if (!isHorizontal) {
// Top center
ctx.moveTo(ox + boardW / 2, oy);
// Top curve to Right
ctx.bezierCurveTo(ox + boardW * 0.85, oy, ox + boardW, oy + boardH * 0.05, ox + boardW, oy + boardH * 0.15);
// Right side (slight narrowing waist in the middle)
ctx.bezierCurveTo(ox + boardW * 0.94, oy + boardH * 0.5, ox + boardW * 0.94, oy + boardH * 0.5, ox + boardW, oy + boardH * 0.85);
// Bottom Right to Bottom Center
ctx.bezierCurveTo(ox + boardW, oy + boardH * 0.95, ox + boardW * 0.85, oy + boardH, ox + boardW / 2, oy + boardH);
// Bottom Center to Bottom Left
ctx.bezierCurveTo(ox + boardW * 0.15, oy + boardH, ox, oy + boardH * 0.95, ox, oy + boardH * 0.85);
// Left side
ctx.bezierCurveTo(ox + boardW * 0.06, oy + boardH * 0.5, ox + boardW * 0.06, oy + boardH * 0.5, ox, oy + boardH * 0.15);
// Top Left to Top Center
ctx.bezierCurveTo(ox, oy + boardH * 0.05, ox + boardW * 0.15, oy, ox + boardW / 2, oy);
} else {
// Left Center
ctx.moveTo(ox, oy + boardH / 2);
// Left curve to Top Edge
ctx.bezierCurveTo(ox, oy + boardH * 0.15, ox + boardW * 0.05, oy, ox + boardW * 0.15, oy);
// Top edge (slight narrowing waist)
ctx.bezierCurveTo(ox + boardW * 0.5, oy + boardH * 0.06, ox + boardW * 0.5, oy + boardH * 0.06, ox + boardW * 0.85, oy);
// Top Edge to Right Center
ctx.bezierCurveTo(ox + boardW * 0.95, oy, ox + boardW, oy + boardH * 0.15, ox + boardW, oy + boardH / 2);
// Right Center to Bottom Edge
ctx.bezierCurveTo(ox + boardW, oy + boardH * 0.85, ox + boardW * 0.95, oy + boardH, ox + boardW * 0.85, oy + boardH);
// Bottom edge
ctx.bezierCurveTo(ox + boardW * 0.5, oy + boardH * 0.94, ox + boardW * 0.5, oy + boardH * 0.94, ox + boardW * 0.15, oy + boardH);
// Bottom Edge to Left Center
ctx.bezierCurveTo(ox + boardW * 0.05, oy + boardH, ox, oy + boardH * 0.85, ox, oy + boardH / 2);
}
ctx.closePath();
}
// Draw the drop shadow of the real physical board
ctx.shadowColor = 'rgba(0, 0, 0, 0.45)';
ctx.shadowBlur = 25;
ctx.shadowOffsetX = 12;
ctx.shadowOffsetY = 18;
drawBoardPath();
ctx.fillStyle = '#fff';
ctx.fill();
// Reset shadow for subsequent drawing
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Clip the canvas to our longboard path to draw the graphic/image
ctx.save();
drawBoardPath();
ctx.clip();
// Calculate aspect fill ratio so the image covers the board area fully
const scale = Math.max(boardW / originalImg.width, boardH / originalImg.height);
const drawW = originalImg.width * scale;
const drawH = originalImg.height * scale;
const dx = ox + (boardW - drawW) / 2;
const dy = oy + (boardH - drawH) / 2;
// Draw the image onto the board
ctx.drawImage(originalImg, dx, dy, drawW, drawH);
// Draw a glossy tubular lighting gradient (simulates curve/reflection of a shiny deck)
const gradient = ctx.createLinearGradient(
ox, oy,
isHorizontal ? ox : ox + boardW,
isHorizontal ? oy + boardH : oy
);
gradient.addColorStop(0, 'rgba(255, 255, 255, 0.3)');
gradient.addColorStop(0.15, 'rgba(255, 255, 255, 0.05)');
gradient.addColorStop(0.5, 'rgba(0, 0, 0, 0.0)');
gradient.addColorStop(0.85, 'rgba(0, 0, 0, 0.1)');
gradient.addColorStop(1, 'rgba(0, 0, 0, 0.4)');
ctx.fillStyle = gradient;
ctx.fillRect(ox, oy, boardW, boardH);
ctx.restore();
// Draw the wooden deck rim and edge shadow
ctx.save();
drawBoardPath();
ctx.lineWidth = 6;
ctx.strokeStyle = '#cd9a5b'; // Light wood color
ctx.stroke();
// Inner thin semi-transparent shadow to give thickness depth
ctx.lineWidth = 2;
ctx.strokeStyle = 'rgba(0,0,0,0.4)';
ctx.stroke();
ctx.restore();
// Function to draw board truck mounting hardware (bolts)
function drawBolts() {
ctx.fillStyle = '#222';
const holeRadius = isHorizontal ? boardH * 0.015 : boardW * 0.015;
const drawHole = (x, y) => {
ctx.beginPath();
ctx.arc(ox + x, oy + y, holeRadius, 0, Math.PI * 2);
ctx.fill();
// Subtle highlight on bolt
ctx.fillStyle = "rgba(255,255,255,0.4)";
ctx.beginPath();
ctx.arc(ox + x - 1, oy + y - 1, holeRadius * 0.4, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#222';
};
if (!isHorizontal) {
const spacingX = boardW * 0.11;
const spacingY = boardH * 0.035;
const topY = boardH * 0.18;
const bottomY = boardH * 0.82;
// Top Truck
drawHole(boardW / 2 - spacingX, topY - spacingY);
drawHole(boardW / 2 + spacingX, topY - spacingY);
drawHole(boardW / 2 - spacingX, topY + spacingY);
drawHole(boardW / 2 + spacingX, topY + spacingY);
// Bottom Truck
drawHole(boardW / 2 - spacingX, bottomY - spacingY);
drawHole(boardW / 2 + spacingX, bottomY - spacingY);
drawHole(boardW / 2 - spacingX, bottomY + spacingY);
drawHole(boardW / 2 + spacingX, bottomY + spacingY);
} else {
const spacingX = boardW * 0.035;
const spacingY = boardH * 0.11;
const leftX = boardW * 0.18;
const rightX = boardW * 0.82;
// Left Truck
drawHole(leftX - spacingX, boardH / 2 - spacingY);
drawHole(leftX + spacingX, boardH / 2 - spacingY);
drawHole(leftX - spacingX, boardH / 2 + spacingY);
drawHole(leftX + spacingX, boardH / 2 + spacingY);
// Right Truck
drawHole(rightX - spacingX, boardH / 2 - spacingY);
drawHole(rightX + spacingX, boardH / 2 - spacingY);
drawHole(rightX - spacingX, boardH / 2 + spacingY);
drawHole(rightX + spacingX, boardH / 2 + spacingY);
}
}
drawBolts();
return canvas;
}
Apply Changes