- `;
-
- this.previewArea.innerHTML = svgContent;
+ const svg = this.buildSvg(panels);
+ this.previewArea.innerHTML = '';
+ this.previewArea.appendChild(svg);
+ }
+
+ buildSvg(panels) {
+ const NS = 'http://www.w3.org/2000/svg';
+ const svg = document.createElementNS(NS, 'svg');
+ svg.setAttribute('xmlns', NS);
+ svg.setAttribute('viewBox', `0 0 ${this.comicWidth} ${this.comicHeight}`);
+ svg.setAttribute('width', String(this.comicWidth));
+ svg.setAttribute('height', String(this.comicHeight));
+ svg.setAttribute('class', 'comic-svg');
+ svg.setAttribute('role', 'img');
+ svg.setAttribute('aria-label', 'Four panel story comic');
+
+ const bg = document.createElementNS(NS, 'rect');
+ bg.setAttribute('width', String(this.comicWidth));
+ bg.setAttribute('height', String(this.comicHeight));
+ bg.setAttribute('fill', '#f4f1ea');
+ svg.appendChild(bg);
+
+ const slots = [
+ { x: 16, y: 16 },
+ { x: 408, y: 16 },
+ { x: 16, y: 268 },
+ { x: 408, y: 268 }
+ ];
+
+ panels.forEach((panel, i) => {
+ const slot = slots[i];
+ svg.appendChild(this.panelGroup(panel, slot.x, slot.y, i));
+ });
+ return svg;
+ }
+
+ panelGroup(panel, x, y, index) {
+ const NS = 'http://www.w3.org/2000/svg';
+ const g = document.createElementNS(NS, 'g');
+ g.setAttribute('class', 'comic-panel');
+
+ const frame = document.createElementNS(NS, 'rect');
+ frame.setAttribute('x', String(x));
+ frame.setAttribute('y', String(y));
+ frame.setAttribute('width', '376');
+ frame.setAttribute('height', '236');
+ frame.setAttribute('rx', '12');
+ frame.setAttribute('fill', '#fffdf8');
+ frame.setAttribute('stroke', '#2b2b2b');
+ frame.setAttribute('stroke-width', '3');
+ g.appendChild(frame);
+
+ const scene = document.createElementNS(NS, 'g');
+ scene.setAttribute('transform', `translate(${x + 14} ${y + 14})`);
+ scene.innerHTML = this.drawScene(panel.scene, 0, 0, 118, 118);
+ g.appendChild(scene);
+
+ const badge = document.createElementNS(NS, 'text');
+ badge.setAttribute('x', String(x + 352));
+ badge.setAttribute('y', String(y + 28));
+ badge.setAttribute('text-anchor', 'end');
+ badge.setAttribute('font-family', 'Georgia, "Times New Roman", serif');
+ badge.setAttribute('font-size', '13');
+ badge.setAttribute('fill', '#6c757d');
+ badge.textContent = String(index + 1);
+ g.appendChild(badge);
+
+ const lines = this.wrapText(panel.text || '', 28);
+ lines.slice(0, 8).forEach((line, i) => {
+ const text = document.createElementNS(NS, 'text');
+ text.setAttribute('x', String(x + 146));
+ text.setAttribute('y', String(y + 36 + i * 22));
+ text.setAttribute('font-family', 'Georgia, "Times New Roman", serif');
+ text.setAttribute('font-size', '15');
+ text.setAttribute('fill', '#212529');
+ text.textContent = line;
+ g.appendChild(text);
+ });
+
+ if (!panel.text) {
+ const empty = document.createElementNS(NS, 'text');
+ empty.setAttribute('x', String(x + 146));
+ empty.setAttribute('y', String(y + 48));
+ empty.setAttribute('font-family', 'Georgia, "Times New Roman", serif');
+ empty.setAttribute('font-size', '15');
+ empty.setAttribute('fill', '#adb5bd');
+ empty.textContent = 'Empty panel';
+ g.appendChild(empty);
+ }
+ return g;
+ }
+
+ wrapText(text, maxChars) {
+ const words = String(text || '').trim().split(/\s+/).filter(Boolean);
+ if (!words.length) return [];
+ const lines = [];
+ let line = '';
+ words.forEach((word) => {
+ const next = line ? line + ' ' + word : word;
+ if (next.length > maxChars && line) {
+ lines.push(line);
+ line = word;
+ } else {
+ line = next;
+ }
+ });
+ if (line) lines.push(line);
+ return lines;
}
drawScene(sceneType, x, y, width, height) {
- switch(sceneType) {
+ switch (sceneType) {
case 'forest':
return `
-