166 lines
3.7 KiB
JavaScript
166 lines
3.7 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const { createCanvas } = require('@napi-rs/canvas');
|
|
|
|
const SIZE = 600;
|
|
const outDir = __dirname;
|
|
|
|
function roundedRect(ctx, x, y, w, h, r) {
|
|
ctx.beginPath();
|
|
ctx.moveTo(x + r, y);
|
|
ctx.arcTo(x + w, y, x + w, y + h, r);
|
|
ctx.arcTo(x + w, y + h, x, y + h, r);
|
|
ctx.arcTo(x, y + h, x, y, r);
|
|
ctx.arcTo(x, y, x + w, y, r);
|
|
ctx.closePath();
|
|
}
|
|
|
|
function drawSteam(ctx, x, y, color) {
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = 10;
|
|
ctx.lineCap = 'round';
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(x, y + 32);
|
|
ctx.bezierCurveTo(x - 14, y + 6, x + 22, y - 6, x + 8, y - 34);
|
|
ctx.stroke();
|
|
}
|
|
|
|
function drawChopsticks(ctx, color) {
|
|
ctx.strokeStyle = color;
|
|
ctx.lineWidth = 12;
|
|
ctx.lineCap = 'round';
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(380, 170);
|
|
ctx.lineTo(490, 280);
|
|
ctx.stroke();
|
|
|
|
ctx.beginPath();
|
|
ctx.moveTo(415, 150);
|
|
ctx.lineTo(525, 260);
|
|
ctx.stroke();
|
|
}
|
|
|
|
function drawLogo({
|
|
filename,
|
|
bgGradientFrom,
|
|
bgGradientTo,
|
|
cardColor,
|
|
cardShadow,
|
|
bowlTop,
|
|
bowlBottom,
|
|
accent,
|
|
textColor,
|
|
steamColor,
|
|
chopColor,
|
|
}) {
|
|
const canvas = createCanvas(SIZE, SIZE);
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// background
|
|
const bg = ctx.createLinearGradient(0, 0, SIZE, SIZE);
|
|
bg.addColorStop(0, bgGradientFrom);
|
|
bg.addColorStop(1, bgGradientTo);
|
|
ctx.fillStyle = bg;
|
|
ctx.fillRect(0, 0, SIZE, SIZE);
|
|
|
|
// icon card
|
|
ctx.save();
|
|
ctx.shadowColor = cardShadow;
|
|
ctx.shadowBlur = 28;
|
|
ctx.shadowOffsetY = 14;
|
|
roundedRect(ctx, 72, 72, 456, 456, 120);
|
|
ctx.fillStyle = cardColor;
|
|
ctx.fill();
|
|
ctx.restore();
|
|
|
|
// bowl gradient
|
|
const bowlGrad = ctx.createLinearGradient(200, 270, 400, 420);
|
|
bowlGrad.addColorStop(0, bowlTop);
|
|
bowlGrad.addColorStop(1, bowlBottom);
|
|
|
|
// bowl body
|
|
ctx.fillStyle = bowlGrad;
|
|
roundedRect(ctx, 170, 300, 260, 130, 54);
|
|
ctx.fill();
|
|
|
|
// bowl lip
|
|
ctx.fillStyle = 'rgba(255,255,255,0.86)';
|
|
ctx.beginPath();
|
|
ctx.ellipse(300, 298, 144, 36, 0, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
|
|
// inner bowl
|
|
ctx.fillStyle = 'rgba(13,31,60,0.32)';
|
|
ctx.beginPath();
|
|
ctx.ellipse(300, 300, 76, 18, 0, 0, Math.PI * 2);
|
|
ctx.fill();
|
|
|
|
// noodles
|
|
ctx.strokeStyle = accent;
|
|
ctx.lineWidth = 9;
|
|
ctx.lineCap = 'round';
|
|
for (let i = 0; i < 3; i++) {
|
|
const y = 282 + i * 8;
|
|
ctx.beginPath();
|
|
ctx.moveTo(220, y);
|
|
ctx.bezierCurveTo(250, y - 14, 350, y - 14, 380, y);
|
|
ctx.stroke();
|
|
}
|
|
|
|
// steam
|
|
drawSteam(ctx, 245, 215, steamColor);
|
|
drawSteam(ctx, 300, 190, steamColor);
|
|
drawSteam(ctx, 355, 215, steamColor);
|
|
|
|
// chopsticks
|
|
drawChopsticks(ctx, chopColor);
|
|
|
|
// JM monogram chip
|
|
roundedRect(ctx, 220, 448, 160, 56, 28);
|
|
ctx.fillStyle = 'rgba(255,255,255,0.22)';
|
|
ctx.fill();
|
|
|
|
ctx.fillStyle = textColor;
|
|
ctx.font = 'bold 34px sans-serif';
|
|
ctx.textAlign = 'center';
|
|
ctx.textBaseline = 'middle';
|
|
ctx.fillText('점메추', 300, 476);
|
|
|
|
const output = path.join(outDir, filename);
|
|
fs.writeFileSync(output, canvas.toBuffer('image/png'));
|
|
return output;
|
|
}
|
|
|
|
const light = drawLogo({
|
|
filename: 'lunch-pick-logo-light-600-v2.png',
|
|
bgGradientFrom: '#F7FBFF',
|
|
bgGradientTo: '#E8F3FF',
|
|
cardColor: 'rgba(255,255,255,0.94)',
|
|
cardShadow: 'rgba(30,102,180,0.20)',
|
|
bowlTop: '#29B2F4',
|
|
bowlBottom: '#0A7FE8',
|
|
accent: '#0876D7',
|
|
textColor: '#0F3F7C',
|
|
steamColor: '#5AAAF6',
|
|
chopColor: '#1D4D87',
|
|
});
|
|
|
|
const dark = drawLogo({
|
|
filename: 'lunch-pick-logo-dark-600-v2.png',
|
|
bgGradientFrom: '#061226',
|
|
bgGradientTo: '#0D203F',
|
|
cardColor: 'rgba(17,39,72,0.95)',
|
|
cardShadow: 'rgba(0,0,0,0.45)',
|
|
bowlTop: '#56C8FF',
|
|
bowlBottom: '#1997F0',
|
|
accent: '#9ED9FF',
|
|
textColor: '#EAF4FF',
|
|
steamColor: '#BFE4FF',
|
|
chopColor: '#E6F3FF',
|
|
});
|
|
|
|
console.log(light);
|
|
console.log(dark);
|