const contentCv = document.getElementById('content'), swatchCv = document.getElementById('swatch'), resultCv = document.getElementById('result');
const sname = document.getElementById('sname');
function fitAll() {
const dpr = Math.min(devicePixelRatio || 1, 2);
[contentCv, swatchCv, resultCv].forEach((cv) => { const r = cv.getBoundingClientRect(); cv.width = Math.max(1, r.width) * dpr; cv.height = Math.max(1, r.height) * dpr; cv.getContext('2d').setTransform(dpr, 0, 0, dpr, 0, 0); });
}
addEventListener('resize', fitAll);
function mulberry32(a) { return function () { a |= 0; a = a + 0x6D2B79F5 | 0; let t = Math.imul(a ^ a >>> 15, 1 | a); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; }; }
function ridge(w, h, seed) {
const r = mulberry32(seed);
const pts = [];
for (let i = 0; i <= 8; i++) { const x = w * i / 8; const y = h * 0.45 + Math.sin(i * 1.1 + seed) * h * 0.12 - r() * h * 0.08; pts.push([x, y]); }
return pts;
}
const pts = { c: null };
function drawContent(w, h) {
const ctx = contentCv.getContext('2d');
ctx.clearRect(0, 0, w, h);
pts.c = ridge(w, h, 3);
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--fg') || '#15151a';
ctx.lineWidth = 1.6;
ctx.beginPath(); ctx.moveTo(pts.c[0][0], pts.c[0][1]); pts.c.forEach(([x, y]) => ctx.lineTo(x, y)); ctx.stroke();
}
const styles = [
{ name: '수채', colors: ['#f2b5d4', '#f7dd72', '#8fd9c4'], pattern: 'blot' },
{ name: '잉크 그라데이션', colors: ['#2b2d63', '#7d3cff', '#00c2a8'], pattern: 'stripe' },
];
function paintSwatch(w, h, style) {
const ctx = swatchCv.getContext('2d');
ctx.clearRect(0, 0, w, h);
const r = mulberry32(50);
if (style.pattern === 'blot') {
ctx.fillStyle = style.colors[0]; ctx.fillRect(0, 0, w, h);
for (let i = 0; i < 10; i++) { ctx.fillStyle = style.colors[1 + (i % 2)]; ctx.globalAlpha = 0.6; ctx.beginPath(); ctx.arc(r() * w, r() * h, 6 + r() * 10, 0, Math.PI * 2); ctx.fill(); }
ctx.globalAlpha = 1;
} else {
ctx.fillStyle = style.colors[0]; ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = style.colors[1]; ctx.lineWidth = 3;
for (let x = -h; x < w; x += 7) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x + h, h); ctx.stroke(); }
}
}
function paintResult(w, h, style) {
const ctx = resultCv.getContext('2d');
ctx.clearRect(0, 0, w, h);
if (!pts.c) return;
ctx.save();
ctx.beginPath(); ctx.moveTo(0, h); pts.c.forEach(([x, y]) => ctx.lineTo(x, y)); ctx.lineTo(w, h); ctx.closePath(); ctx.clip();
const r = mulberry32(77);
if (style.pattern === 'blot') {
ctx.fillStyle = style.colors[0]; ctx.fillRect(0, 0, w, h);
for (let i = 0; i < 40; i++) { ctx.fillStyle = style.colors[1 + (i % 2)]; ctx.globalAlpha = 0.55; ctx.beginPath(); ctx.arc(r() * w, r() * h, 6 + r() * 14, 0, Math.PI * 2); ctx.fill(); }
ctx.globalAlpha = 1;
} else {
ctx.fillStyle = style.colors[0]; ctx.fillRect(0, 0, w, h);
ctx.strokeStyle = style.colors[1]; ctx.lineWidth = 4;
for (let x = -h; x < w; x += 9) { ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x + h, h); ctx.stroke(); }
}
ctx.restore();
ctx.strokeStyle = style.colors[2]; ctx.lineWidth = 2;
ctx.beginPath(); ctx.moveTo(pts.c[0][0], pts.c[0][1]); pts.c.forEach(([x, y]) => ctx.lineTo(x, y)); ctx.stroke();
}
let si = 0;
function renderAll() {
fitAll();
const cr = contentCv.getBoundingClientRect(), sr = swatchCv.getBoundingClientRect(), rr = resultCv.getBoundingClientRect();
drawContent(cr.width, cr.height);
paintSwatch(sr.width, sr.height, styles[si]);
paintResult(rr.width, rr.height, styles[si]);
sname.textContent = '스타일: ' + styles[si].name;
}
renderAll();
setInterval(() => { si = (si + 1) % styles.length; renderAll(); }, 2200);