You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, pathStyle = "diagonal", footprintCount = "10", footprintColor = "#2a1e12", opacity = "0.85") {
const canvas = document.createElement("canvas");
const w = canvas.width = originalImg.width;
const h = canvas.height = originalImg.height;
const ctx = canvas.getContext("2d");
// Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0);
// Parse and validate parameters
const count = Math.max(1, parseInt(footprintCount, 10) || 10);
const alpha = parseFloat(opacity);
ctx.fillStyle = footprintColor || "#2a1e12";
ctx.globalAlpha = isNaN(alpha) ? 0.85 : alpha;
// Add subtle shadow for depth to simulate actual tracks
ctx.shadowColor = "rgba(0, 0, 0, 0.7)";
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 4;
// Define the base size and scale relative to canvas dimensions
const size = Math.min(w, h) * 0.12;
const scale = size / 100; // coordinate system for footprint is roughly 100x100
// Calculates the path of the dinosaur based on style
function getPathPos(t) {
let x, y;
if (pathStyle === "curved") {
x = w * 0.1 + t * w * 0.8 + Math.sin(t * Math.PI) * (w * 0.2);
y = h * 0.9 - t * (h * 0.8);
} else if (pathStyle === "circle") {
x = w/2 + Math.cos(t * Math.PI * 2 * 0.85 + Math.PI*1.5) * (Math.min(w,h) * 0.35);
y = h/2 + Math.sin(t * Math.PI * 2 * 0.85 + Math.PI*1.5) * (Math.min(w,h) * 0.35);
} else if (pathStyle === "zigzag") {
x = w/2 + Math.sin(t * Math.PI * 3) * (w * 0.25);
y = h * 0.9 - t * (h * 0.8);
} else if (pathStyle === "horizontal") {
x = w * 0.1 + t * (w * 0.8);
y = h * 0.85 + Math.sin(t * Math.PI * 4) * (h * 0.05); // slight wave
} else { // default diagonal
x = w * 0.1 + t * (w * 0.8);
y = h * 0.9 - t * (h * 0.8);
}
return { x, y };
}
// Helper to draw a single toe and its claw
function drawToe(tx, ty, tw, tl, trot) {
ctx.save();
ctx.translate(tx, ty);
ctx.rotate(trot);
ctx.beginPath();
// Start from base
ctx.moveTo(-tw/2, 0);
ctx.quadraticCurveTo(-tw/2, -tl * 0.8, -tw/6, -tl);
// Pointy Claw
ctx.lineTo(0, -tl - tw*0.8);
ctx.lineTo(tw/6, -tl);
// Back down to base
ctx.quadraticCurveTo(tw/2, -tl * 0.8, tw/2, 0);
// Connect the round base
ctx.quadraticCurveTo(0, tw/3, -tw/2, 0);
ctx.fill();
ctx.restore();
}
// Stamp the footprints across the specified path
for (let i = 0; i < count; i++) {
const t = count === 1 ? 0.5 : i / (count - 1);
const pos = getPathPos(t);
// Fetch a nearby forward point for calculating the tangent angle
const posNext = getPathPos(t + 0.01);
const dx = posNext.x - pos.x;
const dy = posNext.y - pos.y;
// Base orientation angle along the path
const angle = Math.atan2(dy, dx) + Math.PI / 2;
// Obtain perpendicular normal vectors to stagger left and right feet
const len = Math.hypot(dx, dy) || 1;
const nx = -dy / len;
const ny = dx / len;
const isLeft = (i % 2 === 0);
const offsetDist = size * 0.45; // Separation of stride
const finalX = pos.x + (isLeft ? -nx : nx) * offsetDist;
const finalY = pos.y + (isLeft ? -ny : ny) * offsetDist;
// Toe-in rotation tweak typical of theropod gaits
const toeInAngle = isLeft ? 0.15 : -0.15;
ctx.save();
ctx.translate(finalX, finalY);
ctx.rotate(angle + toeInAngle);
ctx.scale(scale, scale);
// Center footprint offset to map onto the (0,0) track coordinates
ctx.translate(-50, -50);
// 1. Draw Heel Pad
ctx.beginPath();
ctx.moveTo(30, 75);
ctx.bezierCurveTo(30, 95, 45, 105, 50, 105);
ctx.bezierCurveTo(55, 105, 70, 95, 70, 75);
ctx.bezierCurveTo(60, 85, 40, 85, 30, 75);
ctx.fill();
// 2. Draw 3 Toes
drawToe(50, 70, 18, 50, 0); // middle toe
drawToe(32, 74, 14, 42, -0.45); // left outer toe
drawToe(68, 74, 14, 42, 0.45); // right outer toe
ctx.restore();
}
return canvas;
}
Apply Changes