// Diagram primitives + 11 step diagrams
// Technical drawing style: dimension lines, leaders, annotations
// All SVGs use viewBox 1200x700 so they scale large
const INK = "#1A1A1A";
const ACCENT = "#E85D3C";
const NG = "#B23A1A";
const OK = "#2E7D3A";
const GRID = "rgba(26,26,26,0.06)";
const GRID_HARD = "rgba(26,26,26,0.16)";
const VB_W = 1200;
const VB_H = 700;
function GridBg({ id = "grid-default", size = 24 }) {
return (
);
}
function Dim({ x1, y1, x2, y2, label, offset = 0, color = INK, labelBg = "#FAFAF7", fontSize = 15 }) {
const dx = x2 - x1, dy = y2 - y1;
const len = Math.hypot(dx, dy) || 1;
const nx = -dy / len, ny = dx / len;
const ox1 = x1 + nx * offset, oy1 = y1 + ny * offset;
const ox2 = x2 + nx * offset, oy2 = y2 + ny * offset;
const mx = (ox1 + ox2) / 2, my = (oy1 + oy2) / 2;
const ah = 7;
return (
{offset !== 0 && (
<>
>
)}
{label && (
{label}
)}
);
}
function Leader({ x, y, tx, ty, label, color = INK, anchor = "start", fontSize = 16 }) {
return (
{label}
);
}
function StickerShape({ kind = "star", x = 0, y = 0, size = 60, fill = "#fff", stroke = INK, strokeWidth = 1, strokeDasharray }) {
const r = size / 2;
let path = "";
if (kind === "star") {
const pts = [];
for (let i = 0; i < 10; i++) {
const ang = (Math.PI * 2 * i) / 10 - Math.PI / 2;
const rr = i % 2 === 0 ? r : r * 0.45;
pts.push([Math.cos(ang) * rr, Math.sin(ang) * rr]);
}
path = "M" + pts.map(p => p.map(n => n.toFixed(2)).join(",")).join(" L") + " Z";
} else if (kind === "heart") {
path = `M 0 ${-r*0.2} C ${r*0.55} ${-r}, ${r} ${-r*0.4}, 0 ${r*0.55} C ${-r} ${-r*0.4}, ${-r*0.55} ${-r}, 0 ${-r*0.2} Z`;
} else if (kind === "cloud") {
path = `M ${-r*0.7} ${r*0.2} C ${-r} ${r*0.2}, ${-r} ${-r*0.3}, ${-r*0.55} ${-r*0.3} C ${-r*0.55} ${-r*0.7}, ${-r*0.1} ${-r*0.75}, ${0} ${-r*0.4} C ${r*0.15} ${-r*0.75}, ${r*0.65} ${-r*0.65}, ${r*0.6} ${-r*0.25} C ${r} ${-r*0.25}, ${r} ${r*0.2}, ${r*0.65} ${r*0.2} Z`;
} else if (kind === "blob") {
path = `M ${-r*0.7} ${-r*0.3} C ${-r} ${-r*0.8}, ${-r*0.2} ${-r}, ${r*0.35} ${-r*0.75} C ${r} ${-r*0.55}, ${r*0.95} ${r*0.2}, ${r*0.5} ${r*0.8} C ${-r*0.2} ${r}, ${-r*0.9} ${r*0.6}, ${-r*0.7} ${-r*0.3} Z`;
} else if (kind === "circle") {
return ;
} else if (kind === "rect") {
return ;
} else if (kind === "hex") {
const pts = [];
for (let i = 0; i < 6; i++) {
const ang = (Math.PI * 2 * i) / 6 - Math.PI / 2;
pts.push([Math.cos(ang) * r, Math.sin(ang) * r]);
}
path = "M" + pts.map(p => p.map(n => n.toFixed(2)).join(",")).join(" L") + " Z";
}
return ;
}
function VerdictBadge({ verdict = "OK", x = 0, y = 0, w = 78, h = 30 }) {
const isOK = verdict === "OK";
const color = isOK ? OK : NG;
return (
{isOK ? "OK" : "NG"}
);
}
function Panel({ x, y, w, h, title, children, titleRight }) {
return (
{title && (
<>
{title}
{titleRight && {titleRight}}
>
)}
{children}
);
}
// ========== 01 File formats ==========
function DiagramFileFormat({ detail = 2 }) {
const fmt = (ext, ok, color) => ({ ext, ok, color });
const files = [
fmt(".ai", true, "#E87B35"),
fmt(".psd", true, "#31A8FF"),
fmt(".jpg", false, "#888"),
fmt(".png", false, "#888"),
fmt(".docx", false, "#2B579A"),
fmt(".pptx", false, "#D24726"),
];
return (
);
}
// ========== 02 CMYK vs RGB ==========
function DiagramCMYK({ detail = 2 }) {
return (
);
}
// ========== 03 Outline fonts ==========
function DiagramOutline({ detail = 2 }) {
return (
);
}
// ========== 04 Link vs Embed ==========
function DiagramEmbed({ detail = 2 }) {
return (
);
}
// ========== 05 DPI ==========
function DiagramDPI({ detail = 2 }) {
const cells = (size, count) => {
const arr = [];
for (let y = 0; y < count; y++) for (let x = 0; x < count; x++) arr.push([x, y]);
return arr.map(([x, y], i) => (
));
};
return (
);
}
// ========== 06 Layer structure ==========
function DiagramLayers({ detail = 2 }) {
return (
);
}
// ========== 07 K100 cut line ==========
function DiagramK100({ detail = 2 }) {
return (
);
}
// ========== 08 Fill area ==========
function DiagramFillArea({ detail = 2 }) {
return (
);
}
// ========== 09 Bleed ==========
function DiagramBleed({ detail = 2 }) {
return (
);
}
// ========== 10 The 3mm rule (three distances) ==========
function DiagramThreeRules({ detail = 2 }) {
return (
);
}
// ========== 11 Angles ==========
function DiagramAngles({ detail = 2 }) {
return (
);
}
window.Diagrams = {
DiagramFileFormat,
DiagramCMYK,
DiagramOutline,
DiagramEmbed,
DiagramDPI,
DiagramLayers,
DiagramK100,
DiagramFillArea,
DiagramBleed,
DiagramThreeRules,
DiagramAngles,
};