You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, hatPositionX = 'auto', hatPositionY = 'auto', hatWidth = 'auto', rotationDegrees = 0, hatColor = '#222222', tasselColor = '#FFD700') {
const canvas = document.createElement('canvas');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
const ctx = canvas.getContext('2d');
// Draw the underlying original image
ctx.drawImage(originalImg, 0, 0);
// Determine sizes and coordinates
const x = hatPositionX === 'auto' ? canvas.width / 2 : parseFloat(hatPositionX);
const y = hatPositionY === 'auto' ? canvas.height * 0.2 : parseFloat(hatPositionY);
const width = hatWidth === 'auto' ? canvas.width / 3 : parseFloat(hatWidth);
const rot = parseFloat(rotationDegrees);
ctx.save();
ctx.translate(x, y);
ctx.rotate((rot * Math.PI) / 180);
// Baseline hat width is 160 units wide (-80 to 80). Compute scale factor.
const scaleFactor = width / 160;
ctx.scale(scaleFactor, scaleFactor);
// 1. Skullcap (bottom part fitting on head)
ctx.fillStyle = hatColor;
ctx.beginPath();
ctx.moveTo(-45, 10);
ctx.lineTo(45, 10);
ctx.lineTo(40, 50);
ctx.quadraticCurveTo(0, 70, -40, 50);
ctx.closePath();
ctx.fill();
// Skullcap shadow
ctx.fillStyle = 'rgba(0,0,0,0.25)';
ctx.fill();
// 2. Board Rim (creates 3D thickness)
ctx.fillStyle = hatColor;
ctx.beginPath();
ctx.moveTo(-80, 0);
ctx.lineTo(0, 40);
ctx.lineTo(80, 0);
ctx.lineTo(80, 6);
ctx.lineTo(0, 46);
ctx.lineTo(-80, 6);
ctx.closePath();
ctx.fill();
// Darken the rim
ctx.fillStyle = 'rgba(0,0,0,0.4)';
ctx.fill();
// 3. Board Top (Rhombus shape)
ctx.fillStyle = hatColor;
ctx.beginPath();
ctx.moveTo(0, -40);
ctx.lineTo(80, 0);
ctx.lineTo(0, 40);
ctx.lineTo(-80, 0);
ctx.closePath();
ctx.fill();
// 4. Board Highlight (Subtle lighting on the top left)
ctx.fillStyle = 'rgba(255,255,255,0.08)';
ctx.beginPath();
ctx.moveTo(0, -40);
ctx.lineTo(80, 0);
ctx.lineTo(0, 0);
ctx.lineTo(-80, 0);
ctx.closePath();
ctx.fill();
// 5. Center Button
ctx.fillStyle = hatColor;
ctx.beginPath();
ctx.arc(0, 0, 6, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = 'rgba(0,0,0,0.3)';
ctx.fill();
// 6. Tassel String
ctx.strokeStyle = tasselColor;
ctx.lineWidth = 2.5;
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(0, 0);
// Drape toward the right edge and hang off
ctx.quadraticCurveTo(45, 5, 75, 20);
ctx.lineTo(75, 45);
ctx.stroke();
// 7. Tassel Knot
ctx.fillStyle = tasselColor;
ctx.beginPath();
ctx.rect(71, 41, 8, 5);
ctx.fill();
// 8. Tassel Fringes/Strands
ctx.beginPath();
ctx.lineWidth = 1;
for (let i = 0; i <= 8; i++) {
// Space them across the bottom of the knot (width 8)
ctx.moveTo(71 + i, 46);
// Flare out slightly with length variation
ctx.lineTo(65 + i * 2.5, 75 + Math.random() * 8);
}
ctx.stroke();
ctx.restore();
return canvas;
}
Apply Changes